aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
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
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')
-rw-r--r--drivers/message/fusion/mptbase.c287
-rw-r--r--drivers/message/fusion/mptbase.h35
-rw-r--r--drivers/message/fusion/mptctl.c37
-rw-r--r--drivers/message/fusion/mptdebug.h3
-rw-r--r--drivers/message/fusion/mptfc.c10
-rw-r--r--drivers/message/fusion/mptsas.c18
-rw-r--r--drivers/message/fusion/mptscsih.c102
-rw-r--r--drivers/message/fusion/mptspi.c14
8 files changed, 318 insertions, 188 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 5d496a99e034..a66369218c97 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -998,7 +998,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
998 998
999/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 999/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1000/** 1000/**
1001 * mpt_add_sge - Place a simple SGE at address pAddr. 1001 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1002 * @pAddr: virtual address for SGE 1002 * @pAddr: virtual address for SGE
1003 * @flagslength: SGE flags and data transfer length 1003 * @flagslength: SGE flags and data transfer length
1004 * @dma_addr: Physical address 1004 * @dma_addr: Physical address
@@ -1006,23 +1006,117 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1006 * This routine places a MPT request frame back on the MPT adapter's 1006 * This routine places a MPT request frame back on the MPT adapter's
1007 * FreeQ. 1007 * FreeQ.
1008 */ 1008 */
1009void 1009static void
1010mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr) 1010mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1011{ 1011{
1012 if (sizeof(dma_addr_t) == sizeof(u64)) { 1012 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1013 SGESimple64_t *pSge = (SGESimple64_t *) pAddr; 1013 pSge->FlagsLength = cpu_to_le32(flagslength);
1014 pSge->Address = cpu_to_le32(dma_addr);
1015}
1016
1017/**
1018 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1019 * @pAddr: virtual address for SGE
1020 * @flagslength: SGE flags and data transfer length
1021 * @dma_addr: Physical address
1022 *
1023 * This routine places a MPT request frame back on the MPT adapter's
1024 * FreeQ.
1025 **/
1026static void
1027mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1028{
1029 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1030 pSge->Address.Low = cpu_to_le32
1031 (lower_32_bits((unsigned long)(dma_addr)));
1032 pSge->Address.High = cpu_to_le32
1033 (upper_32_bits((unsigned long)dma_addr));
1034 pSge->FlagsLength = cpu_to_le32
1035 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1036}
1037
1038/**
1039 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr
1040 * (1078 workaround).
1041 * @pAddr: virtual address for SGE
1042 * @flagslength: SGE flags and data transfer length
1043 * @dma_addr: Physical address
1044 *
1045 * This routine places a MPT request frame back on the MPT adapter's
1046 * FreeQ.
1047 **/
1048static void
1049mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1050{
1051 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1052 u32 tmp;
1053
1054 pSge->Address.Low = cpu_to_le32
1055 (lower_32_bits((unsigned long)(dma_addr)));
1056 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1057
1058 /*
1059 * 1078 errata workaround for the 36GB limitation
1060 */
1061 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1062 flagslength |=
1063 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1064 tmp |= (1<<31);
1065 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1066 printk(KERN_DEBUG "1078 P0M2 addressing for "
1067 "addr = 0x%llx len = %d\n",
1068 (unsigned long long)dma_addr,
1069 MPI_SGE_LENGTH(flagslength));
1070 }
1071
1072 pSge->Address.High = cpu_to_le32(tmp);
1073 pSge->FlagsLength = cpu_to_le32(
1074 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1075}
1076
1077/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1078/**
1079 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1080 * @pAddr: virtual address for SGE
1081 * @next: nextChainOffset value (u32's)
1082 * @length: length of next SGL segment
1083 * @dma_addr: Physical address
1084 *
1085 */
1086static void
1087mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1088{
1089 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1090 pChain->Length = cpu_to_le16(length);
1091 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1092 pChain->NextChainOffset = next;
1093 pChain->Address = cpu_to_le32(dma_addr);
1094}
1095
1096/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1097/**
1098 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1099 * @pAddr: virtual address for SGE
1100 * @next: nextChainOffset value (u32's)
1101 * @length: length of next SGL segment
1102 * @dma_addr: Physical address
1103 *
1104 */
1105static void
1106mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1107{
1108 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1014 u32 tmp = dma_addr & 0xFFFFFFFF; 1109 u32 tmp = dma_addr & 0xFFFFFFFF;
1015 1110
1016 pSge->FlagsLength = cpu_to_le32(flagslength); 1111 pChain->Length = cpu_to_le16(length);
1017 pSge->Address.Low = cpu_to_le32(tmp); 1112 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1018 tmp = (u32) ((u64)dma_addr >> 32); 1113 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1019 pSge->Address.High = cpu_to_le32(tmp);
1020 1114
1021 } else { 1115 pChain->NextChainOffset = next;
1022 SGESimple32_t *pSge = (SGESimple32_t *) pAddr; 1116
1023 pSge->FlagsLength = cpu_to_le32(flagslength); 1117 pChain->Address.Low = cpu_to_le32(tmp);
1024 pSge->Address = cpu_to_le32(dma_addr); 1118 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1025 } 1119 pChain->Address.High = cpu_to_le32(tmp);
1026} 1120}
1027 1121
1028/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1122/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1225,7 +1319,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1225 } 1319 }
1226 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT; 1320 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1227 flags_length |= ioc->HostPageBuffer_sz; 1321 flags_length |= ioc->HostPageBuffer_sz;
1228 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma); 1322 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1229 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE; 1323 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1230 1324
1231return 0; 1325return 0;
@@ -1534,21 +1628,42 @@ mpt_mapresources(MPT_ADAPTER *ioc)
1534 1628
1535 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 1629 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1536 1630
1537 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) 1631 if (sizeof(dma_addr_t) > 4) {
1538 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { 1632 const uint64_t required_mask = dma_get_required_mask
1539 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1633 (&pdev->dev);
1540 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1634 if (required_mask > DMA_BIT_MASK(32)
1541 ioc->name)); 1635 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1542 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) 1636 && !pci_set_consistent_dma_mask(pdev,
1543 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { 1637 DMA_BIT_MASK(64))) {
1544 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1638 ioc->dma_mask = DMA_BIT_MASK(64);
1545 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1639 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1546 ioc->name)); 1640 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1641 ioc->name));
1642 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1643 && !pci_set_consistent_dma_mask(pdev,
1644 DMA_BIT_MASK(32))) {
1645 ioc->dma_mask = DMA_BIT_MASK(32);
1646 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1647 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1648 ioc->name));
1649 } else {
1650 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1651 ioc->name, pci_name(pdev));
1652 return r;
1653 }
1547 } else { 1654 } else {
1548 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", 1655 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1549 ioc->name, pci_name(pdev)); 1656 && !pci_set_consistent_dma_mask(pdev,
1550 pci_release_selected_regions(pdev, ioc->bars); 1657 DMA_BIT_MASK(32))) {
1551 return r; 1658 ioc->dma_mask = DMA_BIT_MASK(32);
1659 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1660 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1661 ioc->name));
1662 } else {
1663 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1664 ioc->name, pci_name(pdev));
1665 return r;
1666 }
1552 } 1667 }
1553 1668
1554 mem_phys = msize = 0; 1669 mem_phys = msize = 0;
@@ -1650,6 +1765,23 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1650 return r; 1765 return r;
1651 } 1766 }
1652 1767
1768 /*
1769 * Setting up proper handlers for scatter gather handling
1770 */
1771 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1772 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1773 ioc->add_sge = &mpt_add_sge_64bit_1078;
1774 else
1775 ioc->add_sge = &mpt_add_sge_64bit;
1776 ioc->add_chain = &mpt_add_chain_64bit;
1777 ioc->sg_addr_size = 8;
1778 } else {
1779 ioc->add_sge = &mpt_add_sge;
1780 ioc->add_chain = &mpt_add_chain;
1781 ioc->sg_addr_size = 4;
1782 }
1783 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1784
1653 ioc->alloc_total = sizeof(MPT_ADAPTER); 1785 ioc->alloc_total = sizeof(MPT_ADAPTER);
1654 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ 1786 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1655 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1787 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
@@ -1994,6 +2126,21 @@ mpt_resume(struct pci_dev *pdev)
1994 if (err) 2126 if (err)
1995 return err; 2127 return err;
1996 2128
2129 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2130 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2131 ioc->add_sge = &mpt_add_sge_64bit_1078;
2132 else
2133 ioc->add_sge = &mpt_add_sge_64bit;
2134 ioc->add_chain = &mpt_add_chain_64bit;
2135 ioc->sg_addr_size = 8;
2136 } else {
2137
2138 ioc->add_sge = &mpt_add_sge;
2139 ioc->add_chain = &mpt_add_chain;
2140 ioc->sg_addr_size = 4;
2141 }
2142 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2143
1997 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n", 2144 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1998 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT), 2145 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1999 CHIPREG_READ32(&ioc->chip->Doorbell)); 2146 CHIPREG_READ32(&ioc->chip->Doorbell));
@@ -3325,11 +3472,10 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3325 FWUpload_t *prequest; 3472 FWUpload_t *prequest;
3326 FWUploadReply_t *preply; 3473 FWUploadReply_t *preply;
3327 FWUploadTCSGE_t *ptcsge; 3474 FWUploadTCSGE_t *ptcsge;
3328 int sgeoffset;
3329 u32 flagsLength; 3475 u32 flagsLength;
3330 int ii, sz, reply_sz; 3476 int ii, sz, reply_sz;
3331 int cmdStatus; 3477 int cmdStatus;
3332 3478 int request_size;
3333 /* If the image size is 0, we are done. 3479 /* If the image size is 0, we are done.
3334 */ 3480 */
3335 if ((sz = ioc->facts.FWImageSize) == 0) 3481 if ((sz = ioc->facts.FWImageSize) == 0)
@@ -3364,18 +3510,17 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3364 ptcsge->ImageSize = cpu_to_le32(sz); 3510 ptcsge->ImageSize = cpu_to_le32(sz);
3365 ptcsge++; 3511 ptcsge++;
3366 3512
3367 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3368
3369 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz; 3513 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3370 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma); 3514 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3371 3515 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3372 sgeoffset += sizeof(u32) + sizeof(dma_addr_t); 3516 ioc->SGE_size;
3373 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n", 3517 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3374 ioc->name, prequest, sgeoffset)); 3518 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3519 ioc->facts.FWImageSize, request_size));
3375 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest); 3520 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3376 3521
3377 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest, 3522 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3378 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag); 3523 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3379 3524
3380 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii)); 3525 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3381 3526
@@ -4090,18 +4235,18 @@ initChainBuffers(MPT_ADAPTER *ioc)
4090 * num_sge = num sge in request frame + last chain buffer 4235 * num_sge = num sge in request frame + last chain buffer
4091 * scale = num sge per chain buffer if no chain element 4236 * scale = num sge per chain buffer if no chain element
4092 */ 4237 */
4093 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 4238 scale = ioc->req_sz / ioc->SGE_size;
4094 if (sizeof(dma_addr_t) == sizeof(u64)) 4239 if (ioc->sg_addr_size == sizeof(u64))
4095 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); 4240 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4096 else 4241 else
4097 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); 4242 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4098 4243
4099 if (sizeof(dma_addr_t) == sizeof(u64)) { 4244 if (ioc->sg_addr_size == sizeof(u64)) {
4100 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + 4245 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4101 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); 4246 (ioc->req_sz - 60) / ioc->SGE_size;
4102 } else { 4247 } else {
4103 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + 4248 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4104 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); 4249 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4105 } 4250 }
4106 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n", 4251 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4107 ioc->name, num_sge, numSGE)); 4252 ioc->name, num_sge, numSGE));
@@ -4161,12 +4306,42 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
4161 dma_addr_t alloc_dma; 4306 dma_addr_t alloc_dma;
4162 u8 *mem; 4307 u8 *mem;
4163 int i, reply_sz, sz, total_size, num_chain; 4308 int i, reply_sz, sz, total_size, num_chain;
4309 u64 dma_mask;
4310
4311 dma_mask = 0;
4164 4312
4165 /* Prime reply FIFO... */ 4313 /* Prime reply FIFO... */
4166 4314
4167 if (ioc->reply_frames == NULL) { 4315 if (ioc->reply_frames == NULL) {
4168 if ( (num_chain = initChainBuffers(ioc)) < 0) 4316 if ( (num_chain = initChainBuffers(ioc)) < 0)
4169 return -1; 4317 return -1;
4318 /*
4319 * 1078 errata workaround for the 36GB limitation
4320 */
4321 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4322 ioc->dma_mask > DMA_35BIT_MASK) {
4323 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4324 && !pci_set_consistent_dma_mask(ioc->pcidev,
4325 DMA_BIT_MASK(32))) {
4326 dma_mask = DMA_35BIT_MASK;
4327 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4328 "setting 35 bit addressing for "
4329 "Request/Reply/Chain and Sense Buffers\n",
4330 ioc->name));
4331 } else {
4332 /*Reseting DMA mask to 64 bit*/
4333 pci_set_dma_mask(ioc->pcidev,
4334 DMA_BIT_MASK(64));
4335 pci_set_consistent_dma_mask(ioc->pcidev,
4336 DMA_BIT_MASK(64));
4337
4338 printk(MYIOC_s_ERR_FMT
4339 "failed setting 35 bit addressing for "
4340 "Request/Reply/Chain and Sense Buffers\n",
4341 ioc->name);
4342 return -1;
4343 }
4344 }
4170 4345
4171 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth); 4346 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4172 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n", 4347 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
@@ -4305,6 +4480,12 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
4305 alloc_dma += ioc->reply_sz; 4480 alloc_dma += ioc->reply_sz;
4306 } 4481 }
4307 4482
4483 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4484 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4485 ioc->dma_mask))
4486 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4487 "restoring 64 bit addressing\n", ioc->name));
4488
4308 return 0; 4489 return 0;
4309 4490
4310out_fail: 4491out_fail:
@@ -4324,6 +4505,13 @@ out_fail:
4324 ioc->sense_buf_pool, ioc->sense_buf_pool_dma); 4505 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4325 ioc->sense_buf_pool = NULL; 4506 ioc->sense_buf_pool = NULL;
4326 } 4507 }
4508
4509 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4510 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4511 DMA_BIT_MASK(64)))
4512 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4513 "restoring 64 bit addressing\n", ioc->name));
4514
4327 return -1; 4515 return -1;
4328} 4516}
4329 4517
@@ -5926,7 +6114,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5926 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action)); 6114 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5927 } 6115 }
5928 6116
5929 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); 6117 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5930 6118
5931 /* Append pCfg pointer to end of mf 6119 /* Append pCfg pointer to end of mf
5932 */ 6120 */
@@ -7613,7 +7801,6 @@ EXPORT_SYMBOL(mpt_get_msg_frame);
7613EXPORT_SYMBOL(mpt_put_msg_frame); 7801EXPORT_SYMBOL(mpt_put_msg_frame);
7614EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri); 7802EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7615EXPORT_SYMBOL(mpt_free_msg_frame); 7803EXPORT_SYMBOL(mpt_free_msg_frame);
7616EXPORT_SYMBOL(mpt_add_sge);
7617EXPORT_SYMBOL(mpt_send_handshake_request); 7804EXPORT_SYMBOL(mpt_send_handshake_request);
7618EXPORT_SYMBOL(mpt_verify_adapter); 7805EXPORT_SYMBOL(mpt_verify_adapter);
7619EXPORT_SYMBOL(mpt_GetIocState); 7806EXPORT_SYMBOL(mpt_GetIocState);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index b3e981d2a506..4a606764e317 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.04.07" 79#define MPT_LINUX_VERSION_COMMON "3.04.08"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.07" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.08"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
83#define show_mptmod_ver(s,ver) \ 83#define show_mptmod_ver(s,ver) \
@@ -134,6 +134,7 @@
134 134
135#define MPT_COALESCING_TIMEOUT 0x10 135#define MPT_COALESCING_TIMEOUT 0x10
136 136
137
137/* 138/*
138 * SCSI transfer rate defines. 139 * SCSI transfer rate defines.
139 */ 140 */
@@ -564,6 +565,10 @@ struct mptfc_rport_info
564 u8 flags; 565 u8 flags;
565}; 566};
566 567
568typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr);
569typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length,
570 dma_addr_t dma_addr);
571
567/* 572/*
568 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS 573 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
569 */ 574 */
@@ -600,6 +605,10 @@ typedef struct _MPT_ADAPTER
600 int reply_depth; /* Num Allocated reply frames */ 605 int reply_depth; /* Num Allocated reply frames */
601 int reply_sz; /* Reply frame size */ 606 int reply_sz; /* Reply frame size */
602 int num_chain; /* Number of chain buffers */ 607 int num_chain; /* Number of chain buffers */
608 MPT_ADD_SGE add_sge; /* Pointer to add_sge
609 function */
610 MPT_ADD_CHAIN add_chain; /* Pointer to add_chain
611 function */
603 /* Pool of buffers for chaining. ReqToChain 612 /* Pool of buffers for chaining. ReqToChain
604 * and ChainToChain track index of chain buffers. 613 * and ChainToChain track index of chain buffers.
605 * ChainBuffer (DMA) virt/phys addresses. 614 * ChainBuffer (DMA) virt/phys addresses.
@@ -711,12 +720,15 @@ typedef struct _MPT_ADAPTER
711 struct workqueue_struct *fc_rescan_work_q; 720 struct workqueue_struct *fc_rescan_work_q;
712 struct scsi_cmnd **ScsiLookup; 721 struct scsi_cmnd **ScsiLookup;
713 spinlock_t scsi_lookup_lock; 722 spinlock_t scsi_lookup_lock;
714 723 u64 dma_mask;
715 char reset_work_q_name[20]; 724 char reset_work_q_name[20];
716 struct workqueue_struct *reset_work_q; 725 struct workqueue_struct *reset_work_q;
717 struct delayed_work fault_reset_work; 726 struct delayed_work fault_reset_work;
718 spinlock_t fault_reset_work_lock; 727 spinlock_t fault_reset_work_lock;
719 728
729 u8 sg_addr_size;
730 u8 SGE_size;
731
720} MPT_ADAPTER; 732} MPT_ADAPTER;
721 733
722/* 734/*
@@ -753,13 +765,14 @@ typedef struct _mpt_sge {
753 dma_addr_t Address; 765 dma_addr_t Address;
754} MptSge_t; 766} MptSge_t;
755 767
756#define mpt_addr_size() \
757 ((sizeof(dma_addr_t) == sizeof(u64)) ? MPI_SGE_FLAGS_64_BIT_ADDRESSING : \
758 MPI_SGE_FLAGS_32_BIT_ADDRESSING)
759 768
760#define mpt_msg_flags() \ 769#define mpt_msg_flags(ioc) \
761 ((sizeof(dma_addr_t) == sizeof(u64)) ? MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64 : \ 770 (ioc->sg_addr_size == sizeof(u64)) ? \
762 MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32) 771 MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64 : \
772 MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32
773
774#define MPT_SGE_FLAGS_64_BIT_ADDRESSING \
775 (MPI_SGE_FLAGS_64_BIT_ADDRESSING << MPI_SGE_FLAGS_SHIFT)
763 776
764/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 777/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
765/* 778/*
@@ -909,7 +922,6 @@ extern MPT_FRAME_HDR *mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc);
909extern void mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); 922extern void mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
910extern void mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); 923extern void mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
911extern void mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); 924extern void mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
912extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr);
913 925
914extern int mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag); 926extern int mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag);
915extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp); 927extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
@@ -959,7 +971,6 @@ extern int mpt_fwfault_debug;
959#define MPT_SGE_FLAGS_END_OF_BUFFER (0x40000000) 971#define MPT_SGE_FLAGS_END_OF_BUFFER (0x40000000)
960#define MPT_SGE_FLAGS_LOCAL_ADDRESS (0x08000000) 972#define MPT_SGE_FLAGS_LOCAL_ADDRESS (0x08000000)
961#define MPT_SGE_FLAGS_DIRECTION (0x04000000) 973#define MPT_SGE_FLAGS_DIRECTION (0x04000000)
962#define MPT_SGE_FLAGS_ADDRESSING (mpt_addr_size() << MPI_SGE_FLAGS_SHIFT)
963#define MPT_SGE_FLAGS_END_OF_LIST (0x01000000) 974#define MPT_SGE_FLAGS_END_OF_LIST (0x01000000)
964 975
965#define MPT_SGE_FLAGS_TRANSACTION_ELEMENT (0x00000000) 976#define MPT_SGE_FLAGS_TRANSACTION_ELEMENT (0x00000000)
@@ -972,14 +983,12 @@ extern int mpt_fwfault_debug;
972 MPT_SGE_FLAGS_END_OF_BUFFER | \ 983 MPT_SGE_FLAGS_END_OF_BUFFER | \
973 MPT_SGE_FLAGS_END_OF_LIST | \ 984 MPT_SGE_FLAGS_END_OF_LIST | \
974 MPT_SGE_FLAGS_SIMPLE_ELEMENT | \ 985 MPT_SGE_FLAGS_SIMPLE_ELEMENT | \
975 MPT_SGE_FLAGS_ADDRESSING | \
976 MPT_TRANSFER_IOC_TO_HOST) 986 MPT_TRANSFER_IOC_TO_HOST)
977#define MPT_SGE_FLAGS_SSIMPLE_WRITE \ 987#define MPT_SGE_FLAGS_SSIMPLE_WRITE \
978 (MPT_SGE_FLAGS_LAST_ELEMENT | \ 988 (MPT_SGE_FLAGS_LAST_ELEMENT | \
979 MPT_SGE_FLAGS_END_OF_BUFFER | \ 989 MPT_SGE_FLAGS_END_OF_BUFFER | \
980 MPT_SGE_FLAGS_END_OF_LIST | \ 990 MPT_SGE_FLAGS_END_OF_LIST | \
981 MPT_SGE_FLAGS_SIMPLE_ELEMENT | \ 991 MPT_SGE_FLAGS_SIMPLE_ELEMENT | \
982 MPT_SGE_FLAGS_ADDRESSING | \
983 MPT_TRANSFER_HOST_TO_IOC) 992 MPT_TRANSFER_HOST_TO_IOC)
984 993
985/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 994/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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;
diff --git a/drivers/message/fusion/mptdebug.h b/drivers/message/fusion/mptdebug.h
index 510b9f492093..28e478879284 100644
--- a/drivers/message/fusion/mptdebug.h
+++ b/drivers/message/fusion/mptdebug.h
@@ -58,6 +58,7 @@
58#define MPT_DEBUG_FC 0x00080000 58#define MPT_DEBUG_FC 0x00080000
59#define MPT_DEBUG_SAS 0x00100000 59#define MPT_DEBUG_SAS 0x00100000
60#define MPT_DEBUG_SAS_WIDE 0x00200000 60#define MPT_DEBUG_SAS_WIDE 0x00200000
61#define MPT_DEBUG_36GB_MEM 0x00400000
61 62
62/* 63/*
63 * CONFIG_FUSION_LOGGING - enabled in Kconfig 64 * CONFIG_FUSION_LOGGING - enabled in Kconfig
@@ -135,6 +136,8 @@
135#define dsaswideprintk(IOC, CMD) \ 136#define dsaswideprintk(IOC, CMD) \
136 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE) 137 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE)
137 138
139#define d36memprintk(IOC, CMD) \
140 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_36GB_MEM)
138 141
139 142
140/* 143/*
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index c3c24fdf9fb6..da16b47a3f32 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -1251,17 +1251,15 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1251 * A slightly different algorithm is required for 1251 * A slightly different algorithm is required for
1252 * 64bit SGEs. 1252 * 64bit SGEs.
1253 */ 1253 */
1254 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 1254 scale = ioc->req_sz/ioc->SGE_size;
1255 if (sizeof(dma_addr_t) == sizeof(u64)) { 1255 if (ioc->sg_addr_size == sizeof(u64)) {
1256 numSGE = (scale - 1) * 1256 numSGE = (scale - 1) *
1257 (ioc->facts.MaxChainDepth-1) + scale + 1257 (ioc->facts.MaxChainDepth-1) + scale +
1258 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 1258 (ioc->req_sz - 60) / ioc->SGE_size;
1259 sizeof(u32));
1260 } else { 1259 } else {
1261 numSGE = 1 + (scale - 1) * 1260 numSGE = 1 + (scale - 1) *
1262 (ioc->facts.MaxChainDepth-1) + scale + 1261 (ioc->facts.MaxChainDepth-1) + scale +
1263 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 1262 (ioc->req_sz - 64) / ioc->SGE_size;
1264 sizeof(u32));
1265 } 1263 }
1266 1264
1267 if (numSGE < sh->sg_tablesize) { 1265 if (numSGE < sh->sg_tablesize) {
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index a9019f081b97..b162f7a1c563 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1319,15 +1319,15 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1319 /* request */ 1319 /* request */
1320 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT | 1320 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1321 MPI_SGE_FLAGS_END_OF_BUFFER | 1321 MPI_SGE_FLAGS_END_OF_BUFFER |
1322 MPI_SGE_FLAGS_DIRECTION | 1322 MPI_SGE_FLAGS_DIRECTION)
1323 mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT; 1323 << MPI_SGE_FLAGS_SHIFT;
1324 flagsLength |= (req->data_len - 4); 1324 flagsLength |= (req->data_len - 4);
1325 1325
1326 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio), 1326 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
1327 req->data_len, PCI_DMA_BIDIRECTIONAL); 1327 req->data_len, PCI_DMA_BIDIRECTIONAL);
1328 if (!dma_addr_out) 1328 if (!dma_addr_out)
1329 goto put_mf; 1329 goto put_mf;
1330 mpt_add_sge(psge, flagsLength, dma_addr_out); 1330 ioc->add_sge(psge, flagsLength, dma_addr_out);
1331 psge += (sizeof(u32) + sizeof(dma_addr_t)); 1331 psge += (sizeof(u32) + sizeof(dma_addr_t));
1332 1332
1333 /* response */ 1333 /* response */
@@ -1337,7 +1337,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1337 rsp->data_len, PCI_DMA_BIDIRECTIONAL); 1337 rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1338 if (!dma_addr_in) 1338 if (!dma_addr_in)
1339 goto unmap; 1339 goto unmap;
1340 mpt_add_sge(psge, flagsLength, dma_addr_in); 1340 ioc->add_sge(psge, flagsLength, dma_addr_in);
1341 1341
1342 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); 1342 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1343 1343
@@ -3211,17 +3211,15 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3211 * A slightly different algorithm is required for 3211 * A slightly different algorithm is required for
3212 * 64bit SGEs. 3212 * 64bit SGEs.
3213 */ 3213 */
3214 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 3214 scale = ioc->req_sz/ioc->SGE_size;
3215 if (sizeof(dma_addr_t) == sizeof(u64)) { 3215 if (ioc->sg_addr_size == sizeof(u64)) {
3216 numSGE = (scale - 1) * 3216 numSGE = (scale - 1) *
3217 (ioc->facts.MaxChainDepth-1) + scale + 3217 (ioc->facts.MaxChainDepth-1) + scale +
3218 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 3218 (ioc->req_sz - 60) / ioc->SGE_size;
3219 sizeof(u32));
3220 } else { 3219 } else {
3221 numSGE = 1 + (scale - 1) * 3220 numSGE = 1 + (scale - 1) *
3222 (ioc->facts.MaxChainDepth-1) + scale + 3221 (ioc->facts.MaxChainDepth-1) + scale +
3223 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 3222 (ioc->req_sz - 64) / ioc->SGE_size;
3224 sizeof(u32));
3225 } 3223 }
3226 3224
3227 if (numSGE < sh->sg_tablesize) { 3225 if (numSGE < sh->sg_tablesize) {
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index e62c6bc4ad33..8c08c73f194c 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -113,69 +113,6 @@ int mptscsih_resume(struct pci_dev *pdev);
113 113
114#define SNS_LEN(scp) SCSI_SENSE_BUFFERSIZE 114#define SNS_LEN(scp) SCSI_SENSE_BUFFERSIZE
115 115
116/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
117/**
118 * mptscsih_add_sge - Place a simple SGE at address pAddr.
119 * @pAddr: virtual address for SGE
120 * @flagslength: SGE flags and data transfer length
121 * @dma_addr: Physical address
122 *
123 * This routine places a MPT request frame back on the MPT adapter's
124 * FreeQ.
125 */
126static inline void
127mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
128{
129 if (sizeof(dma_addr_t) == sizeof(u64)) {
130 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
131 u32 tmp = dma_addr & 0xFFFFFFFF;
132
133 pSge->FlagsLength = cpu_to_le32(flagslength);
134 pSge->Address.Low = cpu_to_le32(tmp);
135 tmp = (u32) ((u64)dma_addr >> 32);
136 pSge->Address.High = cpu_to_le32(tmp);
137
138 } else {
139 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
140 pSge->FlagsLength = cpu_to_le32(flagslength);
141 pSge->Address = cpu_to_le32(dma_addr);
142 }
143} /* mptscsih_add_sge() */
144
145/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
146/**
147 * mptscsih_add_chain - Place a chain SGE at address pAddr.
148 * @pAddr: virtual address for SGE
149 * @next: nextChainOffset value (u32's)
150 * @length: length of next SGL segment
151 * @dma_addr: Physical address
152 *
153 * This routine places a MPT request frame back on the MPT adapter's
154 * FreeQ.
155 */
156static inline void
157mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
158{
159 if (sizeof(dma_addr_t) == sizeof(u64)) {
160 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
161 u32 tmp = dma_addr & 0xFFFFFFFF;
162
163 pChain->Length = cpu_to_le16(length);
164 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
165
166 pChain->NextChainOffset = next;
167
168 pChain->Address.Low = cpu_to_le32(tmp);
169 tmp = (u32) ((u64)dma_addr >> 32);
170 pChain->Address.High = cpu_to_le32(tmp);
171 } else {
172 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
173 pChain->Length = cpu_to_le16(length);
174 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
175 pChain->NextChainOffset = next;
176 pChain->Address = cpu_to_le32(dma_addr);
177 }
178} /* mptscsih_add_chain() */
179 116
180/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 117/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
181/* 118/*
@@ -281,10 +218,10 @@ mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
281 */ 218 */
282 219
283nextSGEset: 220nextSGEset:
284 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) ); 221 numSgeSlots = ((frm_sz - sgeOffset) / ioc->SGE_size);
285 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots; 222 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
286 223
287 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir; 224 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | sgdir;
288 225
289 /* Get first (num - 1) SG elements 226 /* Get first (num - 1) SG elements
290 * Skip any SG entries with a length of 0 227 * Skip any SG entries with a length of 0
@@ -299,11 +236,11 @@ nextSGEset:
299 } 236 }
300 237
301 v2 = sg_dma_address(sg); 238 v2 = sg_dma_address(sg);
302 mptscsih_add_sge(psge, sgflags | thisxfer, v2); 239 ioc->add_sge(psge, sgflags | thisxfer, v2);
303 240
304 sg = sg_next(sg); /* Get next SG element from the OS */ 241 sg = sg_next(sg); /* Get next SG element from the OS */
305 psge += (sizeof(u32) + sizeof(dma_addr_t)); 242 psge += ioc->SGE_size;
306 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t)); 243 sgeOffset += ioc->SGE_size;
307 sg_done++; 244 sg_done++;
308 } 245 }
309 246
@@ -320,12 +257,8 @@ nextSGEset:
320 thisxfer = sg_dma_len(sg); 257 thisxfer = sg_dma_len(sg);
321 258
322 v2 = sg_dma_address(sg); 259 v2 = sg_dma_address(sg);
323 mptscsih_add_sge(psge, sgflags | thisxfer, v2); 260 ioc->add_sge(psge, sgflags | thisxfer, v2);
324 /* 261 sgeOffset += ioc->SGE_size;
325 sg = sg_next(sg);
326 psge += (sizeof(u32) + sizeof(dma_addr_t));
327 */
328 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
329 sg_done++; 262 sg_done++;
330 263
331 if (chainSge) { 264 if (chainSge) {
@@ -334,7 +267,8 @@ nextSGEset:
334 * Update the chain element 267 * Update the chain element
335 * Offset and Length fields. 268 * Offset and Length fields.
336 */ 269 */
337 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off); 270 ioc->add_chain((char *)chainSge, 0, sgeOffset,
271 ioc->ChainBufferDMA + chain_dma_off);
338 } else { 272 } else {
339 /* The current buffer is the original MF 273 /* The current buffer is the original MF
340 * and there is no Chain buffer. 274 * and there is no Chain buffer.
@@ -367,7 +301,7 @@ nextSGEset:
367 * set properly). 301 * set properly).
368 */ 302 */
369 if (sg_done) { 303 if (sg_done) {
370 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t))); 304 u32 *ptmp = (u32 *) (psge - ioc->SGE_size);
371 sgflags = le32_to_cpu(*ptmp); 305 sgflags = le32_to_cpu(*ptmp);
372 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT; 306 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
373 *ptmp = cpu_to_le32(sgflags); 307 *ptmp = cpu_to_le32(sgflags);
@@ -381,8 +315,9 @@ nextSGEset:
381 * Old chain element is now complete. 315 * Old chain element is now complete.
382 */ 316 */
383 u8 nextChain = (u8) (sgeOffset >> 2); 317 u8 nextChain = (u8) (sgeOffset >> 2);
384 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t)); 318 sgeOffset += ioc->SGE_size;
385 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off); 319 ioc->add_chain((char *)chainSge, nextChain, sgeOffset,
320 ioc->ChainBufferDMA + chain_dma_off);
386 } else { 321 } else {
387 /* The original MF buffer requires a chain buffer - 322 /* The original MF buffer requires a chain buffer -
388 * set the offset. 323 * set the offset.
@@ -1422,7 +1357,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1422 pScsiReq->CDBLength = SCpnt->cmd_len; 1357 pScsiReq->CDBLength = SCpnt->cmd_len;
1423 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; 1358 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1424 pScsiReq->Reserved = 0; 1359 pScsiReq->Reserved = 0;
1425 pScsiReq->MsgFlags = mpt_msg_flags(); 1360 pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1426 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN); 1361 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1427 pScsiReq->Control = cpu_to_le32(scsictl); 1362 pScsiReq->Control = cpu_to_le32(scsictl);
1428 1363
@@ -1448,7 +1383,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1448 */ 1383 */
1449 if (datalen == 0) { 1384 if (datalen == 0) {
1450 /* Add a NULL SGE */ 1385 /* Add a NULL SGE */
1451 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0, 1386 ioc->add_sge((char *)&pScsiReq->SGL,
1387 MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1452 (dma_addr_t) -1); 1388 (dma_addr_t) -1);
1453 } else { 1389 } else {
1454 /* Add a 32 or 64 bit SGE */ 1390 /* Add a 32 or 64 bit SGE */
@@ -3172,7 +3108,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3172 3108
3173 pScsiReq->Reserved = 0; 3109 pScsiReq->Reserved = 0;
3174 3110
3175 pScsiReq->MsgFlags = mpt_msg_flags(); 3111 pScsiReq->MsgFlags = mpt_msg_flags(ioc);
3176 /* MsgContext set in mpt_get_msg_fram call */ 3112 /* MsgContext set in mpt_get_msg_fram call */
3177 3113
3178 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN); 3114 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
@@ -3199,11 +3135,11 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3199 ioc->name, cmd, io->channel, io->id, io->lun)); 3135 ioc->name, cmd, io->channel, io->id, io->lun));
3200 3136
3201 if (dir == MPI_SCSIIO_CONTROL_READ) { 3137 if (dir == MPI_SCSIIO_CONTROL_READ) {
3202 mpt_add_sge((char *) &pScsiReq->SGL, 3138 ioc->add_sge((char *) &pScsiReq->SGL,
3203 MPT_SGE_FLAGS_SSIMPLE_READ | io->size, 3139 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3204 io->data_dma); 3140 io->data_dma);
3205 } else { 3141 } else {
3206 mpt_add_sge((char *) &pScsiReq->SGL, 3142 ioc->add_sge((char *) &pScsiReq->SGL,
3207 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, 3143 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3208 io->data_dma); 3144 io->data_dma);
3209 } 3145 }
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 61620144e49c..643a3c6443af 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -300,7 +300,7 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id)
300 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | 300 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
301 (IOCPage4Ptr->Header.PageLength + ii) * 4; 301 (IOCPage4Ptr->Header.PageLength + ii) * 4;
302 302
303 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); 303 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
304 304
305 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 305 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
306 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", 306 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
@@ -643,7 +643,7 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
643 pReq->Reserved2 = 0; 643 pReq->Reserved2 = 0;
644 pReq->ActionDataWord = 0; /* Reserved for this action */ 644 pReq->ActionDataWord = 0; /* Reserved for this action */
645 645
646 mpt_add_sge((char *)&pReq->ActionDataSGE, 646 ioc->add_sge((char *)&pReq->ActionDataSGE,
647 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); 647 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
648 648
649 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n", 649 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n",
@@ -1423,17 +1423,15 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1423 * A slightly different algorithm is required for 1423 * A slightly different algorithm is required for
1424 * 64bit SGEs. 1424 * 64bit SGEs.
1425 */ 1425 */
1426 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 1426 scale = ioc->req_sz/ioc->SGE_size;
1427 if (sizeof(dma_addr_t) == sizeof(u64)) { 1427 if (ioc->sg_addr_size == sizeof(u64)) {
1428 numSGE = (scale - 1) * 1428 numSGE = (scale - 1) *
1429 (ioc->facts.MaxChainDepth-1) + scale + 1429 (ioc->facts.MaxChainDepth-1) + scale +
1430 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 1430 (ioc->req_sz - 60) / ioc->SGE_size;
1431 sizeof(u32));
1432 } else { 1431 } else {
1433 numSGE = 1 + (scale - 1) * 1432 numSGE = 1 + (scale - 1) *
1434 (ioc->facts.MaxChainDepth-1) + scale + 1433 (ioc->facts.MaxChainDepth-1) + scale +
1435 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 1434 (ioc->req_sz - 64) / ioc->SGE_size;
1436 sizeof(u32));
1437 } 1435 }
1438 1436
1439 if (numSGE < sh->sg_tablesize) { 1437 if (numSGE < sh->sg_tablesize) {