aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptctl.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-05-29 07:07:04 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-09 18:21:31 -0400
commit14d0f0b063f5363984dd305a792854f9c23e9e97 (patch)
tree6d3e62845bc5273244f3b9ec535159cf5a8bdbc6 /drivers/message/fusion/mptctl.c
parent238ddbb98c327a7392ced5ae65216c55969749ea (diff)
[SCSI] mpt fusion: Fixing 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. Signed-off-by: Kashyap Desai <kadesai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/message/fusion/mptctl.c')
-rw-r--r--drivers/message/fusion/mptctl.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index c63817117c0a..bece386f1d4b 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -841,8 +841,9 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
841 * 96 8 841 * 96 8
842 * 64 4 842 * 64 4
843 */ 843 */
844 maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) - sizeof(FWDownloadTCSGE_t)) 844 maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) -
845 / (sizeof(dma_addr_t) + sizeof(u32)); 845 sizeof(FWDownloadTCSGE_t))
846 / iocp->SGE_size;
846 if (numfrags > maxfrags) { 847 if (numfrags > maxfrags) {
847 ret = -EMLINK; 848 ret = -EMLINK;
848 goto fwdl_out; 849 goto fwdl_out;
@@ -870,7 +871,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
870 if (nib == 0 || nib == 3) { 871 if (nib == 0 || nib == 3) {
871 ; 872 ;
872 } else if (sgIn->Address) { 873 } else if (sgIn->Address) {
873 mpt_add_sge(sgOut, sgIn->FlagsLength, sgIn->Address); 874 iocp->add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
874 n++; 875 n++;
875 if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) { 876 if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
876 printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - " 877 printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "
@@ -882,7 +883,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
882 } 883 }
883 sgIn++; 884 sgIn++;
884 bl++; 885 bl++;
885 sgOut += (sizeof(dma_addr_t) + sizeof(u32)); 886 sgOut += iocp->SGE_size;
886 } 887 }
887 888
888 DBG_DUMP_FW_DOWNLOAD(iocp, (u32 *)mf, numfrags); 889 DBG_DUMP_FW_DOWNLOAD(iocp, (u32 *)mf, numfrags);
@@ -1003,7 +1004,7 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
1003 * 1004 *
1004 */ 1005 */
1005 sgl = sglbuf; 1006 sgl = sglbuf;
1006 sg_spill = ((ioc->req_sz - sge_offset)/(sizeof(dma_addr_t) + sizeof(u32))) - 1; 1007 sg_spill = ((ioc->req_sz - sge_offset)/ioc->SGE_size) - 1;
1007 while (bytes_allocd < bytes) { 1008 while (bytes_allocd < bytes) {
1008 this_alloc = min(alloc_sz, bytes-bytes_allocd); 1009 this_alloc = min(alloc_sz, bytes-bytes_allocd);
1009 buflist[buflist_ent].len = this_alloc; 1010 buflist[buflist_ent].len = this_alloc;
@@ -1024,8 +1025,9 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
1024 dma_addr_t dma_addr; 1025 dma_addr_t dma_addr;
1025 1026
1026 bytes_allocd += this_alloc; 1027 bytes_allocd += this_alloc;
1027 sgl->FlagsLength = (0x10000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|this_alloc); 1028 sgl->FlagsLength = (0x10000000|sgdir|this_alloc);
1028 dma_addr = pci_map_single(ioc->pcidev, buflist[buflist_ent].kptr, this_alloc, dir); 1029 dma_addr = pci_map_single(ioc->pcidev,
1030 buflist[buflist_ent].kptr, this_alloc, dir);
1029 sgl->Address = dma_addr; 1031 sgl->Address = dma_addr;
1030 1032
1031 fragcnt++; 1033 fragcnt++;
@@ -1799,9 +1801,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1799 */ 1801 */
1800 sz = karg.dataSgeOffset * 4; 1802 sz = karg.dataSgeOffset * 4;
1801 if (karg.dataInSize > 0) 1803 if (karg.dataInSize > 0)
1802 sz += sizeof(dma_addr_t) + sizeof(u32); 1804 sz += ioc->SGE_size;
1803 if (karg.dataOutSize > 0) 1805 if (karg.dataOutSize > 0)
1804 sz += sizeof(dma_addr_t) + sizeof(u32); 1806 sz += ioc->SGE_size;
1805 1807
1806 if (sz > ioc->req_sz) { 1808 if (sz > ioc->req_sz) {
1807 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " 1809 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
@@ -1893,7 +1895,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1893 } 1895 }
1894 1896
1895 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; 1897 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1896 pScsiReq->MsgFlags |= mpt_msg_flags(); 1898 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
1897 1899
1898 1900
1899 /* verify that app has not requested 1901 /* verify that app has not requested
@@ -1979,7 +1981,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1979 int dataSize; 1981 int dataSize;
1980 1982
1981 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; 1983 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1982 pScsiReq->MsgFlags |= mpt_msg_flags(); 1984 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
1983 1985
1984 1986
1985 /* verify that app has not requested 1987 /* verify that app has not requested
@@ -2123,8 +2125,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
2123 if (karg.dataInSize > 0) { 2125 if (karg.dataInSize > 0) {
2124 flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT | 2126 flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2125 MPI_SGE_FLAGS_END_OF_BUFFER | 2127 MPI_SGE_FLAGS_END_OF_BUFFER |
2126 MPI_SGE_FLAGS_DIRECTION | 2128 MPI_SGE_FLAGS_DIRECTION)
2127 mpt_addr_size() )
2128 << MPI_SGE_FLAGS_SHIFT; 2129 << MPI_SGE_FLAGS_SHIFT;
2129 } else { 2130 } else {
2130 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE; 2131 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
@@ -2141,8 +2142,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
2141 /* Set up this SGE. 2142 /* Set up this SGE.
2142 * Copy to MF and to sglbuf 2143 * Copy to MF and to sglbuf
2143 */ 2144 */
2144 mpt_add_sge(psge, flagsLength, dma_addr_out); 2145 ioc->add_sge(psge, flagsLength, dma_addr_out);
2145 psge += (sizeof(u32) + sizeof(dma_addr_t)); 2146 psge += ioc->SGE_size;
2146 2147
2147 /* Copy user data to kernel space. 2148 /* Copy user data to kernel space.
2148 */ 2149 */
@@ -2175,13 +2176,13 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
2175 /* Set up this SGE 2176 /* Set up this SGE
2176 * Copy to MF and to sglbuf 2177 * Copy to MF and to sglbuf
2177 */ 2178 */
2178 mpt_add_sge(psge, flagsLength, dma_addr_in); 2179 ioc->add_sge(psge, flagsLength, dma_addr_in);
2179 } 2180 }
2180 } 2181 }
2181 } else { 2182 } else {
2182 /* Add a NULL SGE 2183 /* Add a NULL SGE
2183 */ 2184 */
2184 mpt_add_sge(psge, flagsLength, (dma_addr_t) -1); 2185 ioc->add_sge(psge, flagsLength, (dma_addr_t) -1);
2185 } 2186 }
2186 2187
2187 ioc->ioctl->wait_done = 0; 2188 ioc->ioctl->wait_done = 0;
@@ -2498,7 +2499,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2498 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); 2499 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2499 if (!pbuf) 2500 if (!pbuf)
2500 goto out; 2501 goto out;
2501 mpt_add_sge((char *)&IstwiRWRequest->SGL, 2502 ioc->add_sge((char *)&IstwiRWRequest->SGL,
2502 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma); 2503 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2503 2504
2504 ioc->ioctl->wait_done = 0; 2505 ioc->ioctl->wait_done = 0;