aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-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 f517d0692d5..14d62d96ca4 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 f4827d92373..bbd21d74ce5 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 4a003dc5fde..58b5fdee009 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