diff options
author | James.Smart@Emulex.Com <James.Smart@Emulex.Com> | 2005-10-28 20:29:47 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-10-29 11:29:09 -0400 |
commit | 68876920f442912c94f749bc337c888696cb9ed0 (patch) | |
tree | 12fe1c63be2fedad13706b4b14d46c90c94cce49 | |
parent | 604a3e3042eb89ffaa4f735ef9208281aae786c7 (diff) |
[SCSI] lpfc: Replace lpfc_sli_issue_iocb_wait_high_priority
Replace lpfc_sli_issue_iocb_wait_high_priority with lpfc_sli_issue_iocb_wait.
Simplify code paths, as there really wasn't a "priority"
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-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; |