mpt fusion: Fix for 1078 Data corruption issue for 36GB memory region
Subsystems (2)
PATCH 1/1 mpt fusion: Fix for 1078 Data corruption issue for 36GB memory region
The reason for this change is there is a data corruption when four different physical memory regions in the 36GB to 37GB region are accessed. This is only affecting 1078.
The solution is we need to use different addressing when filling in the scatter gather table for the effected memory regions. So instead of snooping on all four different memory holes, we treat any physical addresses in the 36GB address with the same algorithm.
The fix is explained below
1) Ensure that the message frames are NOT located in the trouble region. There is no remapping available for message frames, they must be allocated outside the problem region.
2) Ensure that Sense buffers are NOT in the trouble region. There is no remapping available.
3) Walk through the SGE entries and if any are inside the trouble region then they need to be remapped as discussed below.
1) Set the Local Address bit in the SGE Flags field. MPI_SGE_FLAGS_LOCAL_ADDRESS
2) Ensure we are using 64-bit SGEs
3) Set MSb (Bit 63) of the 64-bit address, this will indicate buffer location is Host Memory.
---
drivers/message/fusion/mptbase.c +123 -35
@@ -925,33 +925,75 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPTspin_unlock_irqrestore (&ioc->FreeQlock, flags); } +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** -* mpt_add_sge - Place a simple SGE at address pAddr. -* @pAddr: virtual address for SGE +* mpt_add_sge - Place a simple 32 bit SGE at address addr. +* @addr: virtual address for SGE * @flagslength: SGE flags and data transfer length * @dma_addr: Physical address -* -* This routine places a MPT request frame back on the MPT adapter's -* FreeQ. */ -void -mpt_add_sge (char *pAddr,u32 flagslength,dma_addr_t dma_addr) +static void +mpt_add_sge (char *addr,u32 flagslength,dma_addr_t dma_addr) { -if (sizeof (dma_addr_t) ==sizeof (u64)) { -SGESimple64_t *pSge = (SGESimple64_t *) pAddr; -u32 tmp = dma_addr &0xFFFFFFFF ; +SGESimple32_t *pSge = (SGESimple32_t *) addr; + pSge->FlagsLength =cpu_to_le32 (flagslength); + pSge->Address =cpu_to_le32 (dma_addr); +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** +* mpt_add_sge_64bit - Place a simple 64 bit SGE at address addr. +* @addr: virtual address for SGE +* @flagslength: SGE flags and data transfer length +* @dma_addr: Physical address +*/ +static void +mpt_add_sge_64bit (char *addr,u32 flagslength,dma_addr_t dma_addr) +{ +SGESimple64_t *pSge = (SGESimple64_t *) addr; +u32 tmp = dma_addr &0xFFFFFFFF ; - pSge->FlagsLength =cpu_to_le32 (flagslength); - pSge->Address.Low =cpu_to_le32 (tmp); - tmp = (u32) ((u64 )dma_addr >>32 ); - pSge->Address.High =cpu_to_le32 (tmp); + pSge->FlagsLength =cpu_to_le32 (flagslength); + pSge->Address.Low =cpu_to_le32 (tmp); + tmp = (u32) ((u64 )dma_addr >>32 ); + pSge->Address.High =cpu_to_le32 (tmp); +} - }else { -SGESimple32_t *pSge = (SGESimple32_t *) pAddr; - pSge->FlagsLength =cpu_to_le32 (flagslength); - pSge->Address =cpu_to_le32 (dma_addr); +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** +* mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address addr +* (1078 workaround). +* @addr: virtual address for SGE +* @flagslength: SGE flags and data transfer length +* @dma_addr: Physical address +*/ +static void +mpt_add_sge_64bit_1078 (char *addr,u32 flagslength,dma_addr_t dma_addr) +{ +SGESimple64_t *pSge = (SGESimple64_t *) addr; +u32 tmp; + + tmp = dma_addr &0xFFFFFFFF ; + pSge->Address.Low =cpu_to_le32 (tmp); + tmp = (u32) ((u64 )dma_addr >>32 ); + +/* +* 1078 errata workaround for the 36GB limitation +*/ +if ((((u64 )dma_addr +MPI_SGE_LENGTH (flagslength)) >>32 ) ==9 ) { + flagslength |= +MPI_SGE_SET_FLAGS (MPI_SGE_FLAGS_LOCAL_ADDRESS ); + tmp |= (1 <<31 ); +if (mpt_debug_level &MPT_DEBUG_36GB_MEM ) +printk (KERN_DEBUG "1078 P0M2 addressing for " +"addr = 0x%llx len = %d\n" , + (unsigned long long )dma_addr, +MPI_SGE_LENGTH (flagslength)); } + + pSge->FlagsLength =cpu_to_le32 (flagslength); + pSge->Address.High =cpu_to_le32 (tmp); }/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1154,7 +1196,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pI } flags_length = flags_length <<MPI_SGE_FLAGS_SHIFT ; flags_length |= ioc->HostPageBuffer_sz; -mpt_add_sge (psge, flags_length, ioc->HostPageBuffer_dma); + ioc->add_sge (psge, flags_length, ioc->HostPageBuffer_dma); ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;return 0 ;
@@ -1496,28 +1538,41 @@ mpt_attach(struct pci_dev *pdev, const sdinitprintk (ioc,printk (MYIOC_s_INFO_FMT": mpt_adapter_install\n" , ioc->name)); -if (!pci_set_dma_mask (pdev,DMA_64BIT_MASK )) { -dprintk (ioc,printk (MYIOC_s_INFO_FMT -": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n" , ioc->name)); - }else if (pci_set_dma_mask (pdev,DMA_32BIT_MASK )) { -printk (MYIOC_s_WARN_FMT": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n" , - ioc->name); +if (!pci_set_dma_mask (pdev,DMA_64BIT_MASK ) + && !pci_set_consistent_dma_mask (pdev,DMA_64BIT_MASK )) { + ioc->dma_mask =DMA_64BIT_MASK ; +dinitprintk (ioc,printk (MYIOC_s_INFO_FMT +": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n" , + ioc->name)); + }else if (!pci_set_dma_mask (pdev,DMA_32BIT_MASK ) + && !pci_set_consistent_dma_mask (pdev,DMA_32BIT_MASK )) { + ioc->dma_mask =DMA_32BIT_MASK ; +dinitprintk (ioc,printk (MYIOC_s_INFO_FMT +": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n" , + ioc->name)); + }else { +printk (MYIOC_s_WARN_FMT"no suitable DMA mask for %s\n" , + ioc->name,pci_name (pdev));kfree (ioc);return r; } -if (!pci_set_consistent_dma_mask (pdev,DMA_64BIT_MASK )) { -dprintk (ioc,printk (MYIOC_s_INFO_FMT -": Using 64 bit consistent mask\n" , ioc->name)); - }else { -dprintk (ioc,printk (MYIOC_s_INFO_FMT -": Not using 64 bit consistent mask\n" , ioc->name)); - } ioc->alloc_total =sizeof (MPT_ADAPTER ); ioc->req_sz =MPT_DEFAULT_FRAME_SIZE ;/* avoid div by zero! */ ioc->reply_sz =MPT_REPLY_FRAME_SIZE ; +/* +* Setting up proper handlers for scatter gather handling +*/ +if (sizeof (dma_addr_t) ==sizeof (u64)) { +if (pdev->device ==MPI_MANUFACTPAGE_DEVID_SAS1078 ) + ioc->add_sge = &mpt_add_sge_64bit_1078; +else + ioc->add_sge = &mpt_add_sge_64bit; + }else + ioc->add_sge = &mpt_add_sge; + ioc->pcidev = pdev; ioc->diagPending =0 ;spin_lock_init (&ioc->diagLock);
@@ -3201,7 +3256,7 @@ mpt_do_upload(MPT_ADAPTER *ioc, int slee sgeoffset =sizeof (FWUpload_t) -sizeof (SGE_MPI_UNION ) +sizeof (FWUploadTCSGE_t); flagsLength =MPT_SGE_FLAGS_SSIMPLE_READ | sz; -mpt_add_sge ((char *)ptcsge, flagsLength, ioc->cached_fw_dma); + ioc->add_sge ((char *)ptcsge, flagsLength, ioc->cached_fw_dma); sgeoffset +=sizeof (u32) +sizeof (dma_addr_t); dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
@@ -3995,12 +4050,33 @@ PrimeIocFifos(MPT_ADAPTER *ioc)dma_addr_t alloc_dma;u8 *mem;int i, reply_sz, sz, total_size, num_chain; +u64 dma_mask =0 ;/* Prime reply FIFO... */ if (ioc->reply_frames ==NULL ) {if ( (num_chain =initChainBuffers (ioc)) <0 )return -1 ; +/* +* 1078 errata workaround for the 36GB limitation +*/ +if (ioc->pcidev->device ==MPI_MANUFACTPAGE_DEVID_SAS1078 && + ioc->dma_mask >MPT_DMA_35BIT_MASK ) { +if (!pci_set_dma_mask (ioc->pcidev,DMA_32BIT_MASK ) + && !pci_set_consistent_dma_mask (ioc->pcidev, +DMA_32BIT_MASK )) { + dma_mask =MPT_DMA_35BIT_MASK ; +d36memprintk (ioc,printk (MYIOC_s_DEBUG_FMT +"setting 35 bit addressing for " +"Request/Reply/Chain and Sense Buffers\n" , + ioc->name)); + }else { +d36memprintk (ioc,printk (MYIOC_s_DEBUG_FMT +"failed setting 35 bit addressing for " +"Request/Reply/Chain and Sense Buffers\n" , + ioc->name)); + } + } total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth); dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
@@ -4139,6 +4215,12 @@ PrimeIocFifos(MPT_ADAPTER *ioc) alloc_dma += ioc->reply_sz; } +if (dma_mask ==MPT_DMA_35BIT_MASK && !pci_set_dma_mask (ioc->pcidev, +DMA_64BIT_MASK ) && !pci_set_consistent_dma_mask (ioc->pcidev, +DMA_64BIT_MASK )) +d36memprintk (ioc,printk (MYIOC_s_DEBUG_FMT +"restoring 64 bit addressing\n" , ioc->name)); +return 0 ; out_fail:
@@ -4158,6 +4240,13 @@ out_fail: ioc->sense_buf_pool, ioc->sense_buf_pool_dma); ioc->sense_buf_pool =NULL ; } + +if (dma_mask ==MPT_DMA_35BIT_MASK && !pci_set_dma_mask (ioc->pcidev, +DMA_64BIT_MASK ) && !pci_set_consistent_dma_mask (ioc->pcidev, +DMA_64BIT_MASK )) +d36memprintk (ioc,printk (MYIOC_s_DEBUG_FMT +"restoring 64 bit addressing\n" , ioc->name)); +return -1 ; }
@@ -5761,7 +5850,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action)); } -mpt_add_sge ((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); + ioc->add_sge ((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);/* Append pCfg pointer to end of mf */
@@ -7421,7 +7510,6 @@ EXPORT_SYMBOL(mpt_get_msg_frame);EXPORT_SYMBOL (mpt_put_msg_frame);EXPORT_SYMBOL (mpt_put_msg_frame_hi_pri);EXPORT_SYMBOL (mpt_free_msg_frame); -EXPORT_SYMBOL (mpt_add_sge);EXPORT_SYMBOL (mpt_send_handshake_request);EXPORT_SYMBOL (mpt_verify_adapter);EXPORT_SYMBOL (mpt_GetIocState);
drivers/message/fusion/mptbase.h +6 -2
@@ -133,6 +133,8 @@#define MPT_COALESCING_TIMEOUT 0x10 +#define MPT_DMA_35BIT_MASK 0x00000007ffffffffULL +/* * SCSI transfer rate defines. */
@@ -561,6 +563,8 @@ struct mptfc_rport_infou8 flags; }; +typedef void (*MPT_ADD_SGE )(char *addr,u32 flagslength,dma_addr_t dma_addr); +/* * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS */
@@ -597,6 +601,8 @@ typedef struct _MPT_ADAPTERint reply_depth;/* Num Allocated reply frames */ int reply_sz;/* Reply frame size */ int num_chain;/* Number of chain buffers */ +MPT_ADD_SGE add_sge; +u64 dma_mask;/* Pool of buffers for chaining. ReqToChain * and ChainToChain track index of chain buffers. * ChainBuffer (DMA) virt/phys addresses.
@@ -900,8 +906,6 @@ extern MPT_FRAME_HDR *mpt_get_msg_frame(extern void mpt_free_msg_frame (MPT_ADAPTER *ioc,MPT_FRAME_HDR *mf);extern void mpt_put_msg_frame (u8 cb_idx,MPT_ADAPTER *ioc,MPT_FRAME_HDR *mf);extern void mpt_put_msg_frame_hi_pri (u8 cb_idx,MPT_ADAPTER *ioc,MPT_FRAME_HDR *mf); -extern void mpt_add_sge (char *pAddr,u32 flagslength,dma_addr_t dma_addr); -extern int mpt_send_handshake_request (u8 cb_idx,MPT_ADAPTER *ioc,int reqBytes,u32 *req,int sleepFlag);extern int mpt_verify_adapter (int iocid,MPT_ADAPTER **iocpp);extern u32 mpt_GetIocState (MPT_ADAPTER *ioc,int cooked);
drivers/message/fusion/mptctl.c +5 -5
@@ -871,7 +871,7 @@ mptctl_do_fw_download(int ioc, char __usif (nib ==0 || nib ==3 ) { ; }else if (sgIn->Address) { -mpt_add_sge (sgOut, sgIn->FlagsLength, sgIn->Address); + iocp->add_sge (sgOut, sgIn->FlagsLength, sgIn->Address); n++;if (copy_from_user (bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) { printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "
@@ -2142,7 +2142,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_/* Set up this SGE. * Copy to MF and to sglbuf */ -mpt_add_sge (psge, flagsLength, dma_addr_out); + ioc->add_sge (psge, flagsLength, dma_addr_out); psge += (sizeof (u32) +sizeof (dma_addr_t));/* Copy user data to kernel space.
@@ -2176,13 +2176,13 @@ mptctl_do_mpt_command (struct mpt_ioctl_/* Set up this SGE * Copy to MF and to sglbuf */ -mpt_add_sge (psge, flagsLength, dma_addr_in); + ioc->add_sge (psge, flagsLength, dma_addr_in); } } }else {/* Add a NULL SGE */ -mpt_add_sge (psge, flagsLength, (dma_addr_t) -1 ); + ioc->add_sge (psge, flagsLength, (dma_addr_t) -1 ); } ioc->ioctl->wait_done =0 ;
@@ -2499,7 +2499,7 @@ mptctl_hp_hostinfo(unsigned long arg, un pbuf =pci_alloc_consistent (ioc->pcidev,4 , &buf_dma);if (!pbuf) goto out; -mpt_add_sge ((char *)&IstwiRWRequest->SGL, + ioc->add_sge ((char *)&IstwiRWRequest->SGL, (MPT_SGE_FLAGS_SSIMPLE_READ |4 ), buf_dma); ioc->ioctl->wait_done =0 ;
drivers/message/fusion/mptdebug.h +3 -0
@@ -58,6 +58,7 @@#define MPT_DEBUG_FC 0x00080000#define MPT_DEBUG_SAS 0x00100000#define MPT_DEBUG_SAS_WIDE 0x00200000 +#define MPT_DEBUG_36GB_MEM 0x00400000/* * CONFIG_FUSION_LOGGING - enabled in Kconfig
@@ -135,6 +136,8 @@#define dsaswideprintk (IOC ,CMD ) \ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE) +#define d36memprintk (IOC ,CMD ) \ + MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_36GB_MEM)/*
drivers/message/fusion/mptsas.c +2 -2
@@ -1313,7 +1313,7 @@ static int mptsas_smp_handler(struct Scs req->data_len, PCI_DMA_BIDIRECTIONAL);if (!dma_addr_out) goto put_mf; -mpt_add_sge (psge, flagsLength, dma_addr_out); + ioc->add_sge (psge, flagsLength, dma_addr_out); psge += (sizeof (u32) +sizeof (dma_addr_t));/* response */
@@ -1323,7 +1323,7 @@ static int mptsas_smp_handler(struct Scs rsp->data_len, PCI_DMA_BIDIRECTIONAL);if (!dma_addr_in) goto unmap; -mpt_add_sge (psge, flagsLength, dma_addr_in); + ioc->add_sge (psge, flagsLength, dma_addr_in);mpt_put_msg_frame (mptsasMgmtCtx, ioc, mf);
drivers/message/fusion/mptscsih.c +6 -35
74 lines not on this page · raw message
drivers/message/fusion/mptspi.c +2 -2
@@ -300,7 +300,7 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, flagsLength =MPT_SGE_FLAGS_SSIMPLE_WRITE | (IOCPage4Ptr->Header.PageLength + ii) *4 ; -mpt_add_sge ((char *)&pReq->PageBufferSGE, flagsLength, dataDma); + ioc->add_sge ((char *)&pReq->PageBufferSGE, flagsLength, dataDma); ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
@@ -642,7 +642,7 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, pReq->Reserved2 =0 ; pReq->ActionDataWord =0 ;/* Reserved for this action */ -mpt_add_sge ((char *)&pReq->ActionDataSGE, + ioc->add_sge ((char *)&pReq->ActionDataSGE,MPT_SGE_FLAGS_SSIMPLE_READ |0 , (dma_addr_t) -1 ); ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n",
James Bottomley
maintainerQuoted 9 lines · Sathya
The reason for this change is there is a data corruption when four different physical memory regions in the 36GB to 37GB region are accessed. This is only affecting 1078.
The solution is we need to use different addressing when filling in the scatter gather table for the effected memory regions. So instead of snooping on all four different memory holes, we treat any physical addresses in the 36GB address with the same algorithm.
Quoted 13 lines
The fix is explained below
1) Ensure that the message frames are NOT located in the trouble region. There is no remapping available for message frames, they must be allocated outside the problem region.
2) Ensure that Sense buffers are NOT in the trouble region. There is no remapping available.
3) Walk through the SGE entries and if any are inside the trouble region then they need to be remapped as discussed below.
1) Set the Local Address bit in the SGE Flags field.MPI_SGE_FLAGS_LOCAL_ADDRESS
2) Ensure we are using 64-bit SGEs
3) Set MSb (Bit 63) of the 64-bit address, this will indicate buffer location is Host Memory.
Is there any reason these three things can't be done all the time for the troubled adapter rather then do the if you have on every scatter gather segment?
Quoted 75 lines
Signed-off-by Sathya Prakash <[email protected]>---
diff -Naurp
b/drivers/message/fusion/mptbase.ca/drivers/message/fusion/mptbase.cdrivers/message/fusion/mptbase.c +39
-18@@ -925,33 +925,75 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPTspin_unlock_irqrestore (&ioc->FreeQlock, flags); } +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** -* mpt_add_sge - Place a simple SGE at address pAddr. -* @pAddr: virtual address for SGE +* mpt_add_sge - Place a simple 32 bit SGE at address addr. +* @addr: virtual address for SGE * @flagslength: SGE flags and data transfer length * @dma_addr: Physical address -* -* This routine places a MPT request frame back on the MPT adapter's -* FreeQ. */ -void -mpt_add_sge (char *pAddr,u32 flagslength,dma_addr_t dma_addr) +static void +mpt_add_sge (char *addr,u32 flagslength,dma_addr_t dma_addr) { -if (sizeof (dma_addr_t) ==sizeof (u64)) { -SGESimple64_t *pSge = (SGESimple64_t *) pAddr; -u32 tmp = dma_addr &0xFFFFFFFF ; +SGESimple32_t *pSge = (SGESimple32_t *) addr; + pSge->FlagsLength =cpu_to_le32 (flagslength); + pSge->Address =cpu_to_le32 (dma_addr); +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** +* mpt_add_sge_64bit - Place a simple 64 bit SGE at address addr. +* @addr: virtual address for SGE +* @flagslength: SGE flags and data transfer length +* @dma_addr: Physical address +*/ +static void +mpt_add_sge_64bit (char *addr,u32 flagslength,dma_addr_t dma_addr) +{ +SGESimple64_t *pSge = (SGESimple64_t *) addr; +u32 tmp = dma_addr &0xFFFFFFFF ; - pSge->FlagsLength =cpu_to_le32 (flagslength); - pSge->Address.Low =cpu_to_le32 (tmp); - tmp = (u32) ((u64 )dma_addr >>32 ); - pSge->Address.High =cpu_to_le32 (tmp); + pSge->FlagsLength =cpu_to_le32 (flagslength); + pSge->Address.Low =cpu_to_le32 (tmp); + tmp = (u32) ((u64 )dma_addr >>32 ); + pSge->Address.High =cpu_to_le32 (tmp); +} - }else { -SGESimple32_t *pSge = (SGESimple32_t *) pAddr; - pSge->FlagsLength =cpu_to_le32 (flagslength); - pSge->Address =cpu_to_le32 (dma_addr); +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** +* mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address addr +* (1078 workaround). +* @addr: virtual address for SGE +* @flagslength: SGE flags and data transfer length +* @dma_addr: Physical address +*/ +static void +mpt_add_sge_64bit_1078 (char *addr,u32 flagslength,dma_addr_t dma_addr) +{ +SGESimple64_t *pSge = (SGESimple64_t *) addr;
drivers/message/fusion/mptbase.c mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT · line 984
Quoted 10 lines
drivers/message/fusion/mptbase.c +10
-0+u32 tmp; + + tmp = dma_addr &0xFFFFFFFF ; + pSge->Address.Low =cpu_to_le32 (tmp); + tmp = (u32) ((u64 )dma_addr >>32 ); + +/* +* 1078 errata workaround for the 36GB limitation +*/ +if ((((u64 )dma_addr +MPI_SGE_LENGTH (flagslength)) >>32 ) ==9 ) {
This looks really odd. 36GB (in fact 32-64GB) will have (dma_addr >>
32) == 3 not 9
Quoted 59 lines
drivers/message/fusion/mptbase.c +27
-13+ flagslength |= +MPI_SGE_SET_FLAGS (MPI_SGE_FLAGS_LOCAL_ADDRESS ); + tmp |= (1 <<31 ); +if (mpt_debug_level &MPT_DEBUG_36GB_MEM ) +printk (KERN_DEBUG "1078 P0M2 addressing for " +"addr = 0x%llx len = %d\n" , + (unsigned long long )dma_addr, +MPI_SGE_LENGTH (flagslength)); } + + pSge->FlagsLength =cpu_to_le32 (flagslength); + pSge->Address.High =cpu_to_le32 (tmp); }/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1154,7 +1196,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pI } flags_length = flags_length <<MPI_SGE_FLAGS_SHIFT ; flags_length |= ioc->HostPageBuffer_sz; -mpt_add_sge (psge, flags_length, ioc->HostPageBuffer_dma); + ioc->add_sge (psge, flags_length, ioc->HostPageBuffer_dma); ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;return 0 ;@@ -1496,28 +1538,41 @@ mpt_attach(struct pci_dev *pdev, const sdinitprintk (ioc,printk (MYIOC_s_INFO_FMT": mpt_adapter_install\n" , ioc->name)); -if (!pci_set_dma_mask (pdev,DMA_64BIT_MASK )) { -dprintk (ioc,printk (MYIOC_s_INFO_FMT -": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n" , ioc->name)); - }else if (pci_set_dma_mask (pdev,DMA_32BIT_MASK )) { -printk (MYIOC_s_WARN_FMT": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n" , - ioc->name); +if (!pci_set_dma_mask (pdev,DMA_64BIT_MASK ) + && !pci_set_consistent_dma_mask (pdev,DMA_64BIT_MASK )) { + ioc->dma_mask =DMA_64BIT_MASK ; +dinitprintk (ioc,printk (MYIOC_s_INFO_FMT +": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n" , + ioc->name)); + }else if (!pci_set_dma_mask (pdev,DMA_32BIT_MASK ) + && !pci_set_consistent_dma_mask (pdev,DMA_32BIT_MASK )) { + ioc->dma_mask =DMA_32BIT_MASK ; +dinitprintk (ioc,printk (MYIOC_s_INFO_FMT +": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n" , + ioc->name)); + }else { +printk (MYIOC_s_WARN_FMT"no suitable DMA mask for %s\n" , + ioc->name,pci_name (pdev));kfree (ioc);return r; } -if (!pci_set_consistent_dma_mask (pdev,DMA_64BIT_MASK )) { -dprintk (ioc,printk (MYIOC_s_INFO_FMT -": Using 64 bit consistent mask\n" , ioc->name)); - }else { -dprintk (ioc,printk (MYIOC_s_INFO_FMT -": Not using 64 bit consistent mask\n" , ioc->name));
drivers/message/fusion/mptbase.c mpt_attach(struct pci_dev *pdev, const s · line 1568
Quoted 10 lines
drivers/message/fusion/mptbase.c +4
-1- } ioc->alloc_total =sizeof (MPT_ADAPTER ); ioc->req_sz =MPT_DEFAULT_FRAME_SIZE ;/* avoid div by zero! */ ioc->reply_sz =MPT_REPLY_FRAME_SIZE ; +/* +* Setting up proper handlers for scatter gather handling +*/ +if (sizeof (dma_addr_t) ==sizeof (u64)) {
use dma_get_required_mask() here ... that will tell you not only if you were compiled for 64 bits, but also if the box would actually use them.
Quoted 26 lines
drivers/message/fusion/mptbase.c +9
-1+if (pdev->device ==MPI_MANUFACTPAGE_DEVID_SAS1078 ) + ioc->add_sge = &mpt_add_sge_64bit_1078; +else + ioc->add_sge = &mpt_add_sge_64bit; + }else + ioc->add_sge = &mpt_add_sge; + ioc->pcidev = pdev; ioc->diagPending =0 ;spin_lock_init (&ioc->diagLock);@@ -3201,7 +3256,7 @@ mpt_do_upload(MPT_ADAPTER *ioc, int slee sgeoffset =sizeof (FWUpload_t) -sizeof (SGE_MPI_UNION ) +sizeof (FWUploadTCSGE_t); flagsLength =MPT_SGE_FLAGS_SSIMPLE_READ | sz; -mpt_add_sge ((char *)ptcsge, flagsLength, ioc->cached_fw_dma); + ioc->add_sge ((char *)ptcsge, flagsLength, ioc->cached_fw_dma); sgeoffset +=sizeof (u32) +sizeof (dma_addr_t); dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",@@ -3995,12 +4050,33 @@ PrimeIocFifos(MPT_ADAPTER *ioc)dma_addr_t alloc_dma;u8 *mem;int i, reply_sz, sz, total_size, num_chain; +u64 dma_mask =0 ;/* Prime reply FIFO... */
drivers/message/fusion/mptbase.c PrimeIocFifos(MPT_ADAPTER *ioc) · line 4065
Quoted 10 lines
drivers/message/fusion/mptbase.c +6
-0if (ioc->reply_frames ==NULL ) {if ( (num_chain =initChainBuffers (ioc)) <0 )return -1 ; +/* +* 1078 errata workaround for the 36GB limitation +*/ +if (ioc->pcidev->device ==MPI_MANUFACTPAGE_DEVID_SAS1078 && + ioc->dma_mask >MPT_DMA_35BIT_MASK ) { + if (!pci_set_dma_mask(ioc->pcidev, DMA_32BIT_MASK)
Don't you want to be setting a 35 bit mask here, not a 32 bit one ... not that it really matters, most architectures will happily give you 32 bits anyway (except possibly altix).
Quoted 65 lines
drivers/message/fusion/mptbase.c +28
-2+ && !pci_set_consistent_dma_mask(ioc->pcidev, + DMA_32BIT_MASK)) { + dma_mask = MPT_DMA_35BIT_MASK; + d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "setting 35 bit addressing for " + "Request/Reply/Chain and Sense Buffers\n", + ioc->name)); + } else { +d36memprintk (ioc,printk (MYIOC_s_DEBUG_FMT +"failed setting 35 bit addressing for " +"Request/Reply/Chain and Sense Buffers\n" , + ioc->name)); + } + } total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth); dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",@@ -4139,6 +4215,12 @@ PrimeIocFifos(MPT_ADAPTER *ioc) alloc_dma += ioc->reply_sz; } +if (dma_mask ==MPT_DMA_35BIT_MASK && !pci_set_dma_mask (ioc->pcidev, +DMA_64BIT_MASK ) && !pci_set_consistent_dma_mask (ioc->pcidev, +DMA_64BIT_MASK )) +d36memprintk (ioc,printk (MYIOC_s_DEBUG_FMT +"restoring 64 bit addressing\n" , ioc->name)); +return 0 ; out_fail:@@ -4158,6 +4240,13 @@ out_fail: ioc->sense_buf_pool, ioc->sense_buf_pool_dma); ioc->sense_buf_pool =NULL ; } + +if (dma_mask ==MPT_DMA_35BIT_MASK && !pci_set_dma_mask (ioc->pcidev, +DMA_64BIT_MASK ) && !pci_set_consistent_dma_mask (ioc->pcidev, +DMA_64BIT_MASK )) +d36memprintk (ioc,printk (MYIOC_s_DEBUG_FMT +"restoring 64 bit addressing\n" , ioc->name)); +return -1 ; }@@ -5761,7 +5850,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action)); } -mpt_add_sge ((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); + ioc->add_sge ((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);/* Append pCfg pointer to end of mf */ @@ -7421,7 +7510,6 @@ EXPORT_SYMBOL(mpt_get_msg_frame);EXPORT_SYMBOL (mpt_put_msg_frame);EXPORT_SYMBOL (mpt_put_msg_frame_hi_pri);EXPORT_SYMBOL (mpt_free_msg_frame); -EXPORT_SYMBOL (mpt_add_sge);EXPORT_SYMBOL (mpt_send_handshake_request);EXPORT_SYMBOL (mpt_verify_adapter);EXPORT_SYMBOL (mpt_GetIocState);diff -Naurp
b/drivers/message/fusion/mptbase.ha/drivers/message/fusion/mptbase.h
drivers/message/fusion/mptbase.h line 137
Quoted 5 lines
drivers/message/fusion/mptbase.h +2
-0@@ -133,6 +133,8 @@#define MPT_COALESCING_TIMEOUT 0x10 +#define MPT_DMA_35BIT_MASK 0x00000007ffffffffULL +
There's already a definition DMA_35BIT_MASK ininclude/linux/dma-mapping.h ... please use it.
Quoted 13 lines
drivers/message/fusion/mptbase.h +2
-0/* * SCSI transfer rate defines. */ @@ -561,6 +563,8 @@ struct mptfc_rport_infou8 flags; }; +typedef void (*MPT_ADD_SGE )(char *addr,u32 flagslength,dma_addr_t dma_addr); +/* * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS */
drivers/message/fusion/mptbase.h typedef struct _MPT_ADAPTER · line 605
Quoted 5 lines
drivers/message/fusion/mptbase.h +2
-0@@ -597,6 +601,8 @@ typedef struct _MPT_ADAPTERint reply_depth;/* Num Allocated reply frames */ int reply_sz;/* Reply frame size */ int num_chain;/* Number of chain buffers */ +MPT_ADD_SGE add_sge; +u64 dma_mask;
You don't need this ... isn't it going to be the same as ioc->pcidev->dma_mask?
Quoted 194 lines
drivers/message/fusion/mptbase.h +0
-2/* Pool of buffers for chaining. ReqToChain * and ChainToChain track index of chain buffers. * ChainBuffer (DMA) virt/phys addresses. @@ -900,8 +906,6 @@ extern MPT_FRAME_HDR *mpt_get_msg_frame(extern void mpt_free_msg_frame (MPT_ADAPTER *ioc,MPT_FRAME_HDR *mf);extern void mpt_put_msg_frame (u8 cb_idx,MPT_ADAPTER *ioc,MPT_FRAME_HDR *mf);extern void mpt_put_msg_frame_hi_pri (u8 cb_idx,MPT_ADAPTER *ioc,MPT_FRAME_HDR *mf); -extern void mpt_add_sge (char *pAddr,u32 flagslength,dma_addr_t dma_addr); -extern int mpt_send_handshake_request (u8 cb_idx,MPT_ADAPTER *ioc,int reqBytes,u32 *req,int sleepFlag);extern int mpt_verify_adapter (int iocid,MPT_ADAPTER **iocpp);extern u32 mpt_GetIocState (MPT_ADAPTER *ioc,int cooked);diff -Naurp
b/drivers/message/fusion/mptctl.ca/drivers/message/fusion/mptctl.cdrivers/message/fusion/mptctl.c +5
-5@@ -871,7 +871,7 @@ mptctl_do_fw_download(int ioc, char __usif (nib ==0 || nib ==3 ) { ; }else if (sgIn->Address) { -mpt_add_sge (sgOut, sgIn->FlagsLength, sgIn->Address); + iocp->add_sge (sgOut, sgIn->FlagsLength, sgIn->Address); n++;if (copy_from_user (bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) { printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "@@ -2142,7 +2142,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_/* Set up this SGE. * Copy to MF and to sglbuf */ -mpt_add_sge (psge, flagsLength, dma_addr_out); + ioc->add_sge (psge, flagsLength, dma_addr_out); psge += (sizeof (u32) +sizeof (dma_addr_t));/* Copy user data to kernel space. @@ -2176,13 +2176,13 @@ mptctl_do_mpt_command (struct mpt_ioctl_/* Set up this SGE * Copy to MF and to sglbuf */ -mpt_add_sge (psge, flagsLength, dma_addr_in); + ioc->add_sge (psge, flagsLength, dma_addr_in); } } }else {/* Add a NULL SGE */ -mpt_add_sge (psge, flagsLength, (dma_addr_t) -1 ); + ioc->add_sge (psge, flagsLength, (dma_addr_t) -1 ); } ioc->ioctl->wait_done =0 ;@@ -2499,7 +2499,7 @@ mptctl_hp_hostinfo(unsigned long arg, un pbuf =pci_alloc_consistent (ioc->pcidev,4 , &buf_dma);if (!pbuf) goto out; -mpt_add_sge ((char *)&IstwiRWRequest->SGL, + ioc->add_sge ((char *)&IstwiRWRequest->SGL, (MPT_SGE_FLAGS_SSIMPLE_READ |4 ), buf_dma); ioc->ioctl->wait_done =0 ;diff -Naurp
b/drivers/message/fusion/mptdebug.ha/drivers/message/fusion/mptdebug.hdrivers/message/fusion/mptdebug.h +3
-0@@ -58,6 +58,7 @@#define MPT_DEBUG_FC 0x00080000#define MPT_DEBUG_SAS 0x00100000#define MPT_DEBUG_SAS_WIDE 0x00200000 +#define MPT_DEBUG_36GB_MEM 0x00400000/* * CONFIG_FUSION_LOGGING - enabled in Kconfig @@ -135,6 +136,8 @@#define dsaswideprintk (IOC ,CMD ) \ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE) +#define d36memprintk (IOC ,CMD ) \ + MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_36GB_MEM)/* diff -Naurp
b/drivers/message/fusion/mptsas.ca/drivers/message/fusion/mptsas.cdrivers/message/fusion/mptsas.c +2
-2@@ -1313,7 +1313,7 @@ static int mptsas_smp_handler(struct Scs req->data_len, PCI_DMA_BIDIRECTIONAL);if (!dma_addr_out) goto put_mf; -mpt_add_sge (psge, flagsLength, dma_addr_out); + ioc->add_sge (psge, flagsLength, dma_addr_out); psge += (sizeof (u32) +sizeof (dma_addr_t));/* response */ @@ -1323,7 +1323,7 @@ static int mptsas_smp_handler(struct Scs rsp->data_len, PCI_DMA_BIDIRECTIONAL);if (!dma_addr_in) goto unmap; -mpt_add_sge (psge, flagsLength, dma_addr_in); + ioc->add_sge (psge, flagsLength, dma_addr_in);mpt_put_msg_frame (mptsasMgmtCtx, ioc, mf);diff -Naurp
b/drivers/message/fusion/mptscsih.ca/drivers/message/fusion/mptscsih.cdrivers/message/fusion/mptscsih.c +6
-35@@ -115,35 +115,6 @@ int mptscsih_resume(struct pci_dev *pd/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** -* mptscsih_add_sge - Place a simple SGE at address pAddr. -* @pAddr: virtual address for SGE -* @flagslength: SGE flags and data transfer length -* @dma_addr: Physical address -* -* This routine places a MPT request frame back on the MPT adapter's -* FreeQ. -*/ -static inline void -mptscsih_add_sge (char *pAddr,u32 flagslength,dma_addr_t dma_addr) -{ -if (sizeof (dma_addr_t) ==sizeof (u64)) { -SGESimple64_t *pSge = (SGESimple64_t *) pAddr; -u32 tmp = dma_addr &0xFFFFFFFF ; - - pSge->FlagsLength =cpu_to_le32 (flagslength); - pSge->Address.Low =cpu_to_le32 (tmp); - tmp = (u32) ((u64 )dma_addr >>32 ); - pSge->Address.High =cpu_to_le32 (tmp); - - }else { -SGESimple32_t *pSge = (SGESimple32_t *) pAddr; - pSge->FlagsLength =cpu_to_le32 (flagslength); - pSge->Address =cpu_to_le32 (dma_addr); - } -}/* mptscsih_add_sge() */ - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** * mptscsih_add_chain - Place a chain SGE at address pAddr. * @pAddr: virtual address for SGE * @next: nextChainOffset value (u32's) @@ -299,7 +270,7 @@ nextSGEset: } v2 =sg_dma_address (sg); -mptscsih_add_sge (psge, sgflags | thisxfer, v2); + ioc->add_sge (psge, sgflags | thisxfer, v2); sg =sg_next (sg);/* Get next SG element from the OS */ psge += (sizeof (u32) +sizeof (dma_addr_t));@@ -320,7 +291,7 @@ nextSGEset: thisxfer =sg_dma_len (sg); v2 =sg_dma_address (sg); -mptscsih_add_sge (psge, sgflags | thisxfer, v2); + ioc->add_sge (psge, sgflags | thisxfer, v2);/* sg = sg_next(sg); psge += (sizeof(u32) + sizeof(dma_addr_t)); @@ -1439,8 +1410,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, v*/ if (datalen ==0 ) {/* Add a NULL SGE */ -mptscsih_add_sge ((char *)&pScsiReq->SGL,MPT_SGE_FLAGS_SSIMPLE_READ |0 , - (dma_addr_t) -1 ); + ioc->add_sge ((char *)&pScsiReq->SGL, +MPT_SGE_FLAGS_SSIMPLE_READ |0 , (dma_addr_t) -1 ); }else {/* Add a 32 or 64 bit SGE */ if (mptscsih_AddSGE (ioc, SCpnt, pScsiReq, my_idx) !=SUCCESS )@@ -3193,11 +3164,11 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER ioc->name, cmd, io->channel, io->id, io->lun));if (dir ==MPI_SCSIIO_CONTROL_READ ) { -mpt_add_sge ((char *) &pScsiReq->SGL, + ioc->add_sge ((char *) &pScsiReq->SGL,MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma); }else { -mpt_add_sge ((char *) &pScsiReq->SGL, + ioc->add_sge ((char *) &pScsiReq->SGL,MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma); }diff -Naurp
b/drivers/message/fusion/mptspi.ca/drivers/message/fusion/mptspi.cdrivers/message/fusion/mptspi.c +1
-1@@ -300,7 +300,7 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, flagsLength =MPT_SGE_FLAGS_SSIMPLE_WRITE | (IOCPage4Ptr->Header.PageLength + ii) *4 ; -mpt_add_sge ((char *)&pReq->PageBufferSGE, flagsLength, dataDma); + ioc->add_sge ((char *)&pReq->PageBufferSGE, flagsLength, dataDma); ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
drivers/message/fusion/mptspi.c mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, · line 648
Quoted 8 lines
drivers/message/fusion/mptspi.c +1
-1@@ -642,7 +642,7 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, pReq->Reserved2 =0 ; pReq->ActionDataWord =0 ;/* Reserved for this action */ -mpt_add_sge ((char *)&pReq->ActionDataSGE, + ioc->add_sge ((char *)&pReq->ActionDataSGE,MPT_SGE_FLAGS_SSIMPLE_READ |0 , (dma_addr_t) -1 ); ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n",
James
RE: [PATCH] mpt fusion: Fix for 1078 Data corruption issue for36GB memory region
Quoted 12 lines · James Bottomley
Quoted 4 lines
The fix is explained below
1) Ensure that the message frames are NOT located in the trouble region. There is no remapping available for message frames, they must be allocated outside the problem region.Quoted 8 lines
2) Ensure that Sense buffers are NOT in the trouble region. There is no remapping available.
3) Walk through the SGE entries and if any are inside the trouble region then they need to be remapped as discussed below.
1) Set the Local Address bit in the SGE Flags field.MPI_SGE_FLAGS_LOCAL_ADDRESS
2) Ensure we are using 64-bit SGEs
3) Set MSb (Bit 63) of the 64-bit address, this will
Quoted 7 lines
indicate buffer
Quoted 1 line
location is Host Memory.
Is there any reason these three things can't be done all the time for the troubled adapter rather then do the if you have on every scatter gather segment?
The reason for the this implementation is less risk. Due to a hardware bug, we are providing both firmware and driver fixes. The hardware bug effects three memory ranges within 36-37GB range, the bug is is when your writing into that physical memory, your writting into controller
memory instead of host memory, hence the data corruption. So the
customer will be requiring a firmware upgrade as well as new drivers. We call this method of setting the scatter gather "POM2 addressing".
The other method is called "POM3 addressing". In order to use the
"POM2 addressing", the customer will need a firmware upgrade. If the
customer has less than 36GB of memory, there is no reason they have to
upgrade since "POM3 adrressing" is used in the existing patch. Also,
we only tested the "POM2 addressing" in that range, so we are not sure whether it will work for all memory ranges. So the bottom line is less risk and impact when applying the "POM2" change only within that range.
Quoted 8 lines
drivers/message/fusion/mptbase.c mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT
Quoted 4 lines
drivers/message/fusion/mptbase.c +4
-0+/* +* 1078 errata workaround for the 36GB limitation +*/ + if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >>32) == 9) {
This looks really odd. 36GB (in fact 32-64GB) will have (
dma_addr>>
32) == 3 not 9
I do believe this calculation is correct. The three effected ranges are:
(1) 0x900000000 - 0x91000FFFF
(2) 0x918000000 - 0x918000FFF
(3) 0x91C000000 - 0x91C000FFF
Quoted 10 lines
drivers/message/fusion/mptbase.c mpt_attach(struct pci_dev *pdev, const s · line 1568
Quoted 4 lines
drivers/message/fusion/mptbase.c +4
-0+/* +* Setting up proper handlers for scatter gather handling +*/ +if (sizeof (dma_addr_t) ==sizeof (u64)) {use
dma_get_required_mask()here ... that will tell you not only if you
were compiled for 64 bits, but also if the box would actually use them.
ok
Quoted 10 lines
drivers/message/fusion/mptbase.c PrimeIocFifos(MPT_ADAPTER *ioc)
Quoted 9 lines
drivers/message/fusion/mptbase.c +4
-0/* Prime reply FIFO... */ if (ioc->reply_frames ==NULL ) {if ( (num_chain =initChainBuffers (ioc)) <0 )return -1 ; +/* +* 1078 errata workaround for the 36GB limitation +*/ + if (ioc->pcidev->device ==
MPI_MANUFACTPAGE_DEVID_SAS1078&&
Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ ioc->dma_mask > MPT_DMA_35BIT_MASK) { + if (!pci_set_dma_mask(ioc->pcidev,
DMA_32BIT_MASK)Don't you want to be setting a 35 bit mask here, not a 32 bit one ... not that it really matters, most architectures will happily give you 32
bits anyway (except possibly altix).
I can't off hand remember why I did that, but I agree with your point.
Quoted 4 lines
There's already a definition
DMA_35BIT_MASKininclude/linux/dma-mapping.h... please use it.
ok, this was really a portability thing, but I agree the mainstream code should be using DMA_35BIT_MASK
Quoted 5 lines
drivers/message/fusion/mptbase.h typedef struct _MPT_ADAPTER · line 605
Quoted 2 lines
drivers/message/fusion/mptbase.h +2
-0+MPT_ADD_SGE add_sge; +u64 dma_mask;You don't need this ... isn't it going to be the same as
ioc->pcidev->dma_mask?
The general idea of the flag was to help in PrimeIocFifos, so the message frames are below the effected memory in the hardware errata, meanwhile we use full available physical memory for dma the scatter gather.
Eric