aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames.Smart@Emulex.Com <James.Smart@Emulex.Com>2005-10-28 20:29:47 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-10-29 11:29:09 -0400
commit68876920f442912c94f749bc337c888696cb9ed0 (patch)
tree12fe1c63be2fedad13706b4b14d46c90c94cce49
parent604a3e3042eb89ffaa4f735ef9208281aae786c7 (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.h14
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c19
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c137
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h9
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,
180int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, 180int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
181 uint32_t timeout); 181 uint32_t timeout);
182 182
183int lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba, 183int 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);
189void lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
190 struct lpfc_iocbq * queue1,
191 struct lpfc_iocbq * queue2);
192void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, 188void 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
2595void 2593static void
2596lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba, 2594lpfc_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 */
2610int 2620int
2611lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba, 2621lpfc_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
2673int 2686int
2674lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, 2687lpfc_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;