Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] fusion - error handling bug fix's

misc error handling bug fix's
- properly interpret iocstatus returned after task management request
- clear tmState after a failed doorbell
- cleanup mptscsih_taskmgmt_complete

Signed-off-by: Eric Moore <Eric.Moore@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by

Eric Moore and committed by
James Bottomley
cd2c6191 2ecce492

+161 -166
+7 -7
drivers/message/fusion/mptbase.c
··· 916 916 int 917 917 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) 918 918 { 919 - int r = 0; 919 + int r = 0; 920 920 u8 *req_as_bytes; 921 921 int ii; 922 922 ··· 3219 3219 u32 diag1val = 0; 3220 3220 #endif 3221 3221 3222 + /* Clear any existing interrupts */ 3223 + CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 3224 + 3222 3225 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { 3223 3226 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " 3224 3227 "address=%p\n", ioc->name, __FUNCTION__, ··· 3241 3238 " count=%d\n", 3242 3239 ioc->name, doorbell, count)); 3243 3240 if (doorbell == MPI_IOC_STATE_READY) { 3244 - return 0; 3241 + return 1; 3245 3242 } 3246 3243 3247 3244 /* wait 1 sec */ ··· 3252 3249 } 3253 3250 return -1; 3254 3251 } 3255 - 3256 - /* Clear any existing interrupts */ 3257 - CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 3258 3252 3259 3253 /* Use "Diagnostic reset" method! (only thing available!) */ 3260 3254 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); ··· 3968 3968 } 3969 3969 } else { 3970 3970 while (--cntdn) { 3971 - mdelay (1); 3971 + udelay (1000); 3972 3972 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 3973 3973 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 3974 3974 break; ··· 4020 4020 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4021 4021 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 4022 4022 break; 4023 - mdelay(1); 4023 + udelay (1000); 4024 4024 count++; 4025 4025 } 4026 4026 }
+1 -1
drivers/message/fusion/mptctl.c
··· 313 313 */ 314 314 dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 315 315 ioctl->ioc->name)); 316 - mpt_HardResetHandler(ioctl->ioc, NO_SLEEP); 316 + mpt_HardResetHandler(ioctl->ioc, CAN_SLEEP); 317 317 } 318 318 return; 319 319
+153 -158
drivers/message/fusion/mptscsih.c
··· 1536 1536 */ 1537 1537 1538 1538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1539 - /* 1539 + /** 1540 1540 * mptscsih_TMHandler - Generic handler for SCSI Task Management. 1541 1541 * Fall through to mpt_HardResetHandler if: not operational, too many 1542 1542 * failed TM requests or handshake failure. ··· 1552 1552 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC 1553 1553 * will be active. 1554 1554 * 1555 - * Returns 0 for SUCCESS or -1 if FAILED. 1556 - */ 1555 + * Returns 0 for SUCCESS, or FAILED. 1556 + **/ 1557 1557 int 1558 1558 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) 1559 1559 { 1560 1560 MPT_ADAPTER *ioc; 1561 1561 int rc = -1; 1562 - int doTask = 1; 1563 1562 u32 ioc_raw_state; 1564 1563 unsigned long flags; 1565 1564 1566 - /* If FW is being reloaded currently, return success to 1567 - * the calling function. 1568 - */ 1569 - if (hd == NULL) 1570 - return 0; 1571 - 1572 1565 ioc = hd->ioc; 1573 - if (ioc == NULL) { 1574 - printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n"); 1575 - return FAILED; 1576 - } 1577 1566 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); 1578 1567 1579 1568 // SJR - CHECKME - Can we avoid this here? ··· 1575 1586 spin_unlock_irqrestore(&ioc->diagLock, flags); 1576 1587 1577 1588 /* Wait a fixed amount of time for the TM pending flag to be cleared. 1578 - * If we time out and not bus reset, then we return a FAILED status to the caller. 1579 - * The call to mptscsih_tm_pending_wait() will set the pending flag if we are 1589 + * If we time out and not bus reset, then we return a FAILED status 1590 + * to the caller. 1591 + * The call to mptscsih_tm_pending_wait() will set the pending flag 1592 + * if we are 1580 1593 * successful. Otherwise, reload the FW. 1581 1594 */ 1582 1595 if (mptscsih_tm_pending_wait(hd) == FAILED) { ··· 1588 1597 hd->ioc->name, hd->tmPending)); 1589 1598 return FAILED; 1590 1599 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { 1591 - dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: " 1592 - "Timed out waiting for last TM (%d) to complete! \n", 1593 - hd->ioc->name, hd->tmPending)); 1600 + dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target " 1601 + "reset: Timed out waiting for last TM (%d) " 1602 + "to complete! \n", hd->ioc->name, 1603 + hd->tmPending)); 1594 1604 return FAILED; 1595 1605 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { 1596 1606 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " 1597 1607 "Timed out waiting for last TM (%d) to complete! \n", 1598 1608 hd->ioc->name, hd->tmPending)); 1599 - if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) 1600 - return FAILED; 1601 - 1602 - doTask = 0; 1609 + return FAILED; 1603 1610 } 1604 1611 } else { 1605 1612 spin_lock_irqsave(&hd->ioc->FreeQlock, flags); ··· 1605 1616 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1606 1617 } 1607 1618 1608 - /* Is operational? 1609 - */ 1610 1619 ioc_raw_state = mpt_GetIocState(hd->ioc, 0); 1611 1620 1612 - #ifdef MPT_DEBUG_RESET 1613 1621 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { 1614 1622 printk(MYIOC_s_WARN_FMT 1615 - "TM Handler: IOC Not operational(0x%x)!\n", 1616 - hd->ioc->name, ioc_raw_state); 1617 - } 1618 - #endif 1619 - 1620 - if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) 1621 - && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) { 1622 - 1623 - /* Isse the Task Mgmt request. 1624 - */ 1625 - if (hd->hard_resets < -1) 1626 - hd->hard_resets++; 1627 - rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, ctx2abort, timeout); 1628 - if (rc) { 1629 - printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); 1630 - } else { 1631 - dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name)); 1632 - } 1623 + "TM Handler for type=%x: IOC Not operational (0x%x)!\n", 1624 + ioc->name, type, ioc_raw_state); 1625 + printk(KERN_WARNING " Issuing HardReset!!\n"); 1626 + if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) 1627 + printk((KERN_WARNING "TMHandler: HardReset " 1628 + "FAILED!!\n")); 1629 + return FAILED; 1633 1630 } 1634 1631 1635 - /* Only fall through to the HRH if this is a bus reset 1632 + if (ioc_raw_state & MPI_DOORBELL_ACTIVE) { 1633 + printk(MYIOC_s_WARN_FMT 1634 + "TM Handler for type=%x: ioc_state: " 1635 + "DOORBELL_ACTIVE (0x%x)!\n", 1636 + ioc->name, type, ioc_raw_state); 1637 + return FAILED; 1638 + } 1639 + 1640 + /* Isse the Task Mgmt request. 1636 1641 */ 1637 - if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc || 1638 - ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { 1639 - dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 1640 - hd->ioc->name)); 1641 - rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); 1642 - } 1642 + if (hd->hard_resets < -1) 1643 + hd->hard_resets++; 1643 1644 1644 - /* 1645 - * Check IOCStatus from TM reply message 1646 - */ 1647 - if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS) 1648 - rc = FAILED; 1645 + rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, 1646 + ctx2abort, timeout); 1647 + if (rc) 1648 + printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", 1649 + hd->ioc->name); 1650 + else 1651 + dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", 1652 + hd->ioc->name)); 1649 1653 1650 1654 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); 1651 1655 ··· 1647 1665 1648 1666 1649 1667 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1650 - /* 1668 + /** 1651 1669 * mptscsih_IssueTaskMgmt - Generic send Task Management function. 1652 1670 * @hd: Pointer to MPT_SCSI_HOST structure 1653 1671 * @type: Task Management type ··· 1660 1678 * 1661 1679 * Not all fields are meaningfull for all task types. 1662 1680 * 1663 - * Returns 0 for SUCCESS, -999 for "no msg frames", 1664 - * else other non-zero value returned. 1665 - */ 1681 + * Returns 0 for SUCCESS, or FAILED. 1682 + * 1683 + **/ 1666 1684 static int 1667 1685 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) 1668 1686 { ··· 1702 1720 1703 1721 pScsiTm->TaskMsgContext = ctx2abort; 1704 1722 1705 - dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", 1706 - hd->ioc->name, ctx2abort, type)); 1723 + dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) " 1724 + "type=%d\n", hd->ioc->name, ctx2abort, type)); 1707 1725 1708 1726 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); 1709 1727 1710 1728 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, 1711 - sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, 1712 - CAN_SLEEP)) != 0) { 1713 - dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!" 1714 - " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, 1715 - hd->ioc, mf)); 1716 - mpt_free_msg_frame(hd->ioc, mf); 1717 - return retval; 1729 + sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) { 1730 + dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!" 1731 + " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd, 1732 + hd->ioc, mf, retval)); 1733 + goto fail_out; 1718 1734 } 1719 1735 1720 1736 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { 1721 - dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!" 1737 + dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!" 1722 1738 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, 1723 1739 hd->ioc, mf)); 1724 - mpt_free_msg_frame(hd->ioc, mf); 1725 1740 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 1726 1741 hd->ioc->name)); 1727 1742 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); 1743 + dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n", 1744 + hd->ioc->name, retval)); 1745 + goto fail_out; 1728 1746 } 1729 1747 1748 + /* 1749 + * Handle success case, see if theres a non-zero ioc_status. 1750 + */ 1751 + if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS || 1752 + hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED || 1753 + hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED) 1754 + retval = 0; 1755 + else 1756 + retval = FAILED; 1757 + 1730 1758 return retval; 1759 + 1760 + fail_out: 1761 + 1762 + /* 1763 + * Free task managment mf, and corresponding tm flags 1764 + */ 1765 + mpt_free_msg_frame(hd->ioc, mf); 1766 + hd->tmPending = 0; 1767 + hd->tmState = TM_STATE_NONE; 1768 + return FAILED; 1731 1769 } 1732 1770 1733 1771 static int ··· 1772 1770 * (linux scsi_host_template.eh_abort_handler routine) 1773 1771 * 1774 1772 * Returns SUCCESS or FAILED. 1775 - */ 1773 + **/ 1776 1774 int 1777 1775 mptscsih_abort(struct scsi_cmnd * SCpnt) 1778 1776 { ··· 1808 1806 return SUCCESS; 1809 1807 } 1810 1808 1811 - if (hd->resetPending) { 1809 + if (hd->resetPending) 1812 1810 return FAILED; 1813 - } 1814 1811 1815 1812 if (hd->timeouts < -1) 1816 1813 hd->timeouts++; ··· 1836 1835 ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); 1837 1836 1838 1837 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && 1839 - SCpnt->serial_number == sn) { 1838 + SCpnt->serial_number == sn) 1840 1839 retval = FAILED; 1841 - } 1842 1840 1843 1841 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", 1844 1842 hd->ioc->name, ··· 1845 1845 1846 1846 if (retval == 0) 1847 1847 return SUCCESS; 1848 - 1849 - if(retval != FAILED ) { 1850 - hd->tmPending = 0; 1851 - hd->tmState = TM_STATE_NONE; 1852 - } 1853 - return FAILED; 1848 + else 1849 + return FAILED; 1854 1850 } 1855 1851 1856 1852 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ ··· 1857 1861 * (linux scsi_host_template.eh_dev_reset_handler routine) 1858 1862 * 1859 1863 * Returns SUCCESS or FAILED. 1860 - */ 1864 + **/ 1861 1865 int 1862 1866 mptscsih_dev_reset(struct scsi_cmnd * SCpnt) 1863 1867 { ··· 1892 1896 1893 1897 if (retval == 0) 1894 1898 return SUCCESS; 1895 - 1896 - if(retval != FAILED ) { 1897 - hd->tmPending = 0; 1898 - hd->tmState = TM_STATE_NONE; 1899 - } 1900 - return FAILED; 1899 + else 1900 + return FAILED; 1901 1901 } 1902 + 1902 1903 1903 1904 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1904 1905 /** ··· 1905 1912 * (linux scsi_host_template.eh_bus_reset_handler routine) 1906 1913 * 1907 1914 * Returns SUCCESS or FAILED. 1908 - */ 1915 + **/ 1909 1916 int 1910 1917 mptscsih_bus_reset(struct scsi_cmnd * SCpnt) 1911 1918 { ··· 1939 1946 1940 1947 if (retval == 0) 1941 1948 return SUCCESS; 1942 - 1943 - if(retval != FAILED ) { 1944 - hd->tmPending = 0; 1945 - hd->tmState = TM_STATE_NONE; 1946 - } 1947 - return FAILED; 1949 + else 1950 + return FAILED; 1948 1951 } 1949 1952 1950 1953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ ··· 2023 2034 /** 2024 2035 * mptscsih_tm_wait_for_completion - wait for completion of TM task 2025 2036 * @hd: Pointer to MPT host structure. 2026 - * @timeout: timeout in seconds 2027 2037 * 2028 2038 * Returns {SUCCESS,FAILED}. 2029 2039 */ ··· 2096 2108 * load/init time via the mpt_register() API call. 2097 2109 * 2098 2110 * Returns 1 indicating alloc'd request frame ptr should be freed. 2099 - */ 2111 + **/ 2100 2112 int 2101 2113 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 2102 2114 { ··· 2106 2118 unsigned long flags; 2107 2119 u16 iocstatus; 2108 2120 u8 tmType; 2121 + u32 termination_count; 2109 2122 2110 2123 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n", 2111 - ioc->name, mf, mr)); 2112 - if (ioc->sh) { 2113 - /* Depending on the thread, a timer is activated for 2114 - * the TM request. Delete this timer on completion of TM. 2115 - * Decrement count of outstanding TM requests. 2116 - */ 2117 - hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; 2118 - } else { 2119 - dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n", 2120 - ioc->name)); 2124 + ioc->name, mf, mr)); 2125 + if (!ioc->sh) { 2126 + dtmprintk((MYIOC_s_WARN_FMT 2127 + "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name)); 2121 2128 return 1; 2122 2129 } 2123 2130 2124 2131 if (mr == NULL) { 2125 - dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n", 2126 - ioc->name, mf)); 2132 + dtmprintk((MYIOC_s_WARN_FMT 2133 + "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf)); 2127 2134 return 1; 2128 - } else { 2129 - pScsiTmReply = (SCSITaskMgmtReply_t*)mr; 2130 - pScsiTmReq = (SCSITaskMgmt_t*)mf; 2131 - 2132 - /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ 2133 - tmType = pScsiTmReq->TaskType; 2134 - 2135 - if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && 2136 - pScsiTmReply->ResponseCode) 2137 - mptscsih_taskmgmt_response_code(ioc, 2138 - pScsiTmReply->ResponseCode); 2139 - 2140 - dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", 2141 - ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); 2142 - DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); 2143 - 2144 - iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; 2145 - hd->tm_iocstatus = iocstatus; 2146 - dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", 2147 - ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); 2148 - /* Error? (anything non-zero?) */ 2149 - if (iocstatus) { 2150 - 2151 - /* clear flags and continue. 2152 - */ 2153 - if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) 2154 - hd->abortSCpnt = NULL; 2155 - 2156 - /* If an internal command is present 2157 - * or the TM failed - reload the FW. 2158 - * FC FW may respond FAILED to an ABORT 2159 - */ 2160 - if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { 2161 - if ((hd->cmdPtr) || 2162 - (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) { 2163 - if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) { 2164 - printk((KERN_WARNING 2165 - " Firmware Reload FAILED!!\n")); 2166 - } 2167 - } 2168 - } 2169 - } else { 2170 - dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name)); 2171 - 2172 - hd->abortSCpnt = NULL; 2173 - 2174 - } 2175 2135 } 2176 2136 2137 + hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; 2138 + pScsiTmReply = (SCSITaskMgmtReply_t*)mr; 2139 + pScsiTmReq = (SCSITaskMgmt_t*)mf; 2140 + tmType = pScsiTmReq->TaskType; 2141 + iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; 2142 + termination_count = le32_to_cpu(pScsiTmReply->TerminationCount); 2143 + 2144 + if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && 2145 + pScsiTmReply->ResponseCode) 2146 + mptscsih_taskmgmt_response_code(ioc, 2147 + pScsiTmReply->ResponseCode); 2148 + DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); 2149 + 2150 + #if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM) 2151 + printk("%s: ha=%d [%d:%d:0] task_type=0x%02X " 2152 + "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X " 2153 + "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus, 2154 + pScsiTmReply->TargetID, pScsiTmReq->TaskType, 2155 + le16_to_cpu(pScsiTmReply->IOCStatus), 2156 + le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode, 2157 + le32_to_cpu(pScsiTmReply->TerminationCount)); 2158 + #endif 2159 + if (!iocstatus) { 2160 + dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name)); 2161 + hd->abortSCpnt = NULL; 2162 + goto out; 2163 + } 2164 + 2165 + /* Error? (anything non-zero?) */ 2166 + 2167 + /* clear flags and continue. 2168 + */ 2169 + switch (tmType) { 2170 + 2171 + case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 2172 + if (termination_count == 1) 2173 + iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED; 2174 + hd->abortSCpnt = NULL; 2175 + break; 2176 + 2177 + case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS: 2178 + 2179 + /* If an internal command is present 2180 + * or the TM failed - reload the FW. 2181 + * FC FW may respond FAILED to an ABORT 2182 + */ 2183 + if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED || 2184 + hd->cmdPtr) 2185 + if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) 2186 + printk((KERN_WARNING " Firmware Reload FAILED!!\n")); 2187 + break; 2188 + 2189 + case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 2190 + default: 2191 + break; 2192 + } 2193 + 2194 + out: 2177 2195 spin_lock_irqsave(&ioc->FreeQlock, flags); 2178 2196 hd->tmPending = 0; 2179 - spin_unlock_irqrestore(&ioc->FreeQlock, flags); 2180 2197 hd->tmState = TM_STATE_NONE; 2198 + hd->tm_iocstatus = iocstatus; 2199 + spin_unlock_irqrestore(&ioc->FreeQlock, flags); 2181 2200 2182 2201 return 1; 2183 2202 }