aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-05-29 07:14:06 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-09 18:27:49 -0400
commit37c60f374a855974c27bd30d5662a8fa5e933792 (patch)
tree98e1ee9a5f54152a7dfaf9f320a87fde791f544e /drivers
parentf0f09d3b3f06900d64971625d6753dea0623ed45 (diff)
[SCSI] mpt fusion: rewrite of all internal generated functions
Rewrite of all internal generated functions that issue commands to firmware, porting them to be single threaded using the generic MPT_MGMT struct. Implemented using completion Queue. Signed-off-by: Kashyap Desai <kadesai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/message/fusion/mptbase.c2
-rw-r--r--drivers/message/fusion/mptbase.h5
-rw-r--r--drivers/message/fusion/mptfc.c2
-rw-r--r--drivers/message/fusion/mptsas.c2
-rw-r--r--drivers/message/fusion/mptscsih.c514
-rw-r--r--drivers/message/fusion/mptscsih.h1
-rw-r--r--drivers/message/fusion/mptspi.c52
7 files changed, 248 insertions, 330 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index e63a6260b0a0..d8d5231f484e 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1775,6 +1775,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1775 spin_lock_init(&ioc->diagLock); 1775 spin_lock_init(&ioc->diagLock);
1776 spin_lock_init(&ioc->initializing_hba_lock); 1776 spin_lock_init(&ioc->initializing_hba_lock);
1777 1777
1778 mutex_init(&ioc->internal_cmds.mutex);
1779 init_completion(&ioc->internal_cmds.done);
1778 mutex_init(&ioc->mptbase_cmds.mutex); 1780 mutex_init(&ioc->mptbase_cmds.mutex);
1779 init_completion(&ioc->mptbase_cmds.done); 1781 init_completion(&ioc->mptbase_cmds.done);
1780 1782
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 41273fff4b01..4d77256954f9 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -465,7 +465,9 @@ typedef struct _MPT_MGMT {
465 struct mutex mutex; 465 struct mutex mutex;
466 struct completion done; 466 struct completion done;
467 u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */ 467 u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
468 u8 sense[MPT_SENSE_BUFFER_ALLOC];
468 u8 status; /* current command status */ 469 u8 status; /* current command status */
470 int completion_code;
469} MPT_MGMT; 471} MPT_MGMT;
470 472
471/* 473/*
@@ -709,6 +711,7 @@ typedef struct _MPT_ADAPTER
709 int sas_index; /* index refrencing */ 711 int sas_index; /* index refrencing */
710 MPT_MGMT sas_mgmt; 712 MPT_MGMT sas_mgmt;
711 MPT_MGMT mptbase_cmds; /* for sending config pages */ 713 MPT_MGMT mptbase_cmds; /* for sending config pages */
714 MPT_MGMT internal_cmds;
712 struct work_struct sas_persist_task; 715 struct work_struct sas_persist_task;
713 716
714 struct work_struct fc_setup_reset_work; 717 struct work_struct fc_setup_reset_work;
@@ -863,8 +866,6 @@ typedef struct _MPT_SCSI_HOST {
863 unsigned long timeouts; /* cmd timeouts */ 866 unsigned long timeouts; /* cmd timeouts */
864 ushort sel_timeout[MPT_MAX_FC_DEVICES]; 867 ushort sel_timeout[MPT_MAX_FC_DEVICES];
865 char *info_kbuf; 868 char *info_kbuf;
866 wait_queue_head_t scandv_waitq;
867 int scandv_wait_done;
868 long last_queue_full; 869 long last_queue_full;
869 u16 tm_iocstatus; 870 u16 tm_iocstatus;
870 u16 spi_pending; 871 u16 spi_pending;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index da16b47a3f32..d09387134145 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -1310,8 +1310,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1310 hd->timer.data = (unsigned long) hd; 1310 hd->timer.data = (unsigned long) hd;
1311 hd->timer.function = mptscsih_timer_expired; 1311 hd->timer.function = mptscsih_timer_expired;
1312 1312
1313 init_waitqueue_head(&hd->scandv_waitq);
1314 hd->scandv_wait_done = 0;
1315 hd->last_queue_full = 0; 1313 hd->last_queue_full = 0;
1316 1314
1317 sh->transportt = mptfc_transport_template; 1315 sh->transportt = mptfc_transport_template;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index dc23adf9a30f..16c4232c37de 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -3282,8 +3282,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3282 3282
3283 ioc->sas_data.ptClear = mpt_pt_clear; 3283 ioc->sas_data.ptClear = mpt_pt_clear;
3284 3284
3285 init_waitqueue_head(&hd->scandv_waitq);
3286 hd->scandv_wait_done = 0;
3287 hd->last_queue_full = 0; 3285 hd->last_queue_full = 0;
3288 INIT_LIST_HEAD(&hd->target_reset_list); 3286 INIT_LIST_HEAD(&hd->target_reset_list);
3289 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 3287 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 8c08c73f194c..35173252e948 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -100,6 +100,8 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
100int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 100int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
101int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 101int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
102 102
103static int mptscsih_get_completion_code(MPT_ADAPTER *ioc,
104 MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
103int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 105int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
104static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 106static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
105static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); 107static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
@@ -2571,94 +2573,35 @@ int
2571mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) 2573mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2572{ 2574{
2573 MPT_SCSI_HOST *hd; 2575 MPT_SCSI_HOST *hd;
2574 unsigned long flags;
2575
2576 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2577 ": IOC %s_reset routed to SCSI host driver!\n",
2578 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2579 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2580 2576
2581 /* If a FW reload request arrives after base installed but
2582 * before all scsi hosts have been attached, then an alt_ioc
2583 * may have a NULL sh pointer.
2584 */
2585 if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL) 2577 if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2586 return 0; 2578 return 0;
2587 else
2588 hd = shost_priv(ioc->sh);
2589
2590 if (reset_phase == MPT_IOC_SETUP_RESET) {
2591 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Setup-Diag Reset\n", ioc->name));
2592 2579
2593 /* Clean Up: 2580 hd = shost_priv(ioc->sh);
2594 * 1. Set Hard Reset Pending Flag 2581 switch (reset_phase) {
2595 * All new commands go to doneQ 2582 case MPT_IOC_SETUP_RESET:
2596 */ 2583 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2584 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2597 hd->resetPending = 1; 2585 hd->resetPending = 1;
2598 2586 break;
2599 } else if (reset_phase == MPT_IOC_PRE_RESET) { 2587 case MPT_IOC_PRE_RESET:
2600 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Pre-Diag Reset\n", ioc->name)); 2588 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2601 2589 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2602 /* 2. Flush running commands
2603 * Clean ScsiLookup (and associated memory)
2604 * AND clean mytaskQ
2605 */
2606
2607 /* 2b. Reply to OS all known outstanding I/O commands.
2608 */
2609 mptscsih_flush_running_cmds(hd);
2610
2611 /* 2c. If there was an internal command that
2612 * has not completed, configuration or io request,
2613 * free these resources.
2614 */
2615 if (hd->cmdPtr) {
2616 del_timer(&hd->timer);
2617 mpt_free_msg_frame(ioc, hd->cmdPtr);
2618 }
2619
2620 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Pre-Reset complete.\n", ioc->name));
2621
2622 } else {
2623 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Post-Diag Reset\n", ioc->name));
2624
2625 /* Once a FW reload begins, all new OS commands are
2626 * redirected to the doneQ w/ a reset status.
2627 * Init all control structures.
2628 */
2629
2630 /* 2. Chain Buffer initialization
2631 */
2632
2633 /* 4. Renegotiate to all devices, if SPI
2634 */
2635
2636 /* 5. Enable new commands to be posted
2637 */
2638 spin_lock_irqsave(&ioc->FreeQlock, flags);
2639 hd->tmPending = 0;
2640 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2641 hd->resetPending = 0; 2590 hd->resetPending = 0;
2642 hd->tmState = TM_STATE_NONE; 2591 mptscsih_flush_running_cmds(hd);
2643 2592 break;
2644 /* 6. If there was an internal command, 2593 case MPT_IOC_POST_RESET:
2645 * wake this process up. 2594 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2646 */ 2595 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2647 if (hd->cmdPtr) { 2596 if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2648 /* 2597 ioc->internal_cmds.status |=
2649 * Wake up the original calling thread 2598 MPT_MGMT_STATUS_DID_IOCRESET;
2650 */ 2599 complete(&ioc->internal_cmds.done);
2651 hd->pLocal = &hd->localReply;
2652 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2653 hd->scandv_wait_done = 1;
2654 wake_up(&hd->scandv_waitq);
2655 hd->cmdPtr = NULL;
2656 } 2600 }
2657 2601 break;
2658 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Post-Reset complete.\n", ioc->name)); 2602 default:
2659 2603 break;
2660 } 2604 }
2661
2662 return 1; /* currently means nothing really */ 2605 return 1; /* currently means nothing really */
2663} 2606}
2664 2607
@@ -2669,8 +2612,9 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2669 MPT_SCSI_HOST *hd; 2612 MPT_SCSI_HOST *hd;
2670 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; 2613 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2671 2614
2672 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2615 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2673 ioc->name, event)); 2616 "MPT event (=%02Xh) routed to SCSI host driver!\n",
2617 ioc->name, event));
2674 2618
2675 if (ioc->sh == NULL || 2619 if (ioc->sh == NULL ||
2676 ((hd = shost_priv(ioc->sh)) == NULL)) 2620 ((hd = shost_priv(ioc->sh)) == NULL))
@@ -2711,8 +2655,9 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2711 case MPI_EVENT_STATE_CHANGE: /* 02 */ 2655 case MPI_EVENT_STATE_CHANGE: /* 02 */
2712 case MPI_EVENT_EVENT_CHANGE: /* 0A */ 2656 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2713 default: 2657 default:
2714 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": Ignoring event (=%02Xh)\n", 2658 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2715 ioc->name, event)); 2659 ": Ignoring event (=%02Xh)\n",
2660 ioc->name, event));
2716 break; 2661 break;
2717 } 2662 }
2718 2663
@@ -2745,153 +2690,44 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2745 * Used ONLY for DV and other internal commands. 2690 * Used ONLY for DV and other internal commands.
2746 */ 2691 */
2747int 2692int
2748mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 2693mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2694 MPT_FRAME_HDR *reply)
2749{ 2695{
2750 MPT_SCSI_HOST *hd;
2751 SCSIIORequest_t *pReq; 2696 SCSIIORequest_t *pReq;
2752 int completionCode; 2697 SCSIIOReply_t *pReply;
2698 u8 cmd;
2753 u16 req_idx; 2699 u16 req_idx;
2700 u8 *sense_data;
2701 int sz;
2754 2702
2755 hd = shost_priv(ioc->sh); 2703 ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2756 2704 ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2757 if ((mf == NULL) || 2705 if (!reply)
2758 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) { 2706 goto out;
2759 printk(MYIOC_s_ERR_FMT
2760 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2761 ioc->name, mf?"BAD":"NULL", (void *) mf);
2762 goto wakeup;
2763 }
2764
2765 del_timer(&hd->timer);
2766 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2767 mptscsih_set_scsi_lookup(ioc, req_idx, NULL);
2768 pReq = (SCSIIORequest_t *) mf;
2769 2707
2770 if (mf != hd->cmdPtr) { 2708 pReply = (SCSIIOReply_t *) reply;
2771 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n", 2709 pReq = (SCSIIORequest_t *) req;
2772 ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx); 2710 ioc->internal_cmds.completion_code =
2711 mptscsih_get_completion_code(ioc, req, reply);
2712 ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2713 memcpy(ioc->internal_cmds.reply, reply,
2714 min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2715 cmd = reply->u.hdr.Function;
2716 if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2717 (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2718 (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2719 req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2720 sense_data = ((u8 *)ioc->sense_buf_pool +
2721 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2722 sz = min_t(int, pReq->SenseBufferLength,
2723 MPT_SENSE_BUFFER_ALLOC);
2724 memcpy(ioc->internal_cmds.sense, sense_data, sz);
2773 } 2725 }
2774 hd->cmdPtr = NULL; 2726 out:
2775 2727 if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2776 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n", 2728 return 0;
2777 ioc->name, mf, mr, req_idx)); 2729 ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2778 2730 complete(&ioc->internal_cmds.done);
2779 hd->pLocal = &hd->localReply;
2780 hd->pLocal->scsiStatus = 0;
2781
2782 /* If target struct exists, clear sense valid flag.
2783 */
2784 if (mr == NULL) {
2785 completionCode = MPT_SCANDV_GOOD;
2786 } else {
2787 SCSIIOReply_t *pReply;
2788 u16 status;
2789 u8 scsi_status;
2790
2791 pReply = (SCSIIOReply_t *) mr;
2792
2793 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2794 scsi_status = pReply->SCSIStatus;
2795
2796
2797 switch(status) {
2798
2799 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2800 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2801 break;
2802
2803 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2804 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2805 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2806 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2807 completionCode = MPT_SCANDV_DID_RESET;
2808 break;
2809
2810 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2811 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2812 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2813 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2814 ConfigReply_t *pr = (ConfigReply_t *)mr;
2815 completionCode = MPT_SCANDV_GOOD;
2816 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2817 hd->pLocal->header.PageLength = pr->Header.PageLength;
2818 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2819 hd->pLocal->header.PageType = pr->Header.PageType;
2820
2821 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2822 /* If the RAID Volume request is successful,
2823 * return GOOD, else indicate that
2824 * some type of error occurred.
2825 */
2826 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
2827 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2828 completionCode = MPT_SCANDV_GOOD;
2829 else
2830 completionCode = MPT_SCANDV_SOME_ERROR;
2831 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2832
2833 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2834 u8 *sense_data;
2835 int sz;
2836
2837 /* save sense data in global structure
2838 */
2839 completionCode = MPT_SCANDV_SENSE;
2840 hd->pLocal->scsiStatus = scsi_status;
2841 sense_data = ((u8 *)ioc->sense_buf_pool +
2842 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2843
2844 sz = min_t(int, pReq->SenseBufferLength,
2845 SCSI_STD_SENSE_BYTES);
2846 memcpy(hd->pLocal->sense, sense_data, sz);
2847
2848 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Check Condition, sense ptr %p\n",
2849 ioc->name, sense_data));
2850 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2851 if (pReq->CDB[0] == INQUIRY)
2852 completionCode = MPT_SCANDV_ISSUE_SENSE;
2853 else
2854 completionCode = MPT_SCANDV_DID_RESET;
2855 }
2856 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2857 completionCode = MPT_SCANDV_DID_RESET;
2858 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2859 completionCode = MPT_SCANDV_DID_RESET;
2860 else {
2861 completionCode = MPT_SCANDV_GOOD;
2862 hd->pLocal->scsiStatus = scsi_status;
2863 }
2864 break;
2865
2866 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2867 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2868 completionCode = MPT_SCANDV_DID_RESET;
2869 else
2870 completionCode = MPT_SCANDV_SOME_ERROR;
2871 break;
2872
2873 default:
2874 completionCode = MPT_SCANDV_SOME_ERROR;
2875 break;
2876
2877 } /* switch(status) */
2878
2879 } /* end of address reply case */
2880
2881 hd->pLocal->completion = completionCode;
2882
2883 /* MF and RF are freed in mpt_interrupt
2884 */
2885wakeup:
2886 /* Free Chain buffers (will never chain) in scan or dv */
2887 //mptscsih_freeChainBuffers(ioc, req_idx);
2888
2889 /*
2890 * Wake up the original calling thread
2891 */
2892 hd->scandv_wait_done = 1;
2893 wake_up(&hd->scandv_waitq);
2894
2895 return 1; 2731 return 1;
2896} 2732}
2897 2733
@@ -2940,6 +2776,95 @@ mptscsih_timer_expired(unsigned long data)
2940 return; 2776 return;
2941} 2777}
2942 2778
2779/**
2780 * mptscsih_get_completion_code -
2781 * @ioc: Pointer to MPT_ADAPTER structure
2782 * @reply:
2783 * @cmd:
2784 *
2785 **/
2786static int
2787mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2788 MPT_FRAME_HDR *reply)
2789{
2790 SCSIIOReply_t *pReply;
2791 MpiRaidActionReply_t *pr;
2792 u8 scsi_status;
2793 u16 status;
2794 int completion_code;
2795
2796 pReply = (SCSIIOReply_t *)reply;
2797 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2798 scsi_status = pReply->SCSIStatus;
2799
2800 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2801 "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2802 "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2803 scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2804
2805 switch (status) {
2806
2807 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2808 completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2809 break;
2810
2811 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2812 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2813 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2814 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2815 completion_code = MPT_SCANDV_DID_RESET;
2816 break;
2817
2818 case MPI_IOCSTATUS_BUSY:
2819 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2820 completion_code = MPT_SCANDV_BUSY;
2821 break;
2822
2823 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2824 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2825 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2826 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2827 completion_code = MPT_SCANDV_GOOD;
2828 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2829 pr = (MpiRaidActionReply_t *)reply;
2830 if (le16_to_cpu(pr->ActionStatus) ==
2831 MPI_RAID_ACTION_ASTATUS_SUCCESS)
2832 completion_code = MPT_SCANDV_GOOD;
2833 else
2834 completion_code = MPT_SCANDV_SOME_ERROR;
2835 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2836 completion_code = MPT_SCANDV_SENSE;
2837 else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2838 if (req->u.scsireq.CDB[0] == INQUIRY)
2839 completion_code = MPT_SCANDV_ISSUE_SENSE;
2840 else
2841 completion_code = MPT_SCANDV_DID_RESET;
2842 } else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2843 completion_code = MPT_SCANDV_DID_RESET;
2844 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2845 completion_code = MPT_SCANDV_DID_RESET;
2846 else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2847 completion_code = MPT_SCANDV_BUSY;
2848 else
2849 completion_code = MPT_SCANDV_GOOD;
2850 break;
2851
2852 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2853 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2854 completion_code = MPT_SCANDV_DID_RESET;
2855 else
2856 completion_code = MPT_SCANDV_SOME_ERROR;
2857 break;
2858 default:
2859 completion_code = MPT_SCANDV_SOME_ERROR;
2860 break;
2861
2862 } /* switch(status) */
2863
2864 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2865 " completionCode set to %08xh\n", ioc->name, completion_code));
2866 return completion_code;
2867}
2943 2868
2944/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2869/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2945/** 2870/**
@@ -2966,22 +2891,17 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2966{ 2891{
2967 MPT_FRAME_HDR *mf; 2892 MPT_FRAME_HDR *mf;
2968 SCSIIORequest_t *pScsiReq; 2893 SCSIIORequest_t *pScsiReq;
2969 SCSIIORequest_t ReqCopy;
2970 int my_idx, ii, dir; 2894 int my_idx, ii, dir;
2971 int rc, cmdTimeout; 2895 int timeout;
2972 int in_isr;
2973 char cmdLen; 2896 char cmdLen;
2974 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 2897 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2975 char cmd = io->cmd; 2898 u8 cmd = io->cmd;
2976 MPT_ADAPTER *ioc = hd->ioc; 2899 MPT_ADAPTER *ioc = hd->ioc;
2977 2900 int ret = 0;
2978 in_isr = in_interrupt(); 2901 unsigned long timeleft;
2979 if (in_isr) { 2902 unsigned long flags;
2980 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2981 ioc->name));
2982 return -EPERM;
2983 }
2984 2903
2904 mutex_lock(&ioc->internal_cmds.mutex);
2985 2905
2986 /* Set command specific information 2906 /* Set command specific information
2987 */ 2907 */
@@ -2991,13 +2911,13 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2991 dir = MPI_SCSIIO_CONTROL_READ; 2911 dir = MPI_SCSIIO_CONTROL_READ;
2992 CDB[0] = cmd; 2912 CDB[0] = cmd;
2993 CDB[4] = io->size; 2913 CDB[4] = io->size;
2994 cmdTimeout = 10; 2914 timeout = 10;
2995 break; 2915 break;
2996 2916
2997 case TEST_UNIT_READY: 2917 case TEST_UNIT_READY:
2998 cmdLen = 6; 2918 cmdLen = 6;
2999 dir = MPI_SCSIIO_CONTROL_READ; 2919 dir = MPI_SCSIIO_CONTROL_READ;
3000 cmdTimeout = 10; 2920 timeout = 10;
3001 break; 2921 break;
3002 2922
3003 case START_STOP: 2923 case START_STOP:
@@ -3005,7 +2925,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3005 dir = MPI_SCSIIO_CONTROL_READ; 2925 dir = MPI_SCSIIO_CONTROL_READ;
3006 CDB[0] = cmd; 2926 CDB[0] = cmd;
3007 CDB[4] = 1; /*Spin up the disk */ 2927 CDB[4] = 1; /*Spin up the disk */
3008 cmdTimeout = 15; 2928 timeout = 15;
3009 break; 2929 break;
3010 2930
3011 case REQUEST_SENSE: 2931 case REQUEST_SENSE:
@@ -3013,7 +2933,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3013 CDB[0] = cmd; 2933 CDB[0] = cmd;
3014 CDB[4] = io->size; 2934 CDB[4] = io->size;
3015 dir = MPI_SCSIIO_CONTROL_READ; 2935 dir = MPI_SCSIIO_CONTROL_READ;
3016 cmdTimeout = 10; 2936 timeout = 10;
3017 break; 2937 break;
3018 2938
3019 case READ_BUFFER: 2939 case READ_BUFFER:
@@ -3032,7 +2952,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3032 CDB[6] = (io->size >> 16) & 0xFF; 2952 CDB[6] = (io->size >> 16) & 0xFF;
3033 CDB[7] = (io->size >> 8) & 0xFF; 2953 CDB[7] = (io->size >> 8) & 0xFF;
3034 CDB[8] = io->size & 0xFF; 2954 CDB[8] = io->size & 0xFF;
3035 cmdTimeout = 10; 2955 timeout = 10;
3036 break; 2956 break;
3037 2957
3038 case WRITE_BUFFER: 2958 case WRITE_BUFFER:
@@ -3047,21 +2967,21 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3047 CDB[6] = (io->size >> 16) & 0xFF; 2967 CDB[6] = (io->size >> 16) & 0xFF;
3048 CDB[7] = (io->size >> 8) & 0xFF; 2968 CDB[7] = (io->size >> 8) & 0xFF;
3049 CDB[8] = io->size & 0xFF; 2969 CDB[8] = io->size & 0xFF;
3050 cmdTimeout = 10; 2970 timeout = 10;
3051 break; 2971 break;
3052 2972
3053 case RESERVE: 2973 case RESERVE:
3054 cmdLen = 6; 2974 cmdLen = 6;
3055 dir = MPI_SCSIIO_CONTROL_READ; 2975 dir = MPI_SCSIIO_CONTROL_READ;
3056 CDB[0] = cmd; 2976 CDB[0] = cmd;
3057 cmdTimeout = 10; 2977 timeout = 10;
3058 break; 2978 break;
3059 2979
3060 case RELEASE: 2980 case RELEASE:
3061 cmdLen = 6; 2981 cmdLen = 6;
3062 dir = MPI_SCSIIO_CONTROL_READ; 2982 dir = MPI_SCSIIO_CONTROL_READ;
3063 CDB[0] = cmd; 2983 CDB[0] = cmd;
3064 cmdTimeout = 10; 2984 timeout = 10;
3065 break; 2985 break;
3066 2986
3067 case SYNCHRONIZE_CACHE: 2987 case SYNCHRONIZE_CACHE:
@@ -3069,20 +2989,23 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3069 dir = MPI_SCSIIO_CONTROL_READ; 2989 dir = MPI_SCSIIO_CONTROL_READ;
3070 CDB[0] = cmd; 2990 CDB[0] = cmd;
3071// CDB[1] = 0x02; /* set immediate bit */ 2991// CDB[1] = 0x02; /* set immediate bit */
3072 cmdTimeout = 10; 2992 timeout = 10;
3073 break; 2993 break;
3074 2994
3075 default: 2995 default:
3076 /* Error Case */ 2996 /* Error Case */
3077 return -EFAULT; 2997 ret = -EFAULT;
2998 goto out;
3078 } 2999 }
3079 3000
3080 /* Get and Populate a free Frame 3001 /* Get and Populate a free Frame
3002 * MsgContext set in mpt_get_msg_frame call
3081 */ 3003 */
3082 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { 3004 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
3083 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "No msg frames!\n", 3005 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
3084 ioc->name)); 3006 ioc->name, __func__));
3085 return -EBUSY; 3007 ret = MPT_SCANDV_BUSY;
3008 goto out;
3086 } 3009 }
3087 3010
3088 pScsiReq = (SCSIIORequest_t *) mf; 3011 pScsiReq = (SCSIIORequest_t *) mf;
@@ -3120,74 +3043,58 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3120 3043
3121 if (cmd == REQUEST_SENSE) { 3044 if (cmd == REQUEST_SENSE) {
3122 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED); 3045 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3123 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Untagged! 0x%2x\n", 3046 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3124 ioc->name, cmd)); 3047 "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
3125 } 3048 }
3126 3049
3127 for (ii=0; ii < 16; ii++) 3050 for (ii = 0; ii < 16; ii++)
3128 pScsiReq->CDB[ii] = CDB[ii]; 3051 pScsiReq->CDB[ii] = CDB[ii];
3129 3052
3130 pScsiReq->DataLength = cpu_to_le32(io->size); 3053 pScsiReq->DataLength = cpu_to_le32(io->size);
3131 pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma 3054 pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
3132 + (my_idx * MPT_SENSE_BUFFER_ALLOC)); 3055 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3133 3056
3134 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Command 0x%x for (%d:%d:%d)\n", 3057 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3135 ioc->name, cmd, io->channel, io->id, io->lun)); 3058 "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%d\n",
3059 ioc->name, __func__, cmd, io->channel, io->id, io->lun));
3136 3060
3137 if (dir == MPI_SCSIIO_CONTROL_READ) { 3061 if (dir == MPI_SCSIIO_CONTROL_READ)
3138 ioc->add_sge((char *) &pScsiReq->SGL, 3062 ioc->add_sge((char *) &pScsiReq->SGL,
3139 MPT_SGE_FLAGS_SSIMPLE_READ | io->size, 3063 MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
3140 io->data_dma); 3064 else
3141 } else {
3142 ioc->add_sge((char *) &pScsiReq->SGL, 3065 ioc->add_sge((char *) &pScsiReq->SGL,
3143 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, 3066 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
3144 io->data_dma);
3145 }
3146
3147 /* The ISR will free the request frame, but we need
3148 * the information to initialize the target. Duplicate.
3149 */
3150 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3151
3152 /* Issue this command after:
3153 * finish init
3154 * add timer
3155 * Wait until the reply has been received
3156 * ScsiScanDvCtx callback function will
3157 * set hd->pLocal;
3158 * set scandv_wait_done and call wake_up
3159 */
3160 hd->pLocal = NULL;
3161 hd->timer.expires = jiffies + HZ*cmdTimeout;
3162 hd->scandv_wait_done = 0;
3163 3067
3164 /* Save cmd pointer, for resource free if timeout or 3068 INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
3165 * FW reload occurs
3166 */
3167 hd->cmdPtr = mf;
3168
3169 add_timer(&hd->timer);
3170 mpt_put_msg_frame(ioc->InternalCtx, ioc, mf); 3069 mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
3171 wait_event(hd->scandv_waitq, hd->scandv_wait_done); 3070 timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
3172 3071 timeout*HZ);
3173 if (hd->pLocal) { 3072 if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
3174 rc = hd->pLocal->completion; 3073 ret = MPT_SCANDV_DID_RESET;
3175 hd->pLocal->skip = 0; 3074 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3176 3075 "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
3177 /* Always set fatal error codes in some cases. 3076 cmd));
3178 */ 3077 if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
3179 if (rc == MPT_SCANDV_SELECTION_TIMEOUT) 3078 mpt_free_msg_frame(ioc, mf);
3180 rc = -ENXIO; 3079 goto out;
3181 else if (rc == MPT_SCANDV_SOME_ERROR) 3080 }
3182 rc = -rc; 3081 if (!timeleft) {
3183 } else { 3082 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
3184 rc = -EFAULT; 3083 ioc->name, __func__);
3185 /* This should never happen. */ 3084 mpt_HardResetHandler(ioc, CAN_SLEEP);
3186 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "_do_cmd: Null pLocal!!!\n", 3085 mpt_free_msg_frame(ioc, mf);
3187 ioc->name)); 3086 }
3087 goto out;
3188 } 3088 }
3189 3089
3190 return rc; 3090 ret = ioc->internal_cmds.completion_code;
3091 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
3092 ioc->name, __func__, ret));
3093
3094 out:
3095 CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
3096 mutex_unlock(&ioc->internal_cmds.mutex);
3097 return ret;
3191} 3098}
3192 3099
3193/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3100/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -3427,6 +3334,7 @@ struct device_attribute *mptscsih_host_attrs[] = {
3427 &dev_attr_debug_level, 3334 &dev_attr_debug_level,
3428 NULL, 3335 NULL,
3429}; 3336};
3337
3430EXPORT_SYMBOL(mptscsih_host_attrs); 3338EXPORT_SYMBOL(mptscsih_host_attrs);
3431 3339
3432EXPORT_SYMBOL(mptscsih_remove); 3340EXPORT_SYMBOL(mptscsih_remove);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 319aa3033371..0b103a2516ee 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -60,6 +60,7 @@
60#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008) 60#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
61#define MPT_SCANDV_ISSUE_SENSE (0x00000010) 61#define MPT_SCANDV_ISSUE_SENSE (0x00000010)
62#define MPT_SCANDV_FALLBACK (0x00000020) 62#define MPT_SCANDV_FALLBACK (0x00000020)
63#define MPT_SCANDV_BUSY (0x00000040)
63 64
64#define MPT_SCANDV_MAX_RETRIES (10) 65#define MPT_SCANDV_MAX_RETRIES (10)
65 66
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 643a3c6443af..8f46fdff7f77 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -614,19 +614,24 @@ static void mptspi_read_parameters(struct scsi_target *starget)
614 spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0; 614 spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0;
615} 615}
616 616
617static int 617int
618mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id) 618mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
619{ 619{
620 MPT_ADAPTER *ioc = hd->ioc;
620 MpiRaidActionRequest_t *pReq; 621 MpiRaidActionRequest_t *pReq;
621 MPT_FRAME_HDR *mf; 622 MPT_FRAME_HDR *mf;
622 MPT_ADAPTER *ioc = hd->ioc; 623 int ret;
624 unsigned long timeleft;
625
626 mutex_lock(&ioc->internal_cmds.mutex);
623 627
624 /* Get and Populate a free Frame 628 /* Get and Populate a free Frame
625 */ 629 */
626 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { 630 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
627 ddvprintk(ioc, printk(MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n", 631 dfailprintk(hd->ioc, printk(MYIOC_s_WARN_FMT
628 ioc->name)); 632 "%s: no msg frames!\n", ioc->name, __func__));
629 return -EAGAIN; 633 ret = -EAGAIN;
634 goto out;
630 } 635 }
631 pReq = (MpiRaidActionRequest_t *)mf; 636 pReq = (MpiRaidActionRequest_t *)mf;
632 if (quiesce) 637 if (quiesce)
@@ -649,23 +654,30 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
649 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n", 654 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n",
650 ioc->name, pReq->Action, channel, id)); 655 ioc->name, pReq->Action, channel, id));
651 656
652 hd->pLocal = NULL; 657 INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
653 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
654 hd->scandv_wait_done = 0;
655
656 /* Save cmd pointer, for resource free if timeout or
657 * FW reload occurs
658 */
659 hd->cmdPtr = mf;
660
661 add_timer(&hd->timer);
662 mpt_put_msg_frame(ioc->InternalCtx, ioc, mf); 658 mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
663 wait_event(hd->scandv_waitq, hd->scandv_wait_done); 659 timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done, 10*HZ);
660 if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
661 ret = -ETIME;
662 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: TIMED OUT!\n",
663 ioc->name, __func__));
664 if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
665 goto out;
666 if (!timeleft) {
667 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
668 ioc->name, __func__);
669 mpt_HardResetHandler(ioc, CAN_SLEEP);
670 mpt_free_msg_frame(ioc, mf);
671 }
672 goto out;
673 }
664 674
665 if ((hd->pLocal == NULL) || (hd->pLocal->completion != 0)) 675 ret = ioc->internal_cmds.completion_code;
666 return -1;
667 676
668 return 0; 677 out:
678 CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
679 mutex_unlock(&ioc->internal_cmds.mutex);
680 return ret;
669} 681}
670 682
671static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, 683static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
@@ -1491,8 +1503,6 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1491 mpt_saf_te)); 1503 mpt_saf_te));
1492 ioc->spi_data.noQas = 0; 1504 ioc->spi_data.noQas = 0;
1493 1505
1494 init_waitqueue_head(&hd->scandv_waitq);
1495 hd->scandv_wait_done = 0;
1496 hd->last_queue_full = 0; 1506 hd->last_queue_full = 0;
1497 hd->spi_pending = 0; 1507 hd->spi_pending = 0;
1498 1508