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 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
