Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] dpt_i2o: 64 bit support

This is the code to actually support 64 bit platforms. 64 bit
DMA is enabled on both x86_32 PAE and 64 bit platforms.

This code is based in part on the unofficial adaptec 64-bit
dpt_i2o driver update that I got from Mark Salyzyn at Adaptec.

Signed-off-by: Miquel van Smoorenburg <miquels@cistron.nl>
Acked-by: Mark Salyzyn <Mark_Salyzyn@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by

Miquel van Smoorenburg and committed by
James Bottomley
62ac5aed 67af2b06

+260 -53
+1 -2
drivers/scsi/Kconfig
··· 504 504 source "drivers/scsi/aic7xxx/Kconfig.aic79xx" 505 505 source "drivers/scsi/aic94xx/Kconfig" 506 506 507 - # All the I2O code and drivers do not seem to be 64bit safe. 508 507 config SCSI_DPT_I2O 509 508 tristate "Adaptec I2O RAID support " 510 - depends on !64BIT && SCSI && PCI && VIRT_TO_BUS 509 + depends on SCSI && PCI && VIRT_TO_BUS 511 510 help 512 511 This driver supports all of Adaptec's I2O based RAID controllers as 513 512 well as the DPT SmartRaid V cards. This is an Adaptec maintained
+8 -8
drivers/scsi/dpt/dpti_ioctl.h
··· 89 89 int njobs; /* # of jobs sent to HA */ 90 90 int qdepth; /* Controller queue depth. */ 91 91 int wakebase; /* mpx wakeup base index. */ 92 - uLONG SGsize; /* Scatter/Gather list size. */ 92 + uINT SGsize; /* Scatter/Gather list size. */ 93 93 unsigned heads; /* heads for drives on cntlr. */ 94 94 unsigned sectors; /* sectors for drives on cntlr. */ 95 95 uCHAR do_drive32; /* Flag for Above 16 MB Ability */ ··· 97 97 char idPAL[4]; /* 4 Bytes Of The ID Pal */ 98 98 uCHAR primary; /* 1 For Primary, 0 For Secondary */ 99 99 uCHAR eataVersion; /* EATA Version */ 100 - uLONG cpLength; /* EATA Command Packet Length */ 101 - uLONG spLength; /* EATA Status Packet Length */ 100 + uINT cpLength; /* EATA Command Packet Length */ 101 + uINT spLength; /* EATA Status Packet Length */ 102 102 uCHAR drqNum; /* DRQ Index (0,5,6,7) */ 103 103 uCHAR flag1; /* EATA Flags 1 (Byte 9) */ 104 104 uCHAR flag2; /* EATA Flags 2 (Byte 30) */ ··· 107 107 typedef struct { 108 108 uSHORT length; // Remaining length of this 109 109 uSHORT drvrHBAnum; // Relative HBA # used by the driver 110 - uLONG baseAddr; // Base I/O address 110 + uINT baseAddr; // Base I/O address 111 111 uSHORT blinkState; // Blink LED state (0=Not in blink LED) 112 112 uCHAR pciBusNum; // PCI Bus # (Optional) 113 113 uCHAR pciDeviceNum; // PCI Device # (Optional) 114 114 uSHORT hbaFlags; // Miscellaneous HBA flags 115 115 uSHORT Interrupt; // Interrupt set for this device. 116 116 # if (defined(_DPT_ARC)) 117 - uLONG baseLength; 117 + uINT baseLength; 118 118 ADAPTER_OBJECT *AdapterObject; 119 119 LARGE_INTEGER DmaLogicalAddress; 120 120 PVOID DmaVirtualAddress; 121 121 LARGE_INTEGER ReplyLogicalAddress; 122 122 PVOID ReplyVirtualAddress; 123 123 # else 124 - uLONG reserved1; // Reserved for future expansion 125 - uLONG reserved2; // Reserved for future expansion 126 - uLONG reserved3; // Reserved for future expansion 124 + uINT reserved1; // Reserved for future expansion 125 + uINT reserved2; // Reserved for future expansion 126 + uINT reserved3; // Reserved for future expansion 127 127 # endif 128 128 } drvrHBAinfo_S; 129 129
+2 -6
drivers/scsi/dpt/dptsig.h
··· 33 33 /* to make sure we are talking the same size under all OS's */ 34 34 typedef unsigned char sigBYTE; 35 35 typedef unsigned short sigWORD; 36 - #if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32)) 37 - typedef uint32_t sigLONG; 38 - #else 39 - typedef unsigned long sigLONG; 40 - #endif 36 + typedef unsigned int sigINT; 41 37 42 38 /* 43 39 * use sigWORDLittleEndian for: ··· 296 300 sigBYTE dsFiletype; /* type of file */ 297 301 sigBYTE dsFiletypeFlags; /* flags to specify load type, etc. */ 298 302 sigBYTE dsOEM; /* OEM file was created for */ 299 - sigLONG dsOS; /* which Operating systems */ 303 + sigINT dsOS; /* which Operating systems */ 300 304 sigWORD dsCapabilities; /* RAID levels, etc. */ 301 305 sigWORD dsDeviceSupp; /* Types of SCSI devices supported */ 302 306 sigWORD dsAdapterSupp; /* DPT adapter families supported */
+2 -2
drivers/scsi/dpt/sys_info.h
··· 145 145 uCHAR smartROMRevision; 146 146 uSHORT flags; /* See bit definitions above */ 147 147 uSHORT conventionalMemSize; /* in KB */ 148 - uLONG extendedMemSize; /* in KB */ 149 - uLONG osType; /* Same as DPTSIG's definition */ 148 + uINT extendedMemSize; /* in KB */ 149 + uINT osType; /* Same as DPTSIG's definition */ 150 150 uCHAR osMajorVersion; 151 151 uCHAR osMinorVersion; /* The OS version */ 152 152 uCHAR osRevision;
+245 -35
drivers/scsi/dpt_i2o.c
··· 111 111 static adpt_hba* hba_chain = NULL; 112 112 static int hba_count = 0; 113 113 114 + #ifdef CONFIG_COMPAT 115 + static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long); 116 + #endif 117 + 114 118 static const struct file_operations adpt_fops = { 115 119 .ioctl = adpt_ioctl, 116 120 .open = adpt_open, 117 - .release = adpt_close 121 + .release = adpt_close, 122 + #ifdef CONFIG_COMPAT 123 + .compat_ioctl = compat_adpt_ioctl, 124 + #endif 118 125 }; 119 126 120 127 /* Structures and definitions for synchronous message posting. ··· 144 137 * Functions 145 138 *============================================================================ 146 139 */ 140 + 141 + static inline int dpt_dma64(adpt_hba *pHba) 142 + { 143 + return (sizeof(dma_addr_t) > 4 && (pHba)->dma64); 144 + } 147 145 148 146 static inline u32 dma_high(dma_addr_t addr) 149 147 { ··· 289 277 290 278 static void adpt_inquiry(adpt_hba* pHba) 291 279 { 292 - u32 msg[14]; 280 + u32 msg[17]; 293 281 u32 *mptr; 294 282 u32 *lenptr; 295 283 int direction; ··· 313 301 direction = 0x00000000; 314 302 scsidir =0x40000000; // DATA IN (iop<--dev) 315 303 316 - reqlen = 14; // SINGLE SGE 304 + if (dpt_dma64(pHba)) 305 + reqlen = 17; // SINGLE SGE, 64 bit 306 + else 307 + reqlen = 14; // SINGLE SGE, 32 bit 317 308 /* Stick the headers on */ 318 309 msg[0] = reqlen<<16 | SGL_OFFSET_12; 319 310 msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID); ··· 349 334 350 335 /* Now fill in the SGList and command */ 351 336 *lenptr = len; 352 - *mptr++ = 0xD0000000|direction|len; 353 - *mptr++ = addr; 337 + if (dpt_dma64(pHba)) { 338 + *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */ 339 + *mptr++ = 1 << PAGE_SHIFT; 340 + *mptr++ = 0xD0000000|direction|len; 341 + *mptr++ = dma_low(addr); 342 + *mptr++ = dma_high(addr); 343 + } else { 344 + *mptr++ = 0xD0000000|direction|len; 345 + *mptr++ = addr; 346 + } 354 347 355 348 // Send it on it's way 356 349 rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120); ··· 651 628 return len; 652 629 } 653 630 631 + /* 632 + * Turn a struct scsi_cmnd * into a unique 32 bit 'context'. 633 + */ 634 + static u32 adpt_cmd_to_context(struct scsi_cmnd *cmd) 635 + { 636 + return (u32)cmd->serial_number; 637 + } 638 + 639 + /* 640 + * Go from a u32 'context' to a struct scsi_cmnd * . 641 + * This could probably be made more efficient. 642 + */ 643 + static struct scsi_cmnd * 644 + adpt_cmd_from_context(adpt_hba * pHba, u32 context) 645 + { 646 + struct scsi_cmnd * cmd; 647 + struct scsi_device * d; 648 + 649 + if (context == 0) 650 + return NULL; 651 + 652 + spin_unlock(pHba->host->host_lock); 653 + shost_for_each_device(d, pHba->host) { 654 + unsigned long flags; 655 + spin_lock_irqsave(&d->list_lock, flags); 656 + list_for_each_entry(cmd, &d->cmd_list, list) { 657 + if (((u32)cmd->serial_number == context)) { 658 + spin_unlock_irqrestore(&d->list_lock, flags); 659 + scsi_device_put(d); 660 + spin_lock(pHba->host->host_lock); 661 + return cmd; 662 + } 663 + } 664 + spin_unlock_irqrestore(&d->list_lock, flags); 665 + } 666 + spin_lock(pHba->host->host_lock); 667 + 668 + return NULL; 669 + } 670 + 671 + /* 672 + * Turn a pointer to ioctl reply data into an u32 'context' 673 + */ 674 + static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply) 675 + { 676 + #if BITS_PER_LONG == 32 677 + return (u32)(unsigned long)reply; 678 + #else 679 + ulong flags = 0; 680 + u32 nr, i; 681 + 682 + spin_lock_irqsave(pHba->host->host_lock, flags); 683 + nr = ARRAY_SIZE(pHba->ioctl_reply_context); 684 + for (i = 0; i < nr; i++) { 685 + if (pHba->ioctl_reply_context[i] == NULL) { 686 + pHba->ioctl_reply_context[i] = reply; 687 + break; 688 + } 689 + } 690 + spin_unlock_irqrestore(pHba->host->host_lock, flags); 691 + if (i >= nr) { 692 + kfree (reply); 693 + printk(KERN_WARNING"%s: Too many outstanding " 694 + "ioctl commands\n", pHba->name); 695 + return (u32)-1; 696 + } 697 + 698 + return i; 699 + #endif 700 + } 701 + 702 + /* 703 + * Go from an u32 'context' to a pointer to ioctl reply data. 704 + */ 705 + static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context) 706 + { 707 + #if BITS_PER_LONG == 32 708 + return (void *)(unsigned long)context; 709 + #else 710 + void *p = pHba->ioctl_reply_context[context]; 711 + pHba->ioctl_reply_context[context] = NULL; 712 + 713 + return p; 714 + #endif 715 + } 716 + 654 717 /*=========================================================================== 655 718 * Error Handling routines 656 719 *=========================================================================== ··· 764 655 msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid; 765 656 msg[2] = 0; 766 657 msg[3]= 0; 767 - msg[4] = (u32)cmd; 658 + msg[4] = adpt_cmd_to_context(cmd); 768 659 if (pHba->host) 769 660 spin_lock_irq(pHba->host->host_lock); 770 661 rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); ··· 976 867 u32 hba_map1_area_size = 0; 977 868 void __iomem *base_addr_virt = NULL; 978 869 void __iomem *msg_addr_virt = NULL; 870 + int dma64 = 0; 979 871 980 872 int raptorFlag = FALSE; 981 873 ··· 990 880 } 991 881 992 882 pci_set_master(pDev); 993 - if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) 883 + 884 + /* 885 + * See if we should enable dma64 mode. 886 + */ 887 + if (sizeof(dma_addr_t) > 4 && 888 + pci_set_dma_mask(pDev, DMA_64BIT_MASK) == 0) { 889 + if (dma_get_required_mask(&pDev->dev) > DMA_32BIT_MASK) 890 + dma64 = 1; 891 + } 892 + if (!dma64 && pci_set_dma_mask(pDev, DMA_32BIT_MASK) != 0) 994 893 return -EINVAL; 995 894 996 895 /* adapter only supports message blocks below 4GB */ ··· 1024 905 hba_map1_area_size = pci_resource_len(pDev,1); 1025 906 raptorFlag = TRUE; 1026 907 } 908 + 909 + #if BITS_PER_LONG == 64 910 + /* 911 + * The original Adaptec 64 bit driver has this comment here: 912 + * "x86_64 machines need more optimal mappings" 913 + * 914 + * I assume some HBAs report ridiculously large mappings 915 + * and we need to limit them on platforms with IOMMUs. 916 + */ 917 + if (raptorFlag == TRUE) { 918 + if (hba_map0_area_size > 128) 919 + hba_map0_area_size = 128; 920 + if (hba_map1_area_size > 524288) 921 + hba_map1_area_size = 524288; 922 + } else { 923 + if (hba_map0_area_size > 524288) 924 + hba_map0_area_size = 524288; 925 + } 926 + #endif 1027 927 1028 928 base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size); 1029 929 if (!base_addr_virt) { ··· 1106 968 pHba->state = DPTI_STATE_RESET; 1107 969 pHba->pDev = pDev; 1108 970 pHba->devices = NULL; 971 + pHba->dma64 = dma64; 1109 972 1110 973 // Initializing the spinlocks 1111 974 spin_lock_init(&pHba->state_lock); 1112 975 spin_lock_init(&adpt_post_wait_lock); 1113 976 1114 977 if(raptorFlag == 0){ 1115 - printk(KERN_INFO"Adaptec I2O RAID controller %d at %p size=%x irq=%d\n", 1116 - hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq); 978 + printk(KERN_INFO "Adaptec I2O RAID controller" 979 + " %d at %p size=%x irq=%d%s\n", 980 + hba_count-1, base_addr_virt, 981 + hba_map0_area_size, pDev->irq, 982 + dma64 ? " (64-bit DMA)" : ""); 1117 983 } else { 1118 - printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq); 984 + printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d%s\n", 985 + hba_count-1, pDev->irq, 986 + dma64 ? " (64-bit DMA)" : ""); 1119 987 printk(KERN_INFO" BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size); 1120 988 printk(KERN_INFO" BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size); 1121 989 } ··· 1174 1030 if(pHba->msg_addr_virt != pHba->base_addr_virt){ 1175 1031 iounmap(pHba->msg_addr_virt); 1176 1032 } 1033 + if(pHba->FwDebugBuffer_P) 1034 + iounmap(pHba->FwDebugBuffer_P); 1177 1035 if(pHba->hrt) { 1178 1036 dma_free_coherent(&pHba->pDev->dev, 1179 1037 pHba->hrt->num_entries * pHba->hrt->entry_len << 2, ··· 1803 1657 } 1804 1658 sg_offset = (msg[0]>>4)&0xf; 1805 1659 msg[2] = 0x40000000; // IOCTL context 1806 - msg[3] = (u32)reply; 1660 + msg[3] = adpt_ioctl_to_context(pHba, reply); 1661 + if (msg[3] == (u32)-1) 1662 + return -EBUSY; 1663 + 1807 1664 memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize); 1808 1665 if(sg_offset) { 1809 - // TODO 64bit fix 1666 + // TODO add 64 bit API 1810 1667 struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset); 1811 1668 sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); 1812 1669 if (sg_count > pHba->sg_tablesize){ ··· 1838 1689 sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. 1839 1690 /* Copy in the user's SG buffer if necessary */ 1840 1691 if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) { 1841 - // TODO 64bit fix 1842 - if (copy_from_user(p,(void __user *)sg[i].addr_bus, sg_size)) { 1692 + // sg_simple_element API is 32 bit 1693 + if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) { 1843 1694 printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i); 1844 1695 rcode = -EFAULT; 1845 1696 goto cleanup; 1846 1697 } 1847 1698 } 1848 - //TODO 64bit fix 1849 - sg[i].addr_bus = (u32)virt_to_bus(p); 1699 + /* sg_simple_element API is 32 bit, but addr < 4GB */ 1700 + sg[i].addr_bus = addr; 1850 1701 } 1851 1702 } 1852 1703 ··· 1874 1725 if(sg_offset) { 1875 1726 /* Copy back the Scatter Gather buffers back to user space */ 1876 1727 u32 j; 1877 - // TODO 64bit fix 1728 + // TODO add 64 bit API 1878 1729 struct sg_simple_element* sg; 1879 1730 int sg_size; 1880 1731 ··· 1894 1745 } 1895 1746 sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); 1896 1747 1897 - // TODO 64bit fix 1748 + // TODO add 64 bit API 1898 1749 sg = (struct sg_simple_element*)(msg + sg_offset); 1899 1750 for (j = 0; j < sg_count; j++) { 1900 1751 /* Copy out the SG list to user's buffer if necessary */ 1901 1752 if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) { 1902 1753 sg_size = sg[j].flag_count & 0xffffff; 1903 - // TODO 64bit fix 1904 - if (copy_to_user((void __user *)sg[j].addr_bus,sg_list[j], sg_size)) { 1754 + // sg_simple_element API is 32 bit 1755 + if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) { 1905 1756 printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus); 1906 1757 rcode = -EFAULT; 1907 1758 goto cleanup; ··· 2121 1972 return error; 2122 1973 } 2123 1974 1975 + #ifdef CONFIG_COMPAT 1976 + static long compat_adpt_ioctl(struct file *file, 1977 + unsigned int cmd, unsigned long arg) 1978 + { 1979 + struct inode *inode; 1980 + long ret; 1981 + 1982 + inode = file->f_dentry->d_inode; 1983 + 1984 + lock_kernel(); 1985 + 1986 + switch(cmd) { 1987 + case DPT_SIGNATURE: 1988 + case I2OUSRCMD: 1989 + case DPT_CTRLINFO: 1990 + case DPT_SYSINFO: 1991 + case DPT_BLINKLED: 1992 + case I2ORESETCMD: 1993 + case I2ORESCANCMD: 1994 + case (DPT_TARGET_BUSY & 0xFFFF): 1995 + case DPT_TARGET_BUSY: 1996 + ret = adpt_ioctl(inode, file, cmd, arg); 1997 + break; 1998 + default: 1999 + ret = -ENOIOCTLCMD; 2000 + } 2001 + 2002 + unlock_kernel(); 2003 + 2004 + return ret; 2005 + } 2006 + #endif 2124 2007 2125 2008 static irqreturn_t adpt_isr(int irq, void *dev_id) 2126 2009 { ··· 2213 2032 } 2214 2033 context = readl(reply+8); 2215 2034 if(context & 0x40000000){ // IOCTL 2216 - void *p = (void *)readl(reply+12); 2035 + void *p = adpt_ioctl_from_context(pHba, readl(reply+12)); 2217 2036 if( p != NULL) { 2218 2037 memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4); 2219 2038 } ··· 2227 2046 status = I2O_POST_WAIT_OK; 2228 2047 } 2229 2048 if(!(context & 0x40000000)) { 2230 - cmd = (struct scsi_cmnd*) readl(reply+12); 2049 + cmd = adpt_cmd_from_context(pHba, 2050 + readl(reply+12)); 2231 2051 if(cmd != NULL) { 2232 2052 printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); 2233 2053 } 2234 2054 } 2235 2055 adpt_i2o_post_wait_complete(context, status); 2236 2056 } else { // SCSI message 2237 - cmd = (struct scsi_cmnd*) readl(reply+12); 2057 + cmd = adpt_cmd_from_context (pHba, readl(reply+12)); 2238 2058 if(cmd != NULL){ 2239 2059 scsi_dma_unmap(cmd); 2240 2060 if(cmd->serial_number != 0) { // If not timedout ··· 2258 2076 int i; 2259 2077 u32 msg[MAX_MESSAGE_SIZE]; 2260 2078 u32* mptr; 2079 + u32* lptr; 2261 2080 u32 *lenptr; 2262 2081 int direction; 2263 2082 int scsidir; ··· 2266 2083 u32 len; 2267 2084 u32 reqlen; 2268 2085 s32 rcode; 2086 + dma_addr_t addr; 2269 2087 2270 2088 memset(msg, 0 , sizeof(msg)); 2271 2089 len = scsi_bufflen(cmd); ··· 2306 2122 // I2O_CMD_SCSI_EXEC 2307 2123 msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid); 2308 2124 msg[2] = 0; 2309 - msg[3] = (u32)cmd; /* We want the SCSI control block back */ 2125 + msg[3] = adpt_cmd_to_context(cmd); /* Want SCSI control block back */ 2310 2126 // Our cards use the transaction context as the tag for queueing 2311 2127 // Adaptec/DPT Private stuff 2312 2128 msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16); ··· 2324 2140 memcpy(mptr, cmd->cmnd, cmd->cmd_len); 2325 2141 mptr+=4; 2326 2142 lenptr=mptr++; /* Remember me - fill in when we know */ 2327 - reqlen = 14; // SINGLE SGE 2143 + if (dpt_dma64(pHba)) { 2144 + reqlen = 16; // SINGLE SGE 2145 + *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */ 2146 + *mptr++ = 1 << PAGE_SHIFT; 2147 + } else { 2148 + reqlen = 14; // SINGLE SGE 2149 + } 2328 2150 /* Now fill in the SGList and command */ 2329 2151 2330 2152 nseg = scsi_dma_map(cmd); ··· 2340 2150 2341 2151 len = 0; 2342 2152 scsi_for_each_sg(cmd, sg, nseg, i) { 2153 + lptr = mptr; 2343 2154 *mptr++ = direction|0x10000000|sg_dma_len(sg); 2344 2155 len+=sg_dma_len(sg); 2345 - *mptr++ = sg_dma_address(sg); 2156 + addr = sg_dma_address(sg); 2157 + *mptr++ = dma_low(addr); 2158 + if (dpt_dma64(pHba)) 2159 + *mptr++ = dma_high(addr); 2346 2160 /* Make this an end of list */ 2347 2161 if (i == nseg - 1) 2348 - mptr[-2] = direction|0xD0000000|sg_dma_len(sg); 2162 + *lptr = direction|0xD0000000|sg_dma_len(sg); 2349 2163 } 2350 2164 reqlen = mptr - msg; 2351 2165 *lenptr = len; ··· 3018 2824 } 3019 2825 3020 2826 // Calculate the Scatter Gather list size 3021 - pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element); 2827 + if (dpt_dma64(pHba)) { 2828 + pHba->sg_tablesize 2829 + = ((pHba->status_block->inbound_frame_size * 4 2830 + - 14 * sizeof(u32)) 2831 + / (sizeof(struct sg_simple_element) + sizeof(u32))); 2832 + } else { 2833 + pHba->sg_tablesize 2834 + = ((pHba->status_block->inbound_frame_size * 4 2835 + - 12 * sizeof(u32)) 2836 + / sizeof(struct sg_simple_element)); 2837 + } 3022 2838 if (pHba->sg_tablesize > SG_LIST_ELEMENTS) { 3023 2839 pHba->sg_tablesize = SG_LIST_ELEMENTS; 3024 2840 } ··· 3120 2916 // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO; 3121 2917 if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) { 3122 2918 pHba->FwDebugBufferSize = buf[1]; 3123 - pHba->FwDebugBuffer_P = pHba->base_addr_virt + buf[0]; 3124 - pHba->FwDebugFlags_P = pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET; 3125 - pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET; 3126 - pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1; 3127 - pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET; 3128 - pHba->FwDebugBuffer_P += buf[2]; 3129 - pHba->FwDebugFlags = 0; 2919 + pHba->FwDebugBuffer_P = ioremap(pHba->base_addr_phys + buf[0], 2920 + pHba->FwDebugBufferSize); 2921 + if (pHba->FwDebugBuffer_P) { 2922 + pHba->FwDebugFlags_P = pHba->FwDebugBuffer_P + 2923 + FW_DEBUG_FLAGS_OFFSET; 2924 + pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + 2925 + FW_DEBUG_BLED_OFFSET; 2926 + pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1; 2927 + pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + 2928 + FW_DEBUG_STR_LENGTH_OFFSET; 2929 + pHba->FwDebugBuffer_P += buf[2]; 2930 + pHba->FwDebugFlags = 0; 2931 + } 3130 2932 } 3131 2933 3132 2934 return 0;
+2
drivers/scsi/dpti.h
··· 233 233 u8 top_scsi_channel; 234 234 u8 top_scsi_id; 235 235 u8 top_scsi_lun; 236 + u8 dma64; 236 237 237 238 i2o_status_block* status_block; 238 239 dma_addr_t status_block_pa; ··· 253 252 void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED 254 253 void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED 255 254 u32 FwDebugFlags; 255 + u32 *ioctl_reply_context[4]; 256 256 } adpt_hba; 257 257 258 258 struct sg_simple_element {