aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
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 /drivers/scsi/lpfc/lpfc_sli.c
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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c137
1 files changed, 75 insertions, 62 deletions
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)