aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-05-29 07:14:48 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-09 18:28:30 -0400
commit1ba9ab2eb2c53df52e498779e14cf4e5ea77b0ad (patch)
tree494361505cc5556ba4b843714c05d681506a846b /drivers/message/fusion
parent37c60f374a855974c27bd30d5662a8fa5e933792 (diff)
[SCSI] mpt fusion: rewrite taskmgmt request and completion routines
1.) rewrite taskmanagement request and completion routines, making them single threaded and using the generic MPT_MGMT struct, deleting mptscsih_TMHandler, replacing with single request TM handler mptscsih_IssueTaskMgmt, and killing the watchdog timer functions. 2.) cleanup ioc_reset callback handlers, introducing wrappers for synchronizing error recovery (mpt_set_taskmgmt_in_progress_flag, mpt_clear_taskmgmt_in_progress_flag), as the fusion firmware only handles one task management request at a time Signed-off-by: Kashyap Desai <kadesai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/mptbase.c80
-rw-r--r--drivers/message/fusion/mptbase.h8
-rw-r--r--drivers/message/fusion/mptscsih.c459
-rw-r--r--drivers/message/fusion/mptscsih.h3
-rw-r--r--drivers/message/fusion/mptspi.c2
5 files changed, 239 insertions, 313 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index d8d5231f484e..af862bf6386f 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -341,7 +341,7 @@ mpt_fault_reset_work(struct work_struct *work)
341 int rc; 341 int rc;
342 unsigned long flags; 342 unsigned long flags;
343 343
344 if (ioc->diagPending || !ioc->active) 344 if (ioc->ioc_reset_in_progress || !ioc->active)
345 goto out; 345 goto out;
346 346
347 ioc_raw_state = mpt_GetIocState(ioc, 0); 347 ioc_raw_state = mpt_GetIocState(ioc, 0);
@@ -1771,14 +1771,15 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1771 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1771 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1772 1772
1773 ioc->pcidev = pdev; 1773 ioc->pcidev = pdev;
1774 ioc->diagPending = 0;
1775 spin_lock_init(&ioc->diagLock);
1776 spin_lock_init(&ioc->initializing_hba_lock); 1774 spin_lock_init(&ioc->initializing_hba_lock);
1777 1775
1776 spin_lock_init(&ioc->taskmgmt_lock);
1778 mutex_init(&ioc->internal_cmds.mutex); 1777 mutex_init(&ioc->internal_cmds.mutex);
1779 init_completion(&ioc->internal_cmds.done); 1778 init_completion(&ioc->internal_cmds.done);
1780 mutex_init(&ioc->mptbase_cmds.mutex); 1779 mutex_init(&ioc->mptbase_cmds.mutex);
1781 init_completion(&ioc->mptbase_cmds.done); 1780 init_completion(&ioc->mptbase_cmds.done);
1781 mutex_init(&ioc->taskmgmt_cmds.mutex);
1782 init_completion(&ioc->taskmgmt_cmds.done);
1782 1783
1783 /* Initialize the event logging. 1784 /* Initialize the event logging.
1784 */ 1785 */
@@ -6572,6 +6573,53 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
6572 6573
6573 *size = y; 6574 *size = y;
6574} 6575}
6576/**
6577 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task managment
6578 * @ioc: Pointer to MPT_ADAPTER structure
6579 *
6580 * Returns 0 for SUCCESS or -1 if FAILED.
6581 *
6582 * If -1 is return, then it was not possible to set the flags
6583 **/
6584int
6585mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6586{
6587 unsigned long flags;
6588 int retval;
6589
6590 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6591 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6592 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6593 retval = -1;
6594 goto out;
6595 }
6596 retval = 0;
6597 ioc->taskmgmt_in_progress = 1;
6598 if (ioc->alt_ioc)
6599 ioc->alt_ioc->taskmgmt_in_progress = 1;
6600 out:
6601 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6602 return retval;
6603}
6604EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6605
6606/**
6607 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task managment
6608 * @ioc: Pointer to MPT_ADAPTER structure
6609 *
6610 **/
6611void
6612mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6613{
6614 unsigned long flags;
6615
6616 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6617 ioc->taskmgmt_in_progress = 0;
6618 if (ioc->alt_ioc)
6619 ioc->alt_ioc->taskmgmt_in_progress = 0;
6620 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6621}
6622EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6575 6623
6576 6624
6577/** 6625/**
@@ -6638,14 +6686,15 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6638 /* Reset the adapter. Prevent more than 1 call to 6686 /* Reset the adapter. Prevent more than 1 call to
6639 * mpt_do_ioc_recovery at any instant in time. 6687 * mpt_do_ioc_recovery at any instant in time.
6640 */ 6688 */
6641 spin_lock_irqsave(&ioc->diagLock, flags); 6689 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6642 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){ 6690 if (ioc->ioc_reset_in_progress) {
6643 spin_unlock_irqrestore(&ioc->diagLock, flags); 6691 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6644 return 0; 6692 return 0;
6645 } else {
6646 ioc->diagPending = 1;
6647 } 6693 }
6648 spin_unlock_irqrestore(&ioc->diagLock, flags); 6694 ioc->ioc_reset_in_progress = 1;
6695 if (ioc->alt_ioc)
6696 ioc->alt_ioc->ioc_reset_in_progress = 1;
6697 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6649 6698
6650 /* FIXME: If do_ioc_recovery fails, repeat.... 6699 /* FIXME: If do_ioc_recovery fails, repeat....
6651 */ 6700 */
@@ -6680,11 +6729,14 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6680 if (ioc->alt_ioc) 6729 if (ioc->alt_ioc)
6681 ioc->alt_ioc->reload_fw = 0; 6730 ioc->alt_ioc->reload_fw = 0;
6682 6731
6683 spin_lock_irqsave(&ioc->diagLock, flags); 6732 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6684 ioc->diagPending = 0; 6733 ioc->ioc_reset_in_progress = 0;
6685 if (ioc->alt_ioc) 6734 ioc->taskmgmt_in_progress = 0;
6686 ioc->alt_ioc->diagPending = 0; 6735 if (ioc->alt_ioc) {
6687 spin_unlock_irqrestore(&ioc->diagLock, flags); 6736 ioc->alt_ioc->ioc_reset_in_progress = 0;
6737 ioc->alt_ioc->taskmgmt_in_progress = 0;
6738 }
6739 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6688 6740
6689 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); 6741 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6690 6742
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 4d77256954f9..2129aff294d5 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -657,8 +657,6 @@ typedef struct _MPT_ADAPTER
657 MPT_IOCTL *ioctl; /* ioctl data pointer */ 657 MPT_IOCTL *ioctl; /* ioctl data pointer */
658 struct proc_dir_entry *ioc_dentry; 658 struct proc_dir_entry *ioc_dentry;
659 struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */ 659 struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
660 spinlock_t diagLock; /* diagnostic reset lock */
661 int diagPending;
662 u32 biosVersion; /* BIOS version from IO Unit Page 2 */ 660 u32 biosVersion; /* BIOS version from IO Unit Page 2 */
663 int eventTypes; /* Event logging parameters */ 661 int eventTypes; /* Event logging parameters */
664 int eventContext; /* Next event context */ 662 int eventContext; /* Next event context */
@@ -712,6 +710,10 @@ typedef struct _MPT_ADAPTER
712 MPT_MGMT sas_mgmt; 710 MPT_MGMT sas_mgmt;
713 MPT_MGMT mptbase_cmds; /* for sending config pages */ 711 MPT_MGMT mptbase_cmds; /* for sending config pages */
714 MPT_MGMT internal_cmds; 712 MPT_MGMT internal_cmds;
713 MPT_MGMT taskmgmt_cmds;
714 spinlock_t taskmgmt_lock; /* diagnostic reset lock */
715 int taskmgmt_in_progress;
716 u8 ioc_reset_in_progress;
715 struct work_struct sas_persist_task; 717 struct work_struct sas_persist_task;
716 718
717 struct work_struct fc_setup_reset_work; 719 struct work_struct fc_setup_reset_work;
@@ -931,6 +933,8 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
931extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 933extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
932extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 934extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
933extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk); 935extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk);
936extern int mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc);
937extern void mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc);
934extern void mpt_halt_firmware(MPT_ADAPTER *ioc); 938extern void mpt_halt_firmware(MPT_ADAPTER *ioc);
935 939
936 940
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 35173252e948..2463731ed355 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -92,20 +92,24 @@ static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
92 SCSIIORequest_t *pReq, int req_idx); 92 SCSIIORequest_t *pReq, int req_idx);
93static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx); 93static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
94static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply); 94static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
95static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
96static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
97 95
98static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); 96int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
97 int lun, int ctx2abort, ulong timeout);
99 98
100int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 99int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
101int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 100int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
102 101
102static void
103mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
103static int mptscsih_get_completion_code(MPT_ADAPTER *ioc, 104static int mptscsih_get_completion_code(MPT_ADAPTER *ioc,
104 MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); 105 MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
105int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 106int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
106static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 107static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
107static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); 108static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
108 109
110static int
111mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
112 SCSITaskMgmtReply_t *pScsiTmReply);
109void mptscsih_remove(struct pci_dev *); 113void mptscsih_remove(struct pci_dev *);
110void mptscsih_shutdown(struct pci_dev *); 114void mptscsih_shutdown(struct pci_dev *);
111#ifdef CONFIG_PM 115#ifdef CONFIG_PM
@@ -1466,8 +1470,8 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1466 1470
1467/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1471/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1468/** 1472/**
1469 * mptscsih_TMHandler - Generic handler for SCSI Task Management. 1473 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1470 * @hd: Pointer to MPT SCSI HOST structure 1474 * @hd: Pointer to MPT_SCSI_HOST structure
1471 * @type: Task Management type 1475 * @type: Task Management type
1472 * @channel: channel number for task management 1476 * @channel: channel number for task management
1473 * @id: Logical Target ID for reset (if appropriate) 1477 * @id: Logical Target ID for reset (if appropriate)
@@ -1475,145 +1479,68 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1475 * @ctx2abort: Context for the task to be aborted (if appropriate) 1479 * @ctx2abort: Context for the task to be aborted (if appropriate)
1476 * @timeout: timeout for task management control 1480 * @timeout: timeout for task management control
1477 * 1481 *
1478 * Fall through to mpt_HardResetHandler if: not operational, too many 1482 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1479 * failed TM requests or handshake failure. 1483 * or a non-interrupt thread. In the former, must not call schedule().
1480 * 1484 *
1481 * Remark: Currently invoked from a non-interrupt thread (_bh). 1485 * Not all fields are meaningfull for all task types.
1482 * 1486 *
1483 * Note: With old EH code, at most 1 SCSI TaskMgmt function per IOC 1487 * Returns 0 for SUCCESS, or FAILED.
1484 * will be active.
1485 * 1488 *
1486 * Returns 0 for SUCCESS, or %FAILED.
1487 **/ 1489 **/
1488int 1490int
1489mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) 1491mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
1492 int ctx2abort, ulong timeout)
1490{ 1493{
1491 MPT_ADAPTER *ioc; 1494 MPT_FRAME_HDR *mf;
1492 int rc = -1; 1495 SCSITaskMgmt_t *pScsiTm;
1496 int ii;
1497 int retval;
1498 MPT_ADAPTER *ioc = hd->ioc;
1499 unsigned long timeleft;
1500 u8 issue_hard_reset;
1493 u32 ioc_raw_state; 1501 u32 ioc_raw_state;
1494 unsigned long flags; 1502 unsigned long time_count;
1495
1496 ioc = hd->ioc;
1497 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler Entered!\n", ioc->name));
1498
1499 // SJR - CHECKME - Can we avoid this here?
1500 // (mpt_HardResetHandler has this check...)
1501 spin_lock_irqsave(&ioc->diagLock, flags);
1502 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1503 spin_unlock_irqrestore(&ioc->diagLock, flags);
1504 return FAILED;
1505 }
1506 spin_unlock_irqrestore(&ioc->diagLock, flags);
1507
1508 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1509 * If we time out and not bus reset, then we return a FAILED status
1510 * to the caller.
1511 * The call to mptscsih_tm_pending_wait() will set the pending flag
1512 * if we are
1513 * successful. Otherwise, reload the FW.
1514 */
1515 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1516 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1517 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler abort: "
1518 "Timed out waiting for last TM (%d) to complete! \n",
1519 ioc->name, hd->tmPending));
1520 return FAILED;
1521 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1522 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler target "
1523 "reset: Timed out waiting for last TM (%d) "
1524 "to complete! \n", ioc->name,
1525 hd->tmPending));
1526 return FAILED;
1527 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1528 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler bus reset: "
1529 "Timed out waiting for last TM (%d) to complete! \n",
1530 ioc->name, hd->tmPending));
1531 return FAILED;
1532 }
1533 } else {
1534 spin_lock_irqsave(&ioc->FreeQlock, flags);
1535 hd->tmPending |= (1 << type);
1536 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1537 }
1538 1503
1504 issue_hard_reset = 0;
1539 ioc_raw_state = mpt_GetIocState(ioc, 0); 1505 ioc_raw_state = mpt_GetIocState(ioc, 0);
1540 1506
1541 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { 1507 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1542 printk(MYIOC_s_WARN_FMT 1508 printk(MYIOC_s_WARN_FMT
1543 "TM Handler for type=%x: IOC Not operational (0x%x)!\n", 1509 "TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1544 ioc->name, type, ioc_raw_state); 1510 ioc->name, type, ioc_raw_state);
1545 printk(MYIOC_s_WARN_FMT " Issuing HardReset!!\n", ioc->name); 1511 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1512 ioc->name, __func__);
1546 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) 1513 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1547 printk(MYIOC_s_WARN_FMT "TMHandler: HardReset " 1514 printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1548 "FAILED!!\n", ioc->name); 1515 "FAILED!!\n", ioc->name);
1549 return FAILED; 1516 return 0;
1550 } 1517 }
1551 1518
1552 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) { 1519 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1553 printk(MYIOC_s_WARN_FMT 1520 printk(MYIOC_s_WARN_FMT
1554 "TM Handler for type=%x: ioc_state: " 1521 "TaskMgmt type=%x: ioc_state: "
1555 "DOORBELL_ACTIVE (0x%x)!\n", 1522 "DOORBELL_ACTIVE (0x%x)!\n",
1556 ioc->name, type, ioc_raw_state); 1523 ioc->name, type, ioc_raw_state);
1557 return FAILED; 1524 return FAILED;
1558 } 1525 }
1559 1526
1560 /* Isse the Task Mgmt request. 1527 mutex_lock(&ioc->taskmgmt_cmds.mutex);
1561 */ 1528 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1562 if (hd->hard_resets < -1) 1529 mf = NULL;
1563 hd->hard_resets++; 1530 retval = FAILED;
1564 1531 goto out;
1565 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, 1532 }
1566 ctx2abort, timeout);
1567 if (rc)
1568 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1569 ioc->name);
1570 else
1571 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issue of TaskMgmt Successful!\n",
1572 ioc->name));
1573
1574 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1575 "TMHandler rc = %d!\n", ioc->name, rc));
1576
1577 return rc;
1578}
1579
1580
1581/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1582/**
1583 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1584 * @hd: Pointer to MPT_SCSI_HOST structure
1585 * @type: Task Management type
1586 * @channel: channel number for task management
1587 * @id: Logical Target ID for reset (if appropriate)
1588 * @lun: Logical Unit for reset (if appropriate)
1589 * @ctx2abort: Context for the task to be aborted (if appropriate)
1590 * @timeout: timeout for task management control
1591 *
1592 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1593 * or a non-interrupt thread. In the former, must not call schedule().
1594 *
1595 * Not all fields are meaningfull for all task types.
1596 *
1597 * Returns 0 for SUCCESS, or FAILED.
1598 *
1599 **/
1600static int
1601mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1602{
1603 MPT_FRAME_HDR *mf;
1604 SCSITaskMgmt_t *pScsiTm;
1605 int ii;
1606 int retval;
1607 MPT_ADAPTER *ioc = hd->ioc;
1608 1533
1609 /* Return Fail to calling function if no message frames available. 1534 /* Return Fail to calling function if no message frames available.
1610 */ 1535 */
1611 if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) { 1536 if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1612 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n", 1537 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1613 ioc->name)); 1538 "TaskMgmt no msg frames!!\n", ioc->name));
1614 return FAILED; 1539 retval = FAILED;
1540 mpt_clear_taskmgmt_in_progress_flag(ioc);
1541 goto out;
1615 } 1542 }
1616 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt request @ %p\n", 1543 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1617 ioc->name, mf)); 1544 ioc->name, mf));
1618 1545
1619 /* Format the Request 1546 /* Format the Request
@@ -1637,11 +1564,14 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, i
1637 1564
1638 pScsiTm->TaskMsgContext = ctx2abort; 1565 pScsiTm->TaskMsgContext = ctx2abort;
1639 1566
1640 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt: ctx2abort (0x%08x) " 1567 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1641 "type=%d\n", ioc->name, ctx2abort, type)); 1568 "task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1569 type, timeout));
1642 1570
1643 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm); 1571 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1644 1572
1573 INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1574 time_count = jiffies;
1645 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && 1575 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1646 (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) 1576 (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1647 mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf); 1577 mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
@@ -1649,47 +1579,50 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, i
1649 retval = mpt_send_handshake_request(ioc->TaskCtx, ioc, 1579 retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1650 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP); 1580 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1651 if (retval) { 1581 if (retval) {
1652 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "send_handshake FAILED!" 1582 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1653 " (hd %p, ioc %p, mf %p, rc=%d) \n", ioc->name, hd, 1583 "TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1654 ioc, mf, retval)); 1584 ioc->name, mf, retval));
1655 goto fail_out; 1585 mpt_free_msg_frame(ioc, mf);
1586 mpt_clear_taskmgmt_in_progress_flag(ioc);
1587 goto out;
1656 } 1588 }
1657 } 1589 }
1658 1590
1659 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { 1591 timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1660 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "task management request TIMED OUT!" 1592 timeout*HZ);
1661 " (hd %p, ioc %p, mf %p) \n", ioc->name, hd, 1593 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1662 ioc, mf)); 1594 retval = FAILED;
1663 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n", 1595 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1664 ioc->name)); 1596 "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1665 retval = mpt_HardResetHandler(ioc, CAN_SLEEP); 1597 mpt_clear_taskmgmt_in_progress_flag(ioc);
1666 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rc=%d \n", 1598 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1667 ioc->name, retval)); 1599 goto out;
1668 goto fail_out; 1600 issue_hard_reset = 1;
1601 goto out;
1669 } 1602 }
1670 1603
1671 /* 1604 retval = mptscsih_taskmgmt_reply(ioc, type,
1672 * Handle success case, see if theres a non-zero ioc_status. 1605 (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1673 */
1674 if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1675 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1676 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1677 retval = 0;
1678 else
1679 retval = FAILED;
1680 1606
1681 return retval; 1607 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1608 "TaskMgmt completed (%d seconds)\n",
1609 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1682 1610
1683 fail_out: 1611 out:
1684 1612
1685 /* 1613 CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1686 * Free task management mf, and corresponding tm flags 1614 if (issue_hard_reset) {
1687 */ 1615 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
1688 mpt_free_msg_frame(ioc, mf); 1616 ioc->name, __func__);
1689 hd->tmPending = 0; 1617 retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
1690 hd->tmState = TM_STATE_NONE; 1618 mpt_free_msg_frame(ioc, mf);
1691 return FAILED; 1619 }
1620
1621 retval = (retval == 0) ? 0 : FAILED;
1622 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1623 return retval;
1692} 1624}
1625EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1693 1626
1694static int 1627static int
1695mptscsih_get_tm_timeout(MPT_ADAPTER *ioc) 1628mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
@@ -1799,9 +1732,11 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1799 1732
1800 hd->abortSCpnt = SCpnt; 1733 hd->abortSCpnt = SCpnt;
1801 1734
1802 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1735 retval = mptscsih_IssueTaskMgmt(hd,
1803 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, 1736 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1804 ctx2abort, mptscsih_get_tm_timeout(ioc)); 1737 vdevice->vtarget->channel,
1738 vdevice->vtarget->id, vdevice->lun,
1739 ctx2abort, mptscsih_get_tm_timeout(ioc));
1805 1740
1806 if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx && 1741 if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx &&
1807 SCpnt->serial_number == sn) 1742 SCpnt->serial_number == sn)
@@ -1865,9 +1800,11 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1865 goto out; 1800 goto out;
1866 } 1801 }
1867 1802
1868 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 1803 retval = mptscsih_IssueTaskMgmt(hd,
1869 vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0, 1804 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1870 mptscsih_get_tm_timeout(ioc)); 1805 vdevice->vtarget->channel,
1806 vdevice->vtarget->id, 0, 0,
1807 mptscsih_get_tm_timeout(ioc));
1871 1808
1872 out: 1809 out:
1873 printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n", 1810 printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
@@ -1914,8 +1851,10 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1914 hd->timeouts++; 1851 hd->timeouts++;
1915 1852
1916 vdevice = SCpnt->device->hostdata; 1853 vdevice = SCpnt->device->hostdata;
1917 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1854 retval = mptscsih_IssueTaskMgmt(hd,
1918 vdevice->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc)); 1855 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1856 vdevice->vtarget->channel, 0, 0, 0,
1857 mptscsih_get_tm_timeout(ioc));
1919 1858
1920 printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n", 1859 printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1921 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); 1860 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
@@ -1976,65 +1915,55 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1976 return retval; 1915 return retval;
1977} 1916}
1978 1917
1979/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1980/**
1981 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1982 * @hd: Pointer to MPT host structure.
1983 *
1984 * Returns {SUCCESS,FAILED}.
1985 */
1986static int 1918static int
1987mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) 1919mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1920 SCSITaskMgmtReply_t *pScsiTmReply)
1988{ 1921{
1989 unsigned long flags; 1922 u16 iocstatus;
1990 int loop_count = 4 * 10; /* Wait 10 seconds */ 1923 u32 termination_count;
1991 int status = FAILED; 1924 int retval;
1992 MPT_ADAPTER *ioc = hd->ioc;
1993 1925
1994 do { 1926 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1995 spin_lock_irqsave(&ioc->FreeQlock, flags); 1927 retval = FAILED;
1996 if (hd->tmState == TM_STATE_NONE) { 1928 goto out;
1997 hd->tmState = TM_STATE_IN_PROGRESS; 1929 }
1998 hd->tmPending = 1;
1999 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2000 status = SUCCESS;
2001 break;
2002 }
2003 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2004 msleep(250);
2005 } while (--loop_count);
2006 1930
2007 return status; 1931 DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
2008}
2009 1932
2010/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1933 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2011/** 1934 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2012 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2013 * @hd: Pointer to MPT host structure.
2014 * @timeout: timeout value
2015 *
2016 * Returns {SUCCESS,FAILED}.
2017 */
2018static int
2019mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2020{
2021 unsigned long flags;
2022 int loop_count = 4 * timeout;
2023 int status = FAILED;
2024 MPT_ADAPTER *ioc = hd->ioc;
2025 1935
2026 do { 1936 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2027 spin_lock_irqsave(&ioc->FreeQlock, flags); 1937 "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
2028 if(hd->tmPending == 0) { 1938 "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
2029 status = SUCCESS; 1939 "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
2030 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 1940 pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
2031 break; 1941 le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
2032 } 1942 termination_count));
2033 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 1943
2034 msleep(250); 1944 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2035 } while (--loop_count); 1945 pScsiTmReply->ResponseCode)
1946 mptscsih_taskmgmt_response_code(ioc,
1947 pScsiTmReply->ResponseCode);
2036 1948
2037 return status; 1949 if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1950 retval = 0;
1951 goto out;
1952 }
1953
1954 retval = FAILED;
1955 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1956 if (termination_count == 1)
1957 retval = 0;
1958 goto out;
1959 }
1960
1961 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1962 iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1963 retval = 0;
1964
1965 out:
1966 return retval;
2038} 1967}
2039 1968
2040/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1969/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2088,97 +2017,28 @@ mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2088 * Returns 1 indicating alloc'd request frame ptr should be freed. 2017 * Returns 1 indicating alloc'd request frame ptr should be freed.
2089 **/ 2018 **/
2090int 2019int
2091mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 2020mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2021 MPT_FRAME_HDR *mr)
2092{ 2022{
2093 SCSITaskMgmtReply_t *pScsiTmReply; 2023 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2094 SCSITaskMgmt_t *pScsiTmReq; 2024 "TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2095 MPT_SCSI_HOST *hd;
2096 unsigned long flags;
2097 u16 iocstatus;
2098 u8 tmType;
2099 u32 termination_count;
2100
2101 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2102 ioc->name, mf, mr));
2103 if (!ioc->sh) {
2104 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
2105 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2106 return 1;
2107 }
2108
2109 if (mr == NULL) {
2110 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
2111 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2112 return 1;
2113 }
2114
2115 hd = shost_priv(ioc->sh);
2116 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2117 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2118 tmType = pScsiTmReq->TaskType;
2119 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2120 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2121 2025
2122 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && 2026 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2123 pScsiTmReply->ResponseCode)
2124 mptscsih_taskmgmt_response_code(ioc,
2125 pScsiTmReply->ResponseCode);
2126 DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
2127 2027
2128#ifdef CONFIG_FUSION_LOGGING 2028 if (!mr)
2129 if ((ioc->debug_level & MPT_DEBUG_REPLY) ||
2130 (ioc->debug_level & MPT_DEBUG_TM ))
2131 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2132 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2133 "term_cmnds=%d\n", __func__, ioc->id, pScsiTmReply->Bus,
2134 pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2135 le16_to_cpu(pScsiTmReply->IOCStatus),
2136 le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2137 le32_to_cpu(pScsiTmReply->TerminationCount));
2138#endif
2139 if (!iocstatus) {
2140 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT " TaskMgmt SUCCESS\n", ioc->name));
2141 hd->abortSCpnt = NULL;
2142 goto out; 2029 goto out;
2143 }
2144
2145 /* Error? (anything non-zero?) */
2146
2147 /* clear flags and continue.
2148 */
2149 switch (tmType) {
2150
2151 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2152 if (termination_count == 1)
2153 iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2154 hd->abortSCpnt = NULL;
2155 break;
2156
2157 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2158
2159 /* If an internal command is present
2160 * or the TM failed - reload the FW.
2161 * FC FW may respond FAILED to an ABORT
2162 */
2163 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2164 hd->cmdPtr)
2165 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2166 printk(MYIOC_s_WARN_FMT " Firmware Reload FAILED!!\n", ioc->name);
2167 break;
2168
2169 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2170 default:
2171 break;
2172 }
2173 2030
2031 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2032 memcpy(ioc->taskmgmt_cmds.reply, mr,
2033 min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2174 out: 2034 out:
2175 spin_lock_irqsave(&ioc->FreeQlock, flags); 2035 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2176 hd->tmPending = 0; 2036 mpt_clear_taskmgmt_in_progress_flag(ioc);
2177 hd->tmState = TM_STATE_NONE; 2037 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2178 hd->tm_iocstatus = iocstatus; 2038 complete(&ioc->taskmgmt_cmds.done);
2179 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 2039 return 1;
2180 2040 }
2181 return 1; 2041 return 0;
2182} 2042}
2183 2043
2184/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2044/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2901,6 +2761,16 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2901 unsigned long timeleft; 2761 unsigned long timeleft;
2902 unsigned long flags; 2762 unsigned long flags;
2903 2763
2764 /* don't send internal command during diag reset */
2765 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2766 if (ioc->ioc_reset_in_progress) {
2767 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2768 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2769 "%s: busy with host reset\n", ioc->name, __func__));
2770 return MPT_SCANDV_BUSY;
2771 }
2772 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2773
2904 mutex_lock(&ioc->internal_cmds.mutex); 2774 mutex_lock(&ioc->internal_cmds.mutex);
2905 2775
2906 /* Set command specific information 2776 /* Set command specific information
@@ -3360,6 +3230,5 @@ EXPORT_SYMBOL(mptscsih_event_process);
3360EXPORT_SYMBOL(mptscsih_ioc_reset); 3230EXPORT_SYMBOL(mptscsih_ioc_reset);
3361EXPORT_SYMBOL(mptscsih_change_queue_depth); 3231EXPORT_SYMBOL(mptscsih_change_queue_depth);
3362EXPORT_SYMBOL(mptscsih_timer_expired); 3232EXPORT_SYMBOL(mptscsih_timer_expired);
3363EXPORT_SYMBOL(mptscsih_TMHandler);
3364 3233
3365/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3234/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 0b103a2516ee..6ac5d4a5c4e8 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -113,6 +113,8 @@ extern int mptscsih_resume(struct pci_dev *pdev);
113extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); 113extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
114extern const char * mptscsih_info(struct Scsi_Host *SChost); 114extern const char * mptscsih_info(struct Scsi_Host *SChost);
115extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); 115extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
116extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
117 u8 id, int lun, int ctx2abort, ulong timeout);
116extern void mptscsih_slave_destroy(struct scsi_device *device); 118extern void mptscsih_slave_destroy(struct scsi_device *device);
117extern int mptscsih_slave_configure(struct scsi_device *device); 119extern int mptscsih_slave_configure(struct scsi_device *device);
118extern int mptscsih_abort(struct scsi_cmnd * SCpnt); 120extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
@@ -127,7 +129,6 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE
127extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 129extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
128extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); 130extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
129extern void mptscsih_timer_expired(unsigned long data); 131extern void mptscsih_timer_expired(unsigned long data);
130extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
131extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); 132extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
132extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); 133extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
133extern struct device_attribute *mptscsih_host_attrs[]; 134extern struct device_attribute *mptscsih_host_attrs[];
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 8f46fdff7f77..e94c76dbe780 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -1522,7 +1522,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1522 * issue internal bus reset 1522 * issue internal bus reset
1523 */ 1523 */
1524 if (ioc->spi_data.bus_reset) 1524 if (ioc->spi_data.bus_reset)
1525 mptscsih_TMHandler(hd, 1525 mptscsih_IssueTaskMgmt(hd,
1526 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1526 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1527 0, 0, 0, 0, 5); 1527 0, 0, 0, 0, 5);
1528 1528