Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68876920 authored by James.Smart@Emulex.Com's avatar James.Smart@Emulex.Com Committed by James Bottomley
Browse files

[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: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 604a3e30
Loading
Loading
Loading
Loading
+5 −9
Original line number Diff line number Diff line
@@ -180,15 +180,11 @@ struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order,
int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
			 uint32_t timeout);

int lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba,
int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
			     struct lpfc_sli_ring * pring,
			     struct lpfc_iocbq * piocb,
					   uint32_t flag,
			     struct lpfc_iocbq * prspiocbq,
			     uint32_t timeout);
void lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
				      struct lpfc_iocbq * queue1,
				      struct lpfc_iocbq * queue2);
void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
			     struct lpfc_iocbq * cmdiocb,
			     struct lpfc_iocbq * rspiocb);
+6 −13
Original line number Diff line number Diff line
@@ -637,12 +637,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
	if (!iocbqrsp)
		return FAILED;

	iocbq->iocb_flag |= LPFC_IO_POLL;
	ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
	ret = lpfc_sli_issue_iocb_wait(phba,
				       &phba->sli.ring[phba->sli.fcp_ring],
		     iocbq, SLI_IOCB_HIGH_PRIORITY,
		     iocbqrsp,
		     lpfc_cmd->timeout);
				       iocbq, iocbqrsp, lpfc_cmd->timeout);
	if (ret != IOCB_SUCCESS) {
		lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
		ret = FAILED;
@@ -922,7 +919,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
{
	struct Scsi_Host *shost = cmnd->device->host;
	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
	struct lpfc_sli *psli = &phba->sli;
	struct lpfc_scsi_buf *lpfc_cmd = NULL;
	struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
	struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
@@ -969,12 +965,9 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
	if (iocbqrsp == NULL)
		goto out_free_scsi_buf;

	iocbq->iocb_flag |= LPFC_IO_POLL;
	iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;

	ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
		     &phba->sli.ring[psli->fcp_ring],
		     iocbq, 0, iocbqrsp, 60);
	ret = lpfc_sli_issue_iocb_wait(phba,
				       &phba->sli.ring[phba->sli.fcp_ring],
				       iocbq, iocbqrsp, lpfc_cmd->timeout);
	if (ret == IOCB_SUCCESS)
		ret = SUCCESS;

+75 −62
Original line number Diff line number Diff line
@@ -839,9 +839,6 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
				spin_lock_irqsave(phba->host->host_lock, iflag);
			}
			else {
				if (cmdiocbp->iocb_flag & LPFC_IO_POLL)
					rc = 0;

				spin_unlock_irqrestore(phba->host->host_lock,
						       iflag);
				(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
@@ -874,6 +871,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
				saveq->iocb.ulpContext);
		}
	}

	spin_unlock_irqrestore(phba->host->host_lock, iflag);
	return rc;
}
@@ -2592,84 +2590,99 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
	return errcnt;
}

void
lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
				 struct lpfc_iocbq * queue1,
				 struct lpfc_iocbq * queue2)
static void
lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
			struct lpfc_iocbq *cmdiocbq,
			struct lpfc_iocbq *rspiocbq)
{
	struct lpfc_iocbq *save_iocbq = queue1->context2;
	if (save_iocbq && queue2)
		memcpy(&save_iocbq->iocb, &queue2->iocb, sizeof(queue2->iocb));
	wait_queue_head_t *pdone_q;
	unsigned long iflags;

	spin_lock_irqsave(phba->host->host_lock, iflags);
	cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
	if (cmdiocbq->context2 && rspiocbq)
		memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
		       &rspiocbq->iocb, sizeof(IOCB_t));

	/* The waiter is looking for LPFC_IO_HIPRI bit to be set
	   as a signal to wake up */
	queue1->iocb_flag |= LPFC_IO_HIPRI;
	pdone_q = cmdiocbq->context_un.wait_queue;
	spin_unlock_irqrestore(phba->host->host_lock, iflags);
	if (pdone_q)
		wake_up(pdone_q);
	return;
}

/*
 * Issue the caller's iocb and wait for its completion, but no longer than the
 * caller's timeout.  Note that iocb_flags is cleared before the
 * lpfc_sli_issue_call since the wake routine sets a unique value and by
 * definition this is a wait function.
 */
int
lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba,
lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
			 struct lpfc_sli_ring * pring,
			 struct lpfc_iocbq * piocb,
				       uint32_t flag,
			 struct lpfc_iocbq * prspiocbq,
			 uint32_t timeout)
{
	int j, delay_time,  retval = IOCB_ERROR;

	/* The caller must left context1 empty.  */
	if (piocb->context_un.hipri_wait_queue != 0) {
		return IOCB_ERROR;
	}
	DECLARE_WAIT_QUEUE_HEAD(done_q);
	long timeleft, timeout_req = 0;
	int retval = IOCB_SUCCESS;

	/*
	 * If the caller has provided a response iocbq buffer, context2 must
	 * be NULL or its an error.
	 * If the caller has provided a response iocbq buffer, then context2
	 * is NULL or its an error.
	 */
	if (prspiocbq && piocb->context2) {
	if (prspiocbq) {
		if (piocb->context2)
			return IOCB_ERROR;
	}

		piocb->context2 = prspiocbq;

	/* Setup callback routine and issue the command. */
	piocb->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
	retval = lpfc_sli_issue_iocb(phba, pring, piocb,
					flag | SLI_IOCB_HIGH_PRIORITY);
	if (retval != IOCB_SUCCESS) {
		piocb->context2 = NULL;
		return IOCB_ERROR;
	}

	/*
	 * This high-priority iocb was sent out-of-band.  Poll for its
	 * completion rather than wait for a signal.  Note that the host_lock
	 * is held by the midlayer and must be released here to allow the
	 * interrupt handlers to complete the IO and signal this routine via
	 * the iocb_flag.
	 * Also, the delay_time is computed to be one second longer than
	 * the scsi command timeout to give the FW time to abort on
	 * timeout rather than the driver just giving up.  Typically,
	 * the midlayer does not specify a time for this command so the
	 * driver is free to enforce its own timeout.
	 */
	piocb->iocb_cmpl = lpfc_sli_wake_iocb_wait;
	piocb->context_un.wait_queue = &done_q;
	piocb->iocb_flag &= ~LPFC_IO_WAKE;

	delay_time = ((timeout + 1) * 1000) >> 6;
	retval = IOCB_ERROR;
	retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0);
	if (retval == IOCB_SUCCESS) {
		timeout_req = timeout * HZ;
		spin_unlock_irq(phba->host->host_lock);
	for (j = 0; j < 64; j++) {
		msleep(delay_time);
		if (piocb->iocb_flag & LPFC_IO_HIPRI) {
			piocb->iocb_flag &= ~LPFC_IO_HIPRI;
			retval = IOCB_SUCCESS;
			break;
		timeleft = wait_event_timeout(done_q,
				piocb->iocb_flag & LPFC_IO_WAKE,
				timeout_req);
		spin_lock_irq(phba->host->host_lock);

		if (timeleft == 0) {
			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
					"%d:0329 IOCB wait timeout error - no "
					"wake response Data x%x\n",
					phba->brd_no, timeout);
			retval = IOCB_TIMEDOUT;
		} else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) {
			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
					"%d:0330 IOCB wake NOT set, "
					"Data x%x x%lx\n", phba->brd_no,
					timeout, (timeleft / jiffies));
			retval = IOCB_TIMEDOUT;
		} else {
			lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
					"%d:0331 IOCB wake signaled\n",
					phba->brd_no);
		}
	} else {
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"%d:0332 IOCB wait issue failed, Data x%x\n",
				phba->brd_no, retval);
		retval = IOCB_ERROR;
	}

	spin_lock_irq(phba->host->host_lock);
	if (prspiocbq)
		piocb->context2 = NULL;

	piocb->context_un.wait_queue = NULL;
	piocb->iocb_cmpl = NULL;
	return retval;
}

int
lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
			 uint32_t timeout)
+3 −6
Original line number Diff line number Diff line
@@ -39,10 +39,8 @@ struct lpfc_iocbq {
	IOCB_t iocb;		/* IOCB cmd */
	uint8_t retry;		/* retry counter for IOCB cmd - if needed */
	uint8_t iocb_flag;
#define LPFC_IO_POLL	1	/* Polling mode iocb */
#define LPFC_IO_LIBDFC	2	/* libdfc iocb */
#define LPFC_IO_WAIT	4
#define LPFC_IO_HIPRI	8	/* High Priority Queue signal flag */
#define LPFC_IO_LIBDFC	1	/* libdfc iocb */
#define LPFC_IO_WAKE	2	/* High Priority Queue signal flag */

	uint8_t abort_count;
	uint8_t rsvd2;
@@ -51,8 +49,7 @@ struct lpfc_iocbq {
	void *context2;		/* caller context information */
	void *context3;		/* caller context information */
	union {
		wait_queue_head_t *hipri_wait_queue; /* High Priority Queue wait
							queue */
		wait_queue_head_t  *wait_queue;
		struct lpfc_iocbq  *rsp_iocb;
		struct lpfcMboxq   *mbox;
	} context_un;