diff options
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 14 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 19 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 137 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 9 |
4 files changed, 89 insertions, 90 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 25f2650f098c..e16025d76aa2 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
| @@ -180,15 +180,11 @@ struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, | |||
| 180 | int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | 180 | int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, |
| 181 | uint32_t timeout); | 181 | uint32_t timeout); |
| 182 | 182 | ||
| 183 | int lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba, | 183 | int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, |
| 184 | struct lpfc_sli_ring * pring, | 184 | struct lpfc_sli_ring * pring, |
| 185 | struct lpfc_iocbq * piocb, | 185 | struct lpfc_iocbq * piocb, |
| 186 | uint32_t flag, | 186 | struct lpfc_iocbq * prspiocbq, |
| 187 | struct lpfc_iocbq * prspiocbq, | 187 | uint32_t timeout); |
| 188 | uint32_t timeout); | ||
| 189 | void lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba, | ||
| 190 | struct lpfc_iocbq * queue1, | ||
| 191 | struct lpfc_iocbq * queue2); | ||
| 192 | void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, | 188 | void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, |
| 193 | struct lpfc_iocbq * cmdiocb, | 189 | struct lpfc_iocbq * cmdiocb, |
| 194 | struct lpfc_iocbq * rspiocb); | 190 | struct lpfc_iocbq * rspiocb); |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 51c6b677490c..c993069a6500 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
| @@ -637,12 +637,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) | |||
| 637 | if (!iocbqrsp) | 637 | if (!iocbqrsp) |
| 638 | return FAILED; | 638 | return FAILED; |
| 639 | 639 | ||
| 640 | iocbq->iocb_flag |= LPFC_IO_POLL; | 640 | ret = lpfc_sli_issue_iocb_wait(phba, |
| 641 | ret = lpfc_sli_issue_iocb_wait_high_priority(phba, | 641 | &phba->sli.ring[phba->sli.fcp_ring], |
| 642 | &phba->sli.ring[phba->sli.fcp_ring], | 642 | iocbq, iocbqrsp, lpfc_cmd->timeout); |
| 643 | iocbq, SLI_IOCB_HIGH_PRIORITY, | ||
| 644 | iocbqrsp, | ||
| 645 | lpfc_cmd->timeout); | ||
| 646 | if (ret != IOCB_SUCCESS) { | 643 | if (ret != IOCB_SUCCESS) { |
| 647 | lpfc_cmd->status = IOSTAT_DRIVER_REJECT; | 644 | lpfc_cmd->status = IOSTAT_DRIVER_REJECT; |
| 648 | ret = FAILED; | 645 | ret = FAILED; |
| @@ -922,7 +919,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
| 922 | { | 919 | { |
| 923 | struct Scsi_Host *shost = cmnd->device->host; | 920 | struct Scsi_Host *shost = cmnd->device->host; |
| 924 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; | 921 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; |
| 925 | struct lpfc_sli *psli = &phba->sli; | ||
| 926 | struct lpfc_scsi_buf *lpfc_cmd = NULL; | 922 | struct lpfc_scsi_buf *lpfc_cmd = NULL; |
| 927 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; | 923 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; |
| 928 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | 924 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; |
| @@ -969,12 +965,9 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
| 969 | if (iocbqrsp == NULL) | 965 | if (iocbqrsp == NULL) |
| 970 | goto out_free_scsi_buf; | 966 | goto out_free_scsi_buf; |
| 971 | 967 | ||
| 972 | iocbq->iocb_flag |= LPFC_IO_POLL; | 968 | ret = lpfc_sli_issue_iocb_wait(phba, |
| 973 | iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority; | 969 | &phba->sli.ring[phba->sli.fcp_ring], |
| 974 | 970 | iocbq, iocbqrsp, lpfc_cmd->timeout); | |
| 975 | ret = lpfc_sli_issue_iocb_wait_high_priority(phba, | ||
| 976 | &phba->sli.ring[psli->fcp_ring], | ||
| 977 | iocbq, 0, iocbqrsp, 60); | ||
| 978 | if (ret == IOCB_SUCCESS) | 971 | if (ret == IOCB_SUCCESS) |
| 979 | ret = SUCCESS; | 972 | ret = SUCCESS; |
| 980 | 973 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a8097e6c9dce..e09398dbe779 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
| @@ -839,9 +839,6 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, | |||
| 839 | spin_lock_irqsave(phba->host->host_lock, iflag); | 839 | spin_lock_irqsave(phba->host->host_lock, iflag); |
| 840 | } | 840 | } |
| 841 | else { | 841 | else { |
| 842 | if (cmdiocbp->iocb_flag & LPFC_IO_POLL) | ||
| 843 | rc = 0; | ||
| 844 | |||
| 845 | spin_unlock_irqrestore(phba->host->host_lock, | 842 | spin_unlock_irqrestore(phba->host->host_lock, |
| 846 | iflag); | 843 | iflag); |
| 847 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | 844 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); |
| @@ -874,6 +871,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, | |||
| 874 | saveq->iocb.ulpContext); | 871 | saveq->iocb.ulpContext); |
| 875 | } | 872 | } |
| 876 | } | 873 | } |
| 874 | |||
| 877 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 875 | spin_unlock_irqrestore(phba->host->host_lock, iflag); |
| 878 | return rc; | 876 | return rc; |
| 879 | } | 877 | } |
| @@ -2592,84 +2590,99 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
| 2592 | return errcnt; | 2590 | return errcnt; |
| 2593 | } | 2591 | } |
| 2594 | 2592 | ||
| 2595 | void | 2593 | static void |
| 2596 | lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba, | 2594 | lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, |
| 2597 | struct lpfc_iocbq * queue1, | 2595 | struct lpfc_iocbq *cmdiocbq, |
| 2598 | struct lpfc_iocbq * queue2) | 2596 | struct lpfc_iocbq *rspiocbq) |
| 2599 | { | 2597 | { |
| 2600 | struct lpfc_iocbq *save_iocbq = queue1->context2; | 2598 | wait_queue_head_t *pdone_q; |
| 2601 | if (save_iocbq && queue2) | 2599 | unsigned long iflags; |
| 2602 | memcpy(&save_iocbq->iocb, &queue2->iocb, sizeof(queue2->iocb)); | ||
| 2603 | 2600 | ||
| 2604 | /* The waiter is looking for LPFC_IO_HIPRI bit to be set | 2601 | spin_lock_irqsave(phba->host->host_lock, iflags); |
| 2605 | as a signal to wake up */ | 2602 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; |
| 2606 | queue1->iocb_flag |= LPFC_IO_HIPRI; | 2603 | if (cmdiocbq->context2 && rspiocbq) |
| 2604 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, | ||
| 2605 | &rspiocbq->iocb, sizeof(IOCB_t)); | ||
| 2606 | |||
| 2607 | pdone_q = cmdiocbq->context_un.wait_queue; | ||
| 2608 | spin_unlock_irqrestore(phba->host->host_lock, iflags); | ||
| 2609 | if (pdone_q) | ||
| 2610 | wake_up(pdone_q); | ||
| 2607 | return; | 2611 | return; |
| 2608 | } | 2612 | } |
| 2609 | 2613 | ||
| 2614 | /* | ||
| 2615 | * Issue the caller's iocb and wait for its completion, but no longer than the | ||
| 2616 | * caller's timeout. Note that iocb_flags is cleared before the | ||
| 2617 | * lpfc_sli_issue_call since the wake routine sets a unique value and by | ||
| 2618 | * definition this is a wait function. | ||
| 2619 | */ | ||
| 2610 | int | 2620 | int |
| 2611 | lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba, | 2621 | lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, |
| 2612 | struct lpfc_sli_ring * pring, | 2622 | struct lpfc_sli_ring * pring, |
| 2613 | struct lpfc_iocbq * piocb, | 2623 | struct lpfc_iocbq * piocb, |
| 2614 | uint32_t flag, | 2624 | struct lpfc_iocbq * prspiocbq, |
| 2615 | struct lpfc_iocbq * prspiocbq, | 2625 | uint32_t timeout) |
| 2616 | uint32_t timeout) | ||
| 2617 | { | 2626 | { |
| 2618 | int j, delay_time, retval = IOCB_ERROR; | 2627 | DECLARE_WAIT_QUEUE_HEAD(done_q); |
| 2619 | 2628 | long timeleft, timeout_req = 0; | |
| 2620 | /* The caller must left context1 empty. */ | 2629 | int retval = IOCB_SUCCESS; |
| 2621 | if (piocb->context_un.hipri_wait_queue != 0) { | ||
| 2622 | return IOCB_ERROR; | ||
| 2623 | } | ||
| 2624 | 2630 | ||
| 2625 | /* | 2631 | /* |
| 2626 | * If the caller has provided a response iocbq buffer, context2 must | 2632 | * If the caller has provided a response iocbq buffer, then context2 |
| 2627 | * be NULL or its an error. | 2633 | * is NULL or its an error. |
| 2628 | */ | 2634 | */ |
| 2629 | if (prspiocbq && piocb->context2) { | 2635 | if (prspiocbq) { |
| 2630 | return IOCB_ERROR; | 2636 | if (piocb->context2) |
| 2637 | return IOCB_ERROR; | ||
| 2638 | piocb->context2 = prspiocbq; | ||
| 2631 | } | 2639 | } |
| 2632 | 2640 | ||
| 2633 | piocb->context2 = prspiocbq; | 2641 | piocb->iocb_cmpl = lpfc_sli_wake_iocb_wait; |
| 2634 | 2642 | piocb->context_un.wait_queue = &done_q; | |
| 2635 | /* Setup callback routine and issue the command. */ | 2643 | piocb->iocb_flag &= ~LPFC_IO_WAKE; |
| 2636 | piocb->iocb_cmpl = lpfc_sli_wake_iocb_high_priority; | ||
| 2637 | retval = lpfc_sli_issue_iocb(phba, pring, piocb, | ||
| 2638 | flag | SLI_IOCB_HIGH_PRIORITY); | ||
| 2639 | if (retval != IOCB_SUCCESS) { | ||
| 2640 | piocb->context2 = NULL; | ||
| 2641 | return IOCB_ERROR; | ||
| 2642 | } | ||
| 2643 | 2644 | ||
| 2644 | /* | 2645 | retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0); |
| 2645 | * This high-priority iocb was sent out-of-band. Poll for its | 2646 | if (retval == IOCB_SUCCESS) { |
| 2646 | * completion rather than wait for a signal. Note that the host_lock | 2647 | timeout_req = timeout * HZ; |
| 2647 | * is held by the midlayer and must be released here to allow the | 2648 | spin_unlock_irq(phba->host->host_lock); |
| 2648 | * interrupt handlers to complete the IO and signal this routine via | 2649 | timeleft = wait_event_timeout(done_q, |
| 2649 | * the iocb_flag. | 2650 | piocb->iocb_flag & LPFC_IO_WAKE, |
| 2650 | * Also, the delay_time is computed to be one second longer than | 2651 | timeout_req); |
| 2651 | * the scsi command timeout to give the FW time to abort on | 2652 | spin_lock_irq(phba->host->host_lock); |
| 2652 | * timeout rather than the driver just giving up. Typically, | ||
| 2653 | * the midlayer does not specify a time for this command so the | ||
| 2654 | * driver is free to enforce its own timeout. | ||
| 2655 | */ | ||
| 2656 | 2653 | ||
| 2657 | delay_time = ((timeout + 1) * 1000) >> 6; | 2654 | if (timeleft == 0) { |
| 2658 | retval = IOCB_ERROR; | 2655 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
| 2659 | spin_unlock_irq(phba->host->host_lock); | 2656 | "%d:0329 IOCB wait timeout error - no " |
| 2660 | for (j = 0; j < 64; j++) { | 2657 | "wake response Data x%x\n", |
| 2661 | msleep(delay_time); | 2658 | phba->brd_no, timeout); |
| 2662 | if (piocb->iocb_flag & LPFC_IO_HIPRI) { | 2659 | retval = IOCB_TIMEDOUT; |
| 2663 | piocb->iocb_flag &= ~LPFC_IO_HIPRI; | 2660 | } else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) { |
| 2664 | retval = IOCB_SUCCESS; | 2661 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
| 2665 | break; | 2662 | "%d:0330 IOCB wake NOT set, " |
| 2663 | "Data x%x x%lx\n", phba->brd_no, | ||
| 2664 | timeout, (timeleft / jiffies)); | ||
| 2665 | retval = IOCB_TIMEDOUT; | ||
| 2666 | } else { | ||
| 2667 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
| 2668 | "%d:0331 IOCB wake signaled\n", | ||
| 2669 | phba->brd_no); | ||
| 2666 | } | 2670 | } |
| 2671 | } else { | ||
| 2672 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
| 2673 | "%d:0332 IOCB wait issue failed, Data x%x\n", | ||
| 2674 | phba->brd_no, retval); | ||
| 2675 | retval = IOCB_ERROR; | ||
| 2667 | } | 2676 | } |
| 2668 | 2677 | ||
| 2669 | spin_lock_irq(phba->host->host_lock); | 2678 | if (prspiocbq) |
| 2670 | piocb->context2 = NULL; | 2679 | piocb->context2 = NULL; |
| 2680 | |||
| 2681 | piocb->context_un.wait_queue = NULL; | ||
| 2682 | piocb->iocb_cmpl = NULL; | ||
| 2671 | return retval; | 2683 | return retval; |
| 2672 | } | 2684 | } |
| 2685 | |||
| 2673 | int | 2686 | int |
| 2674 | lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | 2687 | lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, |
| 2675 | uint32_t timeout) | 2688 | uint32_t timeout) |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 5d8911de4faa..9f1b85bed5a7 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
| @@ -39,10 +39,8 @@ struct lpfc_iocbq { | |||
| 39 | IOCB_t iocb; /* IOCB cmd */ | 39 | IOCB_t iocb; /* IOCB cmd */ |
| 40 | uint8_t retry; /* retry counter for IOCB cmd - if needed */ | 40 | uint8_t retry; /* retry counter for IOCB cmd - if needed */ |
| 41 | uint8_t iocb_flag; | 41 | uint8_t iocb_flag; |
| 42 | #define LPFC_IO_POLL 1 /* Polling mode iocb */ | 42 | #define LPFC_IO_LIBDFC 1 /* libdfc iocb */ |
| 43 | #define LPFC_IO_LIBDFC 2 /* libdfc iocb */ | 43 | #define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */ |
| 44 | #define LPFC_IO_WAIT 4 | ||
| 45 | #define LPFC_IO_HIPRI 8 /* High Priority Queue signal flag */ | ||
| 46 | 44 | ||
| 47 | uint8_t abort_count; | 45 | uint8_t abort_count; |
| 48 | uint8_t rsvd2; | 46 | uint8_t rsvd2; |
| @@ -51,8 +49,7 @@ struct lpfc_iocbq { | |||
| 51 | void *context2; /* caller context information */ | 49 | void *context2; /* caller context information */ |
| 52 | void *context3; /* caller context information */ | 50 | void *context3; /* caller context information */ |
| 53 | union { | 51 | union { |
| 54 | wait_queue_head_t *hipri_wait_queue; /* High Priority Queue wait | 52 | wait_queue_head_t *wait_queue; |
| 55 | queue */ | ||
| 56 | struct lpfc_iocbq *rsp_iocb; | 53 | struct lpfc_iocbq *rsp_iocb; |
| 57 | struct lpfcMboxq *mbox; | 54 | struct lpfcMboxq *mbox; |
| 58 | } context_un; | 55 | } context_un; |
