diff options
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 516 |
1 files changed, 443 insertions, 73 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); | |||
141 | static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); | 141 | static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); |
142 | static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag); | 142 | static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag); |
143 | static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag); | 143 | static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag); |
144 | static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag); | 144 | static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag); |
145 | static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag); | 145 | static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag); |
146 | static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag); | 146 | static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag); |
147 | static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag); | 147 | static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag); |
@@ -152,6 +152,7 @@ static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag); | |||
152 | static int GetLanConfigPages(MPT_ADAPTER *ioc); | 152 | static int GetLanConfigPages(MPT_ADAPTER *ioc); |
153 | static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum); | 153 | static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum); |
154 | static int GetIoUnitPage2(MPT_ADAPTER *ioc); | 154 | static int GetIoUnitPage2(MPT_ADAPTER *ioc); |
155 | int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); | ||
155 | static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); | 156 | static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); |
156 | static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); | 157 | static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); |
157 | static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); | 158 | static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); |
@@ -159,6 +160,8 @@ static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); | |||
159 | static void mpt_timer_expired(unsigned long data); | 160 | static void mpt_timer_expired(unsigned long data); |
160 | static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); | 161 | static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); |
161 | static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); | 162 | static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); |
163 | static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag); | ||
164 | static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init); | ||
162 | 165 | ||
163 | #ifdef CONFIG_PROC_FS | 166 | #ifdef CONFIG_PROC_FS |
164 | static int procmpt_summary_read(char *buf, char **start, off_t offset, | 167 | static 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 | |||
1007 | static int | ||
1008 | mpt_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 | */ | ||
1040 | static int | ||
1041 | mpt_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 | |||
1099 | return 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 | */ |
2668 | static int | 2861 | static int |
2669 | mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) | 2862 | mpt_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 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
4236 | int | ||
4237 | mptbase_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 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
5369 | static char * | 5663 | static void |
5370 | EventDescriptionStr(u8 event, u32 evData0) | 5664 | EventDescriptionStr(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); | |||
5814 | EXPORT_SYMBOL(mpt_read_ioc_pg_3); | 6183 | EXPORT_SYMBOL(mpt_read_ioc_pg_3); |
5815 | EXPORT_SYMBOL(mpt_alloc_fw_memory); | 6184 | EXPORT_SYMBOL(mpt_alloc_fw_memory); |
5816 | EXPORT_SYMBOL(mpt_free_fw_memory); | 6185 | EXPORT_SYMBOL(mpt_free_fw_memory); |
6186 | EXPORT_SYMBOL(mptbase_sas_persist_operation); | ||
5817 | 6187 | ||
5818 | 6188 | ||
5819 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6189 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |