aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptscsih.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r--drivers/message/fusion/mptscsih.c295
1 files changed, 145 insertions, 150 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index f9e11c8db462..3bc9446ec42d 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1536,7 +1536,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1536 */ 1536 */
1537 1537
1538/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1538/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1539/* 1539/**
1540 * mptscsih_TMHandler - Generic handler for SCSI Task Management. 1540 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1541 * Fall through to mpt_HardResetHandler if: not operational, too many 1541 * Fall through to mpt_HardResetHandler if: not operational, too many
1542 * failed TM requests or handshake failure. 1542 * failed TM requests or handshake failure.
@@ -1552,28 +1552,17 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1552 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC 1552 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1553 * will be active. 1553 * will be active.
1554 * 1554 *
1555 * Returns 0 for SUCCESS or -1 if FAILED. 1555 * Returns 0 for SUCCESS, or FAILED.
1556 */ 1556 **/
1557int 1557int
1558mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) 1558mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1559{ 1559{
1560 MPT_ADAPTER *ioc; 1560 MPT_ADAPTER *ioc;
1561 int rc = -1; 1561 int rc = -1;
1562 int doTask = 1;
1563 u32 ioc_raw_state; 1562 u32 ioc_raw_state;
1564 unsigned long flags; 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 ioc = hd->ioc; 1565 ioc = hd->ioc;
1573 if (ioc == NULL) {
1574 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1575 return FAILED;
1576 }
1577 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); 1566 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1578 1567
1579 // SJR - CHECKME - Can we avoid this here? 1568 // SJR - CHECKME - Can we avoid this here?
@@ -1586,8 +1575,10 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
1586 spin_unlock_irqrestore(&ioc->diagLock, flags); 1575 spin_unlock_irqrestore(&ioc->diagLock, flags);
1587 1576
1588 /* Wait a fixed amount of time for the TM pending flag to be cleared. 1577 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1589 * If we time out and not bus reset, then we return a FAILED status to the caller. 1578 * If we time out and not bus reset, then we return a FAILED status
1590 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are 1579 * to the caller.
1580 * The call to mptscsih_tm_pending_wait() will set the pending flag
1581 * if we are
1591 * successful. Otherwise, reload the FW. 1582 * successful. Otherwise, reload the FW.
1592 */ 1583 */
1593 if (mptscsih_tm_pending_wait(hd) == FAILED) { 1584 if (mptscsih_tm_pending_wait(hd) == FAILED) {
@@ -1597,18 +1588,16 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
1597 hd->ioc->name, hd->tmPending)); 1588 hd->ioc->name, hd->tmPending));
1598 return FAILED; 1589 return FAILED;
1599 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { 1590 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1600 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: " 1591 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
1601 "Timed out waiting for last TM (%d) to complete! \n", 1592 "reset: Timed out waiting for last TM (%d) "
1602 hd->ioc->name, hd->tmPending)); 1593 "to complete! \n", hd->ioc->name,
1594 hd->tmPending));
1603 return FAILED; 1595 return FAILED;
1604 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { 1596 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1605 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " 1597 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1606 "Timed out waiting for last TM (%d) to complete! \n", 1598 "Timed out waiting for last TM (%d) to complete! \n",
1607 hd->ioc->name, hd->tmPending)); 1599 hd->ioc->name, hd->tmPending));
1608 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) 1600 return FAILED;
1609 return FAILED;
1610
1611 doTask = 0;
1612 } 1601 }
1613 } else { 1602 } else {
1614 spin_lock_irqsave(&hd->ioc->FreeQlock, flags); 1603 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
@@ -1616,47 +1605,40 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
1616 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1605 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1617 } 1606 }
1618 1607
1619 /* Is operational?
1620 */
1621 ioc_raw_state = mpt_GetIocState(hd->ioc, 0); 1608 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1622 1609
1623#ifdef MPT_DEBUG_RESET
1624 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { 1610 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1625 printk(MYIOC_s_WARN_FMT 1611 printk(MYIOC_s_WARN_FMT
1626 "TM Handler: IOC Not operational(0x%x)!\n", 1612 "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1627 hd->ioc->name, ioc_raw_state); 1613 ioc->name, type, ioc_raw_state);
1628 } 1614 printk(KERN_WARNING " Issuing HardReset!!\n");
1629#endif 1615 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1630 1616 printk((KERN_WARNING "TMHandler: HardReset "
1631 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) 1617 "FAILED!!\n"));
1632 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) { 1618 return FAILED;
1633
1634 /* Isse the Task Mgmt request.
1635 */
1636 if (hd->hard_resets < -1)
1637 hd->hard_resets++;
1638 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, ctx2abort, timeout);
1639 if (rc) {
1640 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1641 } else {
1642 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1643 }
1644 } 1619 }
1645 1620
1646 /* Only fall through to the HRH if this is a bus reset 1621 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1647 */ 1622 printk(MYIOC_s_WARN_FMT
1648 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc || 1623 "TM Handler for type=%x: ioc_state: "
1649 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { 1624 "DOORBELL_ACTIVE (0x%x)!\n",
1650 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 1625 ioc->name, type, ioc_raw_state);
1651 hd->ioc->name)); 1626 return FAILED;
1652 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1653 } 1627 }
1654 1628
1655 /* 1629 /* Isse the Task Mgmt request.
1656 * Check IOCStatus from TM reply message
1657 */ 1630 */
1658 if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS) 1631 if (hd->hard_resets < -1)
1659 rc = FAILED; 1632 hd->hard_resets++;
1633
1634 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1635 ctx2abort, timeout);
1636 if (rc)
1637 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1638 hd->ioc->name);
1639 else
1640 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
1641 hd->ioc->name));
1660 1642
1661 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); 1643 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1662 1644
@@ -1665,7 +1647,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
1665 1647
1666 1648
1667/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1649/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1668/* 1650/**
1669 * mptscsih_IssueTaskMgmt - Generic send Task Management function. 1651 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1670 * @hd: Pointer to MPT_SCSI_HOST structure 1652 * @hd: Pointer to MPT_SCSI_HOST structure
1671 * @type: Task Management type 1653 * @type: Task Management type
@@ -1678,9 +1660,9 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
1678 * 1660 *
1679 * Not all fields are meaningfull for all task types. 1661 * Not all fields are meaningfull for all task types.
1680 * 1662 *
1681 * Returns 0 for SUCCESS, -999 for "no msg frames", 1663 * Returns 0 for SUCCESS, or FAILED.
1682 * else other non-zero value returned. 1664 *
1683 */ 1665 **/
1684static int 1666static int
1685mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) 1667mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1686{ 1668{
@@ -1720,32 +1702,52 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, i
1720 1702
1721 pScsiTm->TaskMsgContext = ctx2abort; 1703 pScsiTm->TaskMsgContext = ctx2abort;
1722 1704
1723 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", 1705 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1724 hd->ioc->name, ctx2abort, type)); 1706 "type=%d\n", hd->ioc->name, ctx2abort, type));
1725 1707
1726 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); 1708 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1727 1709
1728 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, 1710 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1729 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, 1711 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
1730 CAN_SLEEP)) != 0) { 1712 dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
1731 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!" 1713 " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
1732 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, 1714 hd->ioc, mf, retval));
1733 hd->ioc, mf)); 1715 goto fail_out;
1734 mpt_free_msg_frame(hd->ioc, mf);
1735 return retval;
1736 } 1716 }
1737 1717
1738 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { 1718 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1739 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!" 1719 dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1740 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, 1720 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1741 hd->ioc, mf)); 1721 hd->ioc, mf));
1742 mpt_free_msg_frame(hd->ioc, mf);
1743 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 1722 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1744 hd->ioc->name)); 1723 hd->ioc->name));
1745 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); 1724 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1725 dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
1726 hd->ioc->name, retval));
1727 goto fail_out;
1746 } 1728 }
1747 1729
1730 /*
1731 * Handle success case, see if theres a non-zero ioc_status.
1732 */
1733 if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1734 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1735 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1736 retval = 0;
1737 else
1738 retval = FAILED;
1739
1748 return retval; 1740 return retval;
1741
1742 fail_out:
1743
1744 /*
1745 * Free task managment mf, and corresponding tm flags
1746 */
1747 mpt_free_msg_frame(hd->ioc, mf);
1748 hd->tmPending = 0;
1749 hd->tmState = TM_STATE_NONE;
1750 return FAILED;
1749} 1751}
1750 1752
1751static int 1753static int
@@ -1770,7 +1772,7 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1770 * (linux scsi_host_template.eh_abort_handler routine) 1772 * (linux scsi_host_template.eh_abort_handler routine)
1771 * 1773 *
1772 * Returns SUCCESS or FAILED. 1774 * Returns SUCCESS or FAILED.
1773 */ 1775 **/
1774int 1776int
1775mptscsih_abort(struct scsi_cmnd * SCpnt) 1777mptscsih_abort(struct scsi_cmnd * SCpnt)
1776{ 1778{
@@ -1806,9 +1808,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1806 return SUCCESS; 1808 return SUCCESS;
1807 } 1809 }
1808 1810
1809 if (hd->resetPending) { 1811 if (hd->resetPending)
1810 return FAILED; 1812 return FAILED;
1811 }
1812 1813
1813 if (hd->timeouts < -1) 1814 if (hd->timeouts < -1)
1814 hd->timeouts++; 1815 hd->timeouts++;
@@ -1835,9 +1836,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1835 ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); 1836 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1836 1837
1837 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && 1838 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1838 SCpnt->serial_number == sn) { 1839 SCpnt->serial_number == sn)
1839 retval = FAILED; 1840 retval = FAILED;
1840 }
1841 1841
1842 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", 1842 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1843 hd->ioc->name, 1843 hd->ioc->name,
@@ -1845,12 +1845,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1845 1845
1846 if (retval == 0) 1846 if (retval == 0)
1847 return SUCCESS; 1847 return SUCCESS;
1848 1848 else
1849 if(retval != FAILED ) { 1849 return FAILED;
1850 hd->tmPending = 0;
1851 hd->tmState = TM_STATE_NONE;
1852 }
1853 return FAILED;
1854} 1850}
1855 1851
1856/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1852/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1861,7 +1857,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1861 * (linux scsi_host_template.eh_dev_reset_handler routine) 1857 * (linux scsi_host_template.eh_dev_reset_handler routine)
1862 * 1858 *
1863 * Returns SUCCESS or FAILED. 1859 * Returns SUCCESS or FAILED.
1864 */ 1860 **/
1865int 1861int
1866mptscsih_dev_reset(struct scsi_cmnd * SCpnt) 1862mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1867{ 1863{
@@ -1896,14 +1892,11 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1896 1892
1897 if (retval == 0) 1893 if (retval == 0)
1898 return SUCCESS; 1894 return SUCCESS;
1899 1895 else
1900 if(retval != FAILED ) { 1896 return FAILED;
1901 hd->tmPending = 0;
1902 hd->tmState = TM_STATE_NONE;
1903 }
1904 return FAILED;
1905} 1897}
1906 1898
1899
1907/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1900/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1908/** 1901/**
1909 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant 1902 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
@@ -1912,7 +1905,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1912 * (linux scsi_host_template.eh_bus_reset_handler routine) 1905 * (linux scsi_host_template.eh_bus_reset_handler routine)
1913 * 1906 *
1914 * Returns SUCCESS or FAILED. 1907 * Returns SUCCESS or FAILED.
1915 */ 1908 **/
1916int 1909int
1917mptscsih_bus_reset(struct scsi_cmnd * SCpnt) 1910mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1918{ 1911{
@@ -1946,12 +1939,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1946 1939
1947 if (retval == 0) 1940 if (retval == 0)
1948 return SUCCESS; 1941 return SUCCESS;
1949 1942 else
1950 if(retval != FAILED ) { 1943 return FAILED;
1951 hd->tmPending = 0;
1952 hd->tmState = TM_STATE_NONE;
1953 }
1954 return FAILED;
1955} 1944}
1956 1945
1957/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1946/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2034,7 +2023,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2034/** 2023/**
2035 * mptscsih_tm_wait_for_completion - wait for completion of TM task 2024 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2036 * @hd: Pointer to MPT host structure. 2025 * @hd: Pointer to MPT host structure.
2037 * @timeout: timeout in seconds
2038 * 2026 *
2039 * Returns {SUCCESS,FAILED}. 2027 * Returns {SUCCESS,FAILED}.
2040 */ 2028 */
@@ -2108,7 +2096,7 @@ mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2108 * load/init time via the mpt_register() API call. 2096 * load/init time via the mpt_register() API call.
2109 * 2097 *
2110 * Returns 1 indicating alloc'd request frame ptr should be freed. 2098 * Returns 1 indicating alloc'd request frame ptr should be freed.
2111 */ 2099 **/
2112int 2100int
2113mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 2101mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2114{ 2102{
@@ -2118,78 +2106,85 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
2118 unsigned long flags; 2106 unsigned long flags;
2119 u16 iocstatus; 2107 u16 iocstatus;
2120 u8 tmType; 2108 u8 tmType;
2109 u32 termination_count;
2121 2110
2122 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n", 2111 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2123 ioc->name, mf, mr)); 2112 ioc->name, mf, mr));
2124 if (ioc->sh) { 2113 if (!ioc->sh) {
2125 /* Depending on the thread, a timer is activated for 2114 dtmprintk((MYIOC_s_WARN_FMT
2126 * the TM request. Delete this timer on completion of TM. 2115 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2127 * Decrement count of outstanding TM requests.
2128 */
2129 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2130 } else {
2131 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2132 ioc->name));
2133 return 1; 2116 return 1;
2134 } 2117 }
2135 2118
2136 if (mr == NULL) { 2119 if (mr == NULL) {
2137 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n", 2120 dtmprintk((MYIOC_s_WARN_FMT
2138 ioc->name, mf)); 2121 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2139 return 1; 2122 return 1;
2140 } else { 2123 }
2141 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2142 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2143 2124
2144 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ 2125 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2145 tmType = pScsiTmReq->TaskType; 2126 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2127 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2128 tmType = pScsiTmReq->TaskType;
2129 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2130 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2131
2132 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2133 pScsiTmReply->ResponseCode)
2134 mptscsih_taskmgmt_response_code(ioc,
2135 pScsiTmReply->ResponseCode);
2136 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2137
2138#if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
2139 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2140 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2141 "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2142 pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2143 le16_to_cpu(pScsiTmReply->IOCStatus),
2144 le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2145 le32_to_cpu(pScsiTmReply->TerminationCount));
2146#endif
2147 if (!iocstatus) {
2148 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2149 hd->abortSCpnt = NULL;
2150 goto out;
2151 }
2146 2152
2147 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && 2153 /* Error? (anything non-zero?) */
2148 pScsiTmReply->ResponseCode)
2149 mptscsih_taskmgmt_response_code(ioc,
2150 pScsiTmReply->ResponseCode);
2151 2154
2152 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", 2155 /* clear flags and continue.
2153 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); 2156 */
2154 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); 2157 switch (tmType) {
2155 2158
2156 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; 2159 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2157 hd->tm_iocstatus = iocstatus; 2160 if (termination_count == 1)
2158 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", 2161 iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2159 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); 2162 hd->abortSCpnt = NULL;
2160 /* Error? (anything non-zero?) */ 2163 break;
2161 if (iocstatus) {
2162 2164
2163 /* clear flags and continue. 2165 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2164 */
2165 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2166 hd->abortSCpnt = NULL;
2167 2166
2168 /* If an internal command is present 2167 /* If an internal command is present
2169 * or the TM failed - reload the FW. 2168 * or the TM failed - reload the FW.
2170 * FC FW may respond FAILED to an ABORT 2169 * FC FW may respond FAILED to an ABORT
2171 */ 2170 */
2172 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { 2171 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2173 if ((hd->cmdPtr) || 2172 hd->cmdPtr)
2174 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) { 2173 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2175 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) { 2174 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
2176 printk((KERN_WARNING 2175 break;
2177 " Firmware Reload FAILED!!\n"));
2178 }
2179 }
2180 }
2181 } else {
2182 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2183
2184 hd->abortSCpnt = NULL;
2185 2176
2186 } 2177 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2178 default:
2179 break;
2187 } 2180 }
2188 2181
2182 out:
2189 spin_lock_irqsave(&ioc->FreeQlock, flags); 2183 spin_lock_irqsave(&ioc->FreeQlock, flags);
2190 hd->tmPending = 0; 2184 hd->tmPending = 0;
2191 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2192 hd->tmState = TM_STATE_NONE; 2185 hd->tmState = TM_STATE_NONE;
2186 hd->tm_iocstatus = iocstatus;
2187 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2193 2188
2194 return 1; 2189 return 1;
2195} 2190}