aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2005-09-09 10:25:54 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-19 13:42:31 -0400
commit82ffb67164064752a56669511545316075b41e1d (patch)
tree7b5c92f76e25ddf66419668412db147cde35a410
parent3ed7a4704beb66a155acd67b78b7e9a5674d55fb (diff)
[SCSI] fusion core changes for SAS support
- various bits for SAS support from the LSI driver. - use the device private data for the fusion target private data. this should be using the midlayer target data framework, but we can't move over to that until fusion has been switched to the generic DV code - use target ID and channel from the fusion target private data, because those in scsi_device will be different for mptsas Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/message/fusion/mptbase.c516
-rw-r--r--drivers/message/fusion/mptbase.h28
-rw-r--r--drivers/message/fusion/mptscsih.c15
3 files changed, 472 insertions, 87 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index f517d0692d5f..14d62d96ca41 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -141,7 +141,7 @@ static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
141static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); 141static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
142static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag); 142static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
143static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag); 143static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
144static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag); 144static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
145static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag); 145static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
146static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag); 146static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
147static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag); 147static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
@@ -152,6 +152,7 @@ static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
152static int GetLanConfigPages(MPT_ADAPTER *ioc); 152static int GetLanConfigPages(MPT_ADAPTER *ioc);
153static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum); 153static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
154static int GetIoUnitPage2(MPT_ADAPTER *ioc); 154static int GetIoUnitPage2(MPT_ADAPTER *ioc);
155int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
155static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); 156static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
156static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); 157static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
157static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); 158static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
@@ -159,6 +160,8 @@ static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
159static void mpt_timer_expired(unsigned long data); 160static void mpt_timer_expired(unsigned long data);
160static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); 161static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
161static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); 162static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
163static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
164static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
162 165
163#ifdef CONFIG_PROC_FS 166#ifdef CONFIG_PROC_FS
164static int procmpt_summary_read(char *buf, char **start, off_t offset, 167static int procmpt_summary_read(char *buf, char **start, off_t offset,
@@ -509,6 +512,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
509 pCfg->wait_done = 1; 512 pCfg->wait_done = 1;
510 wake_up(&mpt_waitq); 513 wake_up(&mpt_waitq);
511 } 514 }
515 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
516 /* we should be always getting a reply frame */
517 memcpy(ioc->persist_reply_frame, reply,
518 min(MPT_DEFAULT_FRAME_SIZE,
519 4*reply->u.reply.MsgLength));
520 del_timer(&ioc->persist_timer);
521 ioc->persist_wait_done = 1;
522 wake_up(&mpt_waitq);
512 } else { 523 } else {
513 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n", 524 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
514 ioc->name, func); 525 ioc->name, func);
@@ -750,6 +761,7 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
750 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR, 761 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
751 u.frame.linkage.list); 762 u.frame.linkage.list);
752 list_del(&mf->u.frame.linkage.list); 763 list_del(&mf->u.frame.linkage.list);
764 mf->u.frame.linkage.arg1 = 0;
753 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */ 765 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
754 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 766 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
755 /* u16! */ 767 /* u16! */
@@ -845,6 +857,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
845 857
846 /* Put Request back on FreeQ! */ 858 /* Put Request back on FreeQ! */
847 spin_lock_irqsave(&ioc->FreeQlock, flags); 859 spin_lock_irqsave(&ioc->FreeQlock, flags);
860 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
848 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 861 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
849#ifdef MFCNT 862#ifdef MFCNT
850 ioc->mfcnt--; 863 ioc->mfcnt--;
@@ -971,12 +984,123 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
971 984
972 /* Make sure there are no doorbells */ 985 /* Make sure there are no doorbells */
973 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 986 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
974 987
975 return r; 988 return r;
976} 989}
977 990
978/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 991/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
979/** 992/**
993 * mpt_host_page_access_control - provides mechanism for the host
994 * driver to control the IOC's Host Page Buffer access.
995 * @ioc: Pointer to MPT adapter structure
996 * @access_control_value: define bits below
997 *
998 * Access Control Value - bits[15:12]
999 * 0h Reserved
1000 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1001 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1002 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1003 *
1004 * Returns 0 for success, non-zero for failure.
1005 */
1006
1007static int
1008mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1009{
1010 int r = 0;
1011
1012 /* return if in use */
1013 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1014 & MPI_DOORBELL_ACTIVE)
1015 return -1;
1016
1017 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1018
1019 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1020 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1021 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1022 (access_control_value<<12)));
1023
1024 /* Wait for IOC to clear Doorbell Status bit */
1025 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1026 return -2;
1027 }else
1028 return 0;
1029}
1030
1031/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1032/**
1033 * mpt_host_page_alloc - allocate system memory for the fw
1034 * If we already allocated memory in past, then resend the same pointer.
1035 * ioc@: Pointer to pointer to IOC adapter
1036 * ioc_init@: Pointer to ioc init config page
1037 *
1038 * Returns 0 for success, non-zero for failure.
1039 */
1040static int
1041mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1042{
1043 char *psge;
1044 int flags_length;
1045 u32 host_page_buffer_sz=0;
1046
1047 if(!ioc->HostPageBuffer) {
1048
1049 host_page_buffer_sz =
1050 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1051
1052 if(!host_page_buffer_sz)
1053 return 0; /* fw doesn't need any host buffers */
1054
1055 /* spin till we get enough memory */
1056 while(host_page_buffer_sz > 0) {
1057
1058 if((ioc->HostPageBuffer = pci_alloc_consistent(
1059 ioc->pcidev,
1060 host_page_buffer_sz,
1061 &ioc->HostPageBuffer_dma)) != NULL) {
1062
1063 dinitprintk((MYIOC_s_INFO_FMT
1064 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1065 ioc->name,
1066 ioc->HostPageBuffer,
1067 ioc->HostPageBuffer_dma,
1068 hst_page_buffer_sz));
1069 ioc->alloc_total += host_page_buffer_sz;
1070 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1071 break;
1072 }
1073
1074 host_page_buffer_sz -= (4*1024);
1075 }
1076 }
1077
1078 if(!ioc->HostPageBuffer) {
1079 printk(MYIOC_s_ERR_FMT
1080 "Failed to alloc memory for host_page_buffer!\n",
1081 ioc->name);
1082 return -999;
1083 }
1084
1085 psge = (char *)&ioc_init->HostPageBufferSGE;
1086 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1087 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1088 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1089 MPI_SGE_FLAGS_HOST_TO_IOC |
1090 MPI_SGE_FLAGS_END_OF_BUFFER;
1091 if (sizeof(dma_addr_t) == sizeof(u64)) {
1092 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1093 }
1094 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1095 flags_length |= ioc->HostPageBuffer_sz;
1096 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1097 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1098
1099return 0;
1100}
1101
1102/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1103/**
980 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to 1104 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
981 * the associated MPT adapter structure. 1105 * the associated MPT adapter structure.
982 * @iocid: IOC unique identifier (integer) 1106 * @iocid: IOC unique identifier (integer)
@@ -1213,6 +1337,33 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1213 ioc->prod_name = "LSI53C1035"; 1337 ioc->prod_name = "LSI53C1035";
1214 ioc->bus_type = SCSI; 1338 ioc->bus_type = SCSI;
1215 } 1339 }
1340 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1341 ioc->prod_name = "LSISAS1064";
1342 ioc->bus_type = SAS;
1343 ioc->errata_flag_1064 = 1;
1344 }
1345 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
1346 ioc->prod_name = "LSISAS1066";
1347 ioc->bus_type = SAS;
1348 ioc->errata_flag_1064 = 1;
1349 }
1350 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1351 ioc->prod_name = "LSISAS1068";
1352 ioc->bus_type = SAS;
1353 ioc->errata_flag_1064 = 1;
1354 }
1355 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1356 ioc->prod_name = "LSISAS1064E";
1357 ioc->bus_type = SAS;
1358 }
1359 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
1360 ioc->prod_name = "LSISAS1066E";
1361 ioc->bus_type = SAS;
1362 }
1363 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1364 ioc->prod_name = "LSISAS1068E";
1365 ioc->bus_type = SAS;
1366 }
1216 1367
1217 if (ioc->errata_flag_1064) 1368 if (ioc->errata_flag_1064)
1218 pci_disable_io_access(pdev); 1369 pci_disable_io_access(pdev);
@@ -1640,7 +1791,22 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1640 * and we try GetLanConfigPages again... 1791 * and we try GetLanConfigPages again...
1641 */ 1792 */
1642 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 1793 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1643 if (ioc->bus_type == FC) { 1794 if (ioc->bus_type == SAS) {
1795
1796 /* clear persistency table */
1797 if(ioc->facts.IOCExceptions &
1798 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1799 ret = mptbase_sas_persist_operation(ioc,
1800 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1801 if(ret != 0)
1802 return -1;
1803 }
1804
1805 /* Find IM volumes
1806 */
1807 mpt_findImVolumes(ioc);
1808
1809 } else if (ioc->bus_type == FC) {
1644 /* 1810 /*
1645 * Pre-fetch FC port WWN and stuff... 1811 * Pre-fetch FC port WWN and stuff...
1646 * (FCPortPage0_t stuff) 1812 * (FCPortPage0_t stuff)
@@ -1783,7 +1949,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
1783 1949
1784 if (ioc->cached_fw != NULL) { 1950 if (ioc->cached_fw != NULL) {
1785 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n")); 1951 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1786 if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) { 1952 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1787 printk(KERN_WARNING MYNAM 1953 printk(KERN_WARNING MYNAM
1788 ": firmware downloadboot failure (%d)!\n", ret); 1954 ": firmware downloadboot failure (%d)!\n", ret);
1789 } 1955 }
@@ -1852,6 +2018,23 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
1852 2018
1853 kfree(ioc->ChainToChain); 2019 kfree(ioc->ChainToChain);
1854 ioc->ChainToChain = NULL; 2020 ioc->ChainToChain = NULL;
2021
2022 if (ioc->HostPageBuffer != NULL) {
2023 if((ret = mpt_host_page_access_control(ioc,
2024 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2025 printk(KERN_ERR MYNAM
2026 ": %s: host page buffers free failed (%d)!\n",
2027 __FUNCTION__, ret);
2028 }
2029 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2030 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2031 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2032 ioc->HostPageBuffer,
2033 ioc->HostPageBuffer_dma);
2034 ioc->HostPageBuffer = NULL;
2035 ioc->HostPageBuffer_sz = 0;
2036 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2037 }
1855} 2038}
1856 2039
1857/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2040/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2034,7 +2217,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2034 * Loop here waiting for IOC to come READY. 2217 * Loop here waiting for IOC to come READY.
2035 */ 2218 */
2036 ii = 0; 2219 ii = 0;
2037 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */ 2220 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2038 2221
2039 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { 2222 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2040 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) { 2223 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
@@ -2212,6 +2395,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2212 le32_to_cpu(facts->CurrentSenseBufferHighAddr); 2395 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2213 facts->CurReplyFrameSize = 2396 facts->CurReplyFrameSize =
2214 le16_to_cpu(facts->CurReplyFrameSize); 2397 le16_to_cpu(facts->CurReplyFrameSize);
2398 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2215 2399
2216 /* 2400 /*
2217 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx 2401 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
@@ -2383,13 +2567,25 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2383 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n", 2567 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2384 ioc->name, ioc->upload_fw, ioc->facts.Flags)); 2568 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2385 2569
2386 if (ioc->bus_type == FC) 2570 if(ioc->bus_type == SAS)
2571 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2572 else if(ioc->bus_type == FC)
2387 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES; 2573 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2388 else 2574 else
2389 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES; 2575 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2390
2391 ioc_init.MaxBuses = MPT_MAX_BUS; 2576 ioc_init.MaxBuses = MPT_MAX_BUS;
2392 2577 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2578 ioc->name, ioc->facts.MsgVersion));
2579 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2580 // set MsgVersion and HeaderVersion host driver was built with
2581 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2582 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2583
2584 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2585 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2586 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2587 return -99;
2588 }
2393 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ 2589 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2394 2590
2395 if (sizeof(dma_addr_t) == sizeof(u64)) { 2591 if (sizeof(dma_addr_t) == sizeof(u64)) {
@@ -2403,17 +2599,21 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2403 ioc_init.HostMfaHighAddr = cpu_to_le32(0); 2599 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2404 ioc_init.SenseBufferHighAddr = cpu_to_le32(0); 2600 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2405 } 2601 }
2406 2602
2407 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr; 2603 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2408 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr; 2604 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2605 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2606 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2409 2607
2410 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n", 2608 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2411 ioc->name, &ioc_init)); 2609 ioc->name, &ioc_init));
2412 2610
2413 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init, 2611 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2414 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag); 2612 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2415 if (r != 0) 2613 if (r != 0) {
2614 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2416 return r; 2615 return r;
2616 }
2417 2617
2418 /* No need to byte swap the multibyte fields in the reply 2618 /* No need to byte swap the multibyte fields in the reply
2419 * since we don't even look at it's contents. 2619 * since we don't even look at it's contents.
@@ -2472,7 +2672,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2472{ 2672{
2473 PortEnable_t port_enable; 2673 PortEnable_t port_enable;
2474 MPIDefaultReply_t reply_buf; 2674 MPIDefaultReply_t reply_buf;
2475 int ii; 2675 int rc;
2476 int req_sz; 2676 int req_sz;
2477 int reply_sz; 2677 int reply_sz;
2478 2678
@@ -2494,22 +2694,15 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2494 2694
2495 /* RAID FW may take a long time to enable 2695 /* RAID FW may take a long time to enable
2496 */ 2696 */
2497 if (ioc->bus_type == FC) { 2697 if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2498 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, 2698 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
2499 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag); 2699 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2500 } else {
2501 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2502 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag); 2700 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2701 } else {
2702 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2703 reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
2503 } 2704 }
2504 2705 return rc;
2505 if (ii != 0)
2506 return ii;
2507
2508 /* We do not even look at the reply, so we need not
2509 * swap the multi-byte fields.
2510 */
2511
2512 return 0;
2513} 2706}
2514 2707
2515/* 2708/*
@@ -2666,9 +2859,8 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2666 * <0 for fw upload failure. 2859 * <0 for fw upload failure.
2667 */ 2860 */
2668static int 2861static int
2669mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) 2862mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2670{ 2863{
2671 MpiFwHeader_t *pFwHeader;
2672 MpiExtImageHeader_t *pExtImage; 2864 MpiExtImageHeader_t *pExtImage;
2673 u32 fwSize; 2865 u32 fwSize;
2674 u32 diag0val; 2866 u32 diag0val;
@@ -2679,18 +2871,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2679 u32 load_addr; 2871 u32 load_addr;
2680 u32 ioc_state=0; 2872 u32 ioc_state=0;
2681 2873
2682 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n", 2874 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2683 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw)); 2875 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2684
2685 if ( ioc->facts.FWImageSize == 0 )
2686 return -1;
2687
2688 if (ioc->cached_fw == NULL)
2689 return -2;
2690
2691 /* prevent a second downloadboot and memory free with alt_ioc */
2692 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2693 ioc->alt_ioc->cached_fw = NULL;
2694 2876
2695 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 2877 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2696 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 2878 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
@@ -2718,16 +2900,17 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2718 ioc->name, count)); 2900 ioc->name, count));
2719 break; 2901 break;
2720 } 2902 }
2721 /* wait 1 sec */ 2903 /* wait .1 sec */
2722 if (sleepFlag == CAN_SLEEP) { 2904 if (sleepFlag == CAN_SLEEP) {
2723 msleep_interruptible (1000); 2905 msleep_interruptible (100);
2724 } else { 2906 } else {
2725 mdelay (1000); 2907 mdelay (100);
2726 } 2908 }
2727 } 2909 }
2728 2910
2729 if ( count == 30 ) { 2911 if ( count == 30 ) {
2730 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n", 2912 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2913 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2731 ioc->name, diag0val)); 2914 ioc->name, diag0val));
2732 return -3; 2915 return -3;
2733 } 2916 }
@@ -2742,7 +2925,6 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2742 /* Set the DiagRwEn and Disable ARM bits */ 2925 /* Set the DiagRwEn and Disable ARM bits */
2743 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM)); 2926 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2744 2927
2745 pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2746 fwSize = (pFwHeader->ImageSize + 3)/4; 2928 fwSize = (pFwHeader->ImageSize + 3)/4;
2747 ptrFw = (u32 *) pFwHeader; 2929 ptrFw = (u32 *) pFwHeader;
2748 2930
@@ -2792,19 +2974,38 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2792 /* Clear the internal flash bad bit - autoincrementing register, 2974 /* Clear the internal flash bad bit - autoincrementing register,
2793 * so must do two writes. 2975 * so must do two writes.
2794 */ 2976 */
2795 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); 2977 if (ioc->bus_type == SCSI) {
2796 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData); 2978 /*
2797 diagRwData |= 0x4000000; 2979 * 1030 and 1035 H/W errata, workaround to access
2798 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); 2980 * the ClearFlashBadSignatureBit
2799 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData); 2981 */
2982 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2983 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2984 diagRwData |= 0x40000000;
2985 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2986 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2987
2988 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
2989 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2990 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
2991 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
2992
2993 /* wait 1 msec */
2994 if (sleepFlag == CAN_SLEEP) {
2995 msleep_interruptible (1);
2996 } else {
2997 mdelay (1);
2998 }
2999 }
2800 3000
2801 if (ioc->errata_flag_1064) 3001 if (ioc->errata_flag_1064)
2802 pci_disable_io_access(ioc->pcidev); 3002 pci_disable_io_access(ioc->pcidev);
2803 3003
2804 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3004 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2805 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n", 3005 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3006 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
2806 ioc->name, diag0val)); 3007 ioc->name, diag0val));
2807 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM); 3008 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
2808 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n", 3009 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2809 ioc->name, diag0val)); 3010 ioc->name, diag0val));
2810 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); 3011 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
@@ -2812,10 +3013,23 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2812 /* Write 0xFF to reset the sequencer */ 3013 /* Write 0xFF to reset the sequencer */
2813 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3014 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2814 3015
3016 if (ioc->bus_type == SAS) {
3017 ioc_state = mpt_GetIocState(ioc, 0);
3018 if ( (GetIocFacts(ioc, sleepFlag,
3019 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3020 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3021 ioc->name, ioc_state));
3022 return -EFAULT;
3023 }
3024 }
3025
2815 for (count=0; count<HZ*20; count++) { 3026 for (count=0; count<HZ*20; count++) {
2816 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) { 3027 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2817 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n", 3028 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2818 ioc->name, count, ioc_state)); 3029 ioc->name, count, ioc_state));
3030 if (ioc->bus_type == SAS) {
3031 return 0;
3032 }
2819 if ((SendIocInit(ioc, sleepFlag)) != 0) { 3033 if ((SendIocInit(ioc, sleepFlag)) != 0) {
2820 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n", 3034 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2821 ioc->name)); 3035 ioc->name));
@@ -3049,12 +3263,13 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3049 3263
3050 /* wait 1 sec */ 3264 /* wait 1 sec */
3051 if (sleepFlag == CAN_SLEEP) { 3265 if (sleepFlag == CAN_SLEEP) {
3052 ssleep(1); 3266 msleep_interruptible (1000);
3053 } else { 3267 } else {
3054 mdelay (1000); 3268 mdelay (1000);
3055 } 3269 }
3056 } 3270 }
3057 if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) { 3271 if ((count = mpt_downloadboot(ioc,
3272 (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
3058 printk(KERN_WARNING MYNAM 3273 printk(KERN_WARNING MYNAM
3059 ": firmware downloadboot failure (%d)!\n", count); 3274 ": firmware downloadboot failure (%d)!\n", count);
3060 } 3275 }
@@ -4001,6 +4216,85 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4001 4216
4002/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4217/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4003/* 4218/*
4219 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4220 * @ioc: Pointer to MPT_ADAPTER structure
4221 * @sas_address: 64bit SAS Address for operation.
4222 * @target_id: specified target for operation
4223 * @bus: specified bus for operation
4224 * @persist_opcode: see below
4225 *
4226 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4227 * devices not currently present.
4228 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4229 *
4230 * NOTE: Don't use not this function during interrupt time.
4231 *
4232 * Returns: 0 for success, non-zero error
4233 */
4234
4235/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4236int
4237mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4238{
4239 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4240 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4241 MPT_FRAME_HDR *mf = NULL;
4242 MPIHeader_t *mpi_hdr;
4243
4244
4245 /* insure garbage is not sent to fw */
4246 switch(persist_opcode) {
4247
4248 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4249 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4250 break;
4251
4252 default:
4253 return -1;
4254 break;
4255 }
4256
4257 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4258
4259 /* Get a MF for this command.
4260 */
4261 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4262 printk("%s: no msg frames!\n",__FUNCTION__);
4263 return -1;
4264 }
4265
4266 mpi_hdr = (MPIHeader_t *) mf;
4267 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4268 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4269 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4270 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4271 sasIoUnitCntrReq->Operation = persist_opcode;
4272
4273 init_timer(&ioc->persist_timer);
4274 ioc->persist_timer.data = (unsigned long) ioc;
4275 ioc->persist_timer.function = mpt_timer_expired;
4276 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4277 ioc->persist_wait_done=0;
4278 add_timer(&ioc->persist_timer);
4279 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4280 wait_event(mpt_waitq, ioc->persist_wait_done);
4281
4282 sasIoUnitCntrReply =
4283 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4284 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4285 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4286 __FUNCTION__,
4287 sasIoUnitCntrReply->IOCStatus,
4288 sasIoUnitCntrReply->IOCLogInfo);
4289 return -1;
4290 }
4291
4292 printk("%s: success\n",__FUNCTION__);
4293 return 0;
4294}
4295
4296/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4297/*
4004 * GetIoUnitPage2 - Retrieve BIOS version and boot order information. 4298 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4005 * @ioc: Pointer to MPT_ADAPTER structure 4299 * @ioc: Pointer to MPT_ADAPTER structure
4006 * 4300 *
@@ -5366,8 +5660,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5366} 5660}
5367 5661
5368/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5662/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5369static char * 5663static void
5370EventDescriptionStr(u8 event, u32 evData0) 5664EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5371{ 5665{
5372 char *ds; 5666 char *ds;
5373 5667
@@ -5420,8 +5714,95 @@ EventDescriptionStr(u8 event, u32 evData0)
5420 ds = "Events(OFF) Change"; 5714 ds = "Events(OFF) Change";
5421 break; 5715 break;
5422 case MPI_EVENT_INTEGRATED_RAID: 5716 case MPI_EVENT_INTEGRATED_RAID:
5423 ds = "Integrated Raid"; 5717 {
5718 u8 ReasonCode = (u8)(evData0 >> 16);
5719 switch (ReasonCode) {
5720 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5721 ds = "Integrated Raid: Volume Created";
5722 break;
5723 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5724 ds = "Integrated Raid: Volume Deleted";
5725 break;
5726 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5727 ds = "Integrated Raid: Volume Settings Changed";
5728 break;
5729 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5730 ds = "Integrated Raid: Volume Status Changed";
5731 break;
5732 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5733 ds = "Integrated Raid: Volume Physdisk Changed";
5734 break;
5735 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5736 ds = "Integrated Raid: Physdisk Created";
5737 break;
5738 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5739 ds = "Integrated Raid: Physdisk Deleted";
5740 break;
5741 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5742 ds = "Integrated Raid: Physdisk Settings Changed";
5743 break;
5744 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5745 ds = "Integrated Raid: Physdisk Status Changed";
5746 break;
5747 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5748 ds = "Integrated Raid: Domain Validation Needed";
5749 break;
5750 case MPI_EVENT_RAID_RC_SMART_DATA :
5751 ds = "Integrated Raid; Smart Data";
5752 break;
5753 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5754 ds = "Integrated Raid: Replace Action Started";
5755 break;
5756 default:
5757 ds = "Integrated Raid";
5424 break; 5758 break;
5759 }
5760 break;
5761 }
5762 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5763 ds = "SCSI Device Status Change";
5764 break;
5765 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5766 {
5767 u8 ReasonCode = (u8)(evData0 >> 16);
5768 switch (ReasonCode) {
5769 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5770 ds = "SAS Device Status Change: Added";
5771 break;
5772 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5773 ds = "SAS Device Status Change: Deleted";
5774 break;
5775 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5776 ds = "SAS Device Status Change: SMART Data";
5777 break;
5778 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5779 ds = "SAS Device Status Change: No Persistancy Added";
5780 break;
5781 default:
5782 ds = "SAS Device Status Change: Unknown";
5783 break;
5784 }
5785 break;
5786 }
5787 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5788 ds = "Bus Timer Expired";
5789 break;
5790 case MPI_EVENT_QUEUE_FULL:
5791 ds = "Queue Full";
5792 break;
5793 case MPI_EVENT_SAS_SES:
5794 ds = "SAS SES Event";
5795 break;
5796 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5797 ds = "Persistent Table Full";
5798 break;
5799 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5800 ds = "SAS PHY Link Status";
5801 break;
5802 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5803 ds = "SAS Discovery Error";
5804 break;
5805
5425 /* 5806 /*
5426 * MPT base "custom" events may be added here... 5807 * MPT base "custom" events may be added here...
5427 */ 5808 */
@@ -5429,7 +5810,7 @@ EventDescriptionStr(u8 event, u32 evData0)
5429 ds = "Unknown"; 5810 ds = "Unknown";
5430 break; 5811 break;
5431 } 5812 }
5432 return ds; 5813 strcpy(evStr,ds);
5433} 5814}
5434 5815
5435/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5816/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5451,7 +5832,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5451 int ii; 5832 int ii;
5452 int r = 0; 5833 int r = 0;
5453 int handlers = 0; 5834 int handlers = 0;
5454 char *evStr; 5835 char evStr[100];
5455 u8 event; 5836 u8 event;
5456 5837
5457 /* 5838 /*
@@ -5464,7 +5845,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5464 evData0 = le32_to_cpu(pEventReply->Data[0]); 5845 evData0 = le32_to_cpu(pEventReply->Data[0]);
5465 } 5846 }
5466 5847
5467 evStr = EventDescriptionStr(event, evData0); 5848 EventDescriptionStr(event, evData0, evStr);
5468 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n", 5849 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5469 ioc->name, 5850 ioc->name,
5470 evStr, 5851 evStr,
@@ -5481,20 +5862,6 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5481 * Do general / base driver event processing 5862 * Do general / base driver event processing
5482 */ 5863 */
5483 switch(event) { 5864 switch(event) {
5484 case MPI_EVENT_NONE: /* 00 */
5485 case MPI_EVENT_LOG_DATA: /* 01 */
5486 case MPI_EVENT_STATE_CHANGE: /* 02 */
5487 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
5488 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
5489 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
5490 case MPI_EVENT_RESCAN: /* 06 */
5491 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
5492 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
5493 case MPI_EVENT_LOGOUT: /* 09 */
5494 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
5495 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
5496 default:
5497 break;
5498 case MPI_EVENT_EVENT_CHANGE: /* 0A */ 5865 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5499 if (evDataLen) { 5866 if (evDataLen) {
5500 u8 evState = evData0 & 0xFF; 5867 u8 evState = evData0 & 0xFF;
@@ -5507,6 +5874,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5507 } 5874 }
5508 } 5875 }
5509 break; 5876 break;
5877 default:
5878 break;
5510 } 5879 }
5511 5880
5512 /* 5881 /*
@@ -5814,6 +6183,7 @@ EXPORT_SYMBOL(mpt_findImVolumes);
5814EXPORT_SYMBOL(mpt_read_ioc_pg_3); 6183EXPORT_SYMBOL(mpt_read_ioc_pg_3);
5815EXPORT_SYMBOL(mpt_alloc_fw_memory); 6184EXPORT_SYMBOL(mpt_alloc_fw_memory);
5816EXPORT_SYMBOL(mpt_free_fw_memory); 6185EXPORT_SYMBOL(mpt_free_fw_memory);
6186EXPORT_SYMBOL(mptbase_sas_persist_operation);
5817 6187
5818 6188
5819/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6189/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index f4827d923731..bbd21d74ce5c 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -65,6 +65,7 @@
65#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */ 65#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
66#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */ 66#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
67#include "lsi/mpi_tool.h" /* Tools support */ 67#include "lsi/mpi_tool.h" /* Tools support */
68#include "lsi/mpi_sas.h" /* SAS support */
68 69
69/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 70/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 71
@@ -477,6 +478,14 @@ typedef struct _ScsiCfgData {
477 u8 rsvd[1]; 478 u8 rsvd[1];
478} ScsiCfgData; 479} ScsiCfgData;
479 480
481typedef struct _SasCfgData {
482 u8 ptClear; /* 1 to automatically clear the
483 * persistent table.
484 * 0 to disable
485 * automatic clearing.
486 */
487}SasCfgData;
488
480/* 489/*
481 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS 490 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
482 */ 491 */
@@ -530,11 +539,15 @@ typedef struct _MPT_ADAPTER
530 u8 *sense_buf_pool; 539 u8 *sense_buf_pool;
531 dma_addr_t sense_buf_pool_dma; 540 dma_addr_t sense_buf_pool_dma;
532 u32 sense_buf_low_dma; 541 u32 sense_buf_low_dma;
542 u8 *HostPageBuffer; /* SAS - host page buffer support */
543 u32 HostPageBuffer_sz;
544 dma_addr_t HostPageBuffer_dma;
533 int mtrr_reg; 545 int mtrr_reg;
534 struct pci_dev *pcidev; /* struct pci_dev pointer */ 546 struct pci_dev *pcidev; /* struct pci_dev pointer */
535 u8 __iomem *memmap; /* mmap address */ 547 u8 __iomem *memmap; /* mmap address */
536 struct Scsi_Host *sh; /* Scsi Host pointer */ 548 struct Scsi_Host *sh; /* Scsi Host pointer */
537 ScsiCfgData spi_data; /* Scsi config. data */ 549 ScsiCfgData spi_data; /* Scsi config. data */
550 SasCfgData sas_data; /* Sas config. data */
538 MPT_IOCTL *ioctl; /* ioctl data pointer */ 551 MPT_IOCTL *ioctl; /* ioctl data pointer */
539 struct proc_dir_entry *ioc_dentry; 552 struct proc_dir_entry *ioc_dentry;
540 struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */ 553 struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
@@ -554,31 +567,35 @@ typedef struct _MPT_ADAPTER
554#else 567#else
555 u32 mfcnt; 568 u32 mfcnt;
556#endif 569#endif
557 u32 NB_for_64_byte_frame; 570 u32 NB_for_64_byte_frame;
558 u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)]; 571 u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
559 u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)]; 572 u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
560 IOCFactsReply_t facts; 573 IOCFactsReply_t facts;
561 PortFactsReply_t pfacts[2]; 574 PortFactsReply_t pfacts[2];
562 FCPortPage0_t fc_port_page0[2]; 575 FCPortPage0_t fc_port_page0[2];
576 struct timer_list persist_timer; /* persist table timer */
577 int persist_wait_done; /* persist completion flag */
578 u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */
563 LANPage0_t lan_cnfg_page0; 579 LANPage0_t lan_cnfg_page0;
564 LANPage1_t lan_cnfg_page1; 580 LANPage1_t lan_cnfg_page1;
565 /* 581 /*
566 * Description: errata_flag_1064 582 * Description: errata_flag_1064
567 * If a PCIX read occurs within 1 or 2 cycles after the chip receives 583 * If a PCIX read occurs within 1 or 2 cycles after the chip receives
568 * a split completion for a read data, an internal address pointer incorrectly 584 * a split completion for a read data, an internal address pointer incorrectly
569 * increments by 32 bytes 585 * increments by 32 bytes
570 */ 586 */
571 int errata_flag_1064; 587 int errata_flag_1064;
572 u8 FirstWhoInit; 588 u8 FirstWhoInit;
573 u8 upload_fw; /* If set, do a fw upload */ 589 u8 upload_fw; /* If set, do a fw upload */
574 u8 reload_fw; /* Force a FW Reload on next reset */ 590 u8 reload_fw; /* Force a FW Reload on next reset */
575 u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */ 591 u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
576 u8 pad1[4]; 592 u8 pad1[4];
577 int DoneCtx; 593 int DoneCtx;
578 int TaskCtx; 594 int TaskCtx;
579 int InternalCtx; 595 int InternalCtx;
580 struct list_head list; 596 struct list_head list;
581 struct net_device *netdev; 597 struct net_device *netdev;
598 struct list_head sas_topology;
582} MPT_ADAPTER; 599} MPT_ADAPTER;
583 600
584/* 601/*
@@ -964,6 +981,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
964extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 981extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
965extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 982extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
966extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 983extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
984extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
967 985
968/* 986/*
969 * Public data decl's... 987 * Public data decl's...
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 4a003dc5fde8..58b5fdee009a 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1256,8 +1256,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1256 MPT_SCSI_HOST *hd; 1256 MPT_SCSI_HOST *hd;
1257 MPT_FRAME_HDR *mf; 1257 MPT_FRAME_HDR *mf;
1258 SCSIIORequest_t *pScsiReq; 1258 SCSIIORequest_t *pScsiReq;
1259 VirtDevice *pTarget; 1259 VirtDevice *pTarget = SCpnt->device->hostdata;
1260 int target;
1261 int lun; 1260 int lun;
1262 u32 datalen; 1261 u32 datalen;
1263 u32 scsictl; 1262 u32 scsictl;
@@ -1267,12 +1266,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1267 int ii; 1266 int ii;
1268 1267
1269 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; 1268 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1270 target = SCpnt->device->id;
1271 lun = SCpnt->device->lun; 1269 lun = SCpnt->device->lun;
1272 SCpnt->scsi_done = done; 1270 SCpnt->scsi_done = done;
1273 1271
1274 pTarget = hd->Targets[target];
1275
1276 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n", 1272 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1277 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done)); 1273 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1278 1274
@@ -1315,7 +1311,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1315 /* Default to untagged. Once a target structure has been allocated, 1311 /* Default to untagged. Once a target structure has been allocated,
1316 * use the Inquiry data to determine if device supports tagged. 1312 * use the Inquiry data to determine if device supports tagged.
1317 */ 1313 */
1318 if ( pTarget 1314 if (pTarget
1319 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) 1315 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1320 && (SCpnt->device->tagged_supported)) { 1316 && (SCpnt->device->tagged_supported)) {
1321 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; 1317 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
@@ -1325,8 +1321,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1325 1321
1326 /* Use the above information to set up the message frame 1322 /* Use the above information to set up the message frame
1327 */ 1323 */
1328 pScsiReq->TargetID = (u8) target; 1324 pScsiReq->TargetID = (u8) pTarget->target_id;
1329 pScsiReq->Bus = (u8) SCpnt->device->channel; 1325 pScsiReq->Bus = pTarget->bus_id;
1330 pScsiReq->ChainOffset = 0; 1326 pScsiReq->ChainOffset = 0;
1331 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; 1327 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1332 pScsiReq->CDBLength = SCpnt->cmd_len; 1328 pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -1378,7 +1374,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1378 1374
1379#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 1375#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1380 if (hd->ioc->bus_type == SCSI) { 1376 if (hd->ioc->bus_type == SCSI) {
1381 int dvStatus = hd->ioc->spi_data.dvStatus[target]; 1377 int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
1382 int issueCmd = 1; 1378 int issueCmd = 1;
1383 1379
1384 if (dvStatus || hd->ioc->spi_data.forceDv) { 1380 if (dvStatus || hd->ioc->spi_data.forceDv) {
@@ -2180,6 +2176,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
2180 2176
2181 out: 2177 out:
2182 vdev->num_luns++; 2178 vdev->num_luns++;
2179 device->hostdata = vdev;
2183 return 0; 2180 return 0;
2184} 2181}
2185 2182