forked from luck/tmp_suning_uos_patched
[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>
This commit is contained in:
parent
604a3e3042
commit
68876920f4
@ -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,
|
int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
|
||||||
uint32_t timeout);
|
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_sli_ring * pring,
|
||||||
struct lpfc_iocbq * piocb,
|
struct lpfc_iocbq * piocb,
|
||||||
uint32_t flag,
|
struct lpfc_iocbq * prspiocbq,
|
||||||
struct lpfc_iocbq * prspiocbq,
|
uint32_t timeout);
|
||||||
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,
|
void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
|
||||||
struct lpfc_iocbq * cmdiocb,
|
struct lpfc_iocbq * cmdiocb,
|
||||||
struct lpfc_iocbq * rspiocb);
|
struct lpfc_iocbq * rspiocb);
|
||||||
|
@ -637,12 +637,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
|
|||||||
if (!iocbqrsp)
|
if (!iocbqrsp)
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
|
||||||
iocbq->iocb_flag |= LPFC_IO_POLL;
|
ret = lpfc_sli_issue_iocb_wait(phba,
|
||||||
ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
|
&phba->sli.ring[phba->sli.fcp_ring],
|
||||||
&phba->sli.ring[phba->sli.fcp_ring],
|
iocbq, iocbqrsp, lpfc_cmd->timeout);
|
||||||
iocbq, SLI_IOCB_HIGH_PRIORITY,
|
|
||||||
iocbqrsp,
|
|
||||||
lpfc_cmd->timeout);
|
|
||||||
if (ret != IOCB_SUCCESS) {
|
if (ret != IOCB_SUCCESS) {
|
||||||
lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
|
lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
|
||||||
ret = FAILED;
|
ret = FAILED;
|
||||||
@ -922,7 +919,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
|
|||||||
{
|
{
|
||||||
struct Scsi_Host *shost = cmnd->device->host;
|
struct Scsi_Host *shost = cmnd->device->host;
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
|
||||||
struct lpfc_sli *psli = &phba->sli;
|
|
||||||
struct lpfc_scsi_buf *lpfc_cmd = NULL;
|
struct lpfc_scsi_buf *lpfc_cmd = NULL;
|
||||||
struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
|
struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
|
||||||
struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_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)
|
if (iocbqrsp == NULL)
|
||||||
goto out_free_scsi_buf;
|
goto out_free_scsi_buf;
|
||||||
|
|
||||||
iocbq->iocb_flag |= LPFC_IO_POLL;
|
ret = lpfc_sli_issue_iocb_wait(phba,
|
||||||
iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
|
&phba->sli.ring[phba->sli.fcp_ring],
|
||||||
|
iocbq, iocbqrsp, lpfc_cmd->timeout);
|
||||||
ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
|
|
||||||
&phba->sli.ring[psli->fcp_ring],
|
|
||||||
iocbq, 0, iocbqrsp, 60);
|
|
||||||
if (ret == IOCB_SUCCESS)
|
if (ret == IOCB_SUCCESS)
|
||||||
ret = SUCCESS;
|
ret = SUCCESS;
|
||||||
|
|
||||||
|
@ -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);
|
spin_lock_irqsave(phba->host->host_lock, iflag);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (cmdiocbp->iocb_flag & LPFC_IO_POLL)
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(phba->host->host_lock,
|
spin_unlock_irqrestore(phba->host->host_lock,
|
||||||
iflag);
|
iflag);
|
||||||
(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
|
(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);
|
saveq->iocb.ulpContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(phba->host->host_lock, iflag);
|
spin_unlock_irqrestore(phba->host->host_lock, iflag);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -2592,84 +2590,99 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||||||
return errcnt;
|
return errcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
|
lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
|
||||||
struct lpfc_iocbq * queue1,
|
struct lpfc_iocbq *cmdiocbq,
|
||||||
struct lpfc_iocbq * queue2)
|
struct lpfc_iocbq *rspiocbq)
|
||||||
{
|
{
|
||||||
struct lpfc_iocbq *save_iocbq = queue1->context2;
|
wait_queue_head_t *pdone_q;
|
||||||
if (save_iocbq && queue2)
|
unsigned long iflags;
|
||||||
memcpy(&save_iocbq->iocb, &queue2->iocb, sizeof(queue2->iocb));
|
|
||||||
|
|
||||||
/* The waiter is looking for LPFC_IO_HIPRI bit to be set
|
spin_lock_irqsave(phba->host->host_lock, iflags);
|
||||||
as a signal to wake up */
|
cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
|
||||||
queue1->iocb_flag |= LPFC_IO_HIPRI;
|
if (cmdiocbq->context2 && rspiocbq)
|
||||||
|
memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
|
||||||
|
&rspiocbq->iocb, sizeof(IOCB_t));
|
||||||
|
|
||||||
|
pdone_q = cmdiocbq->context_un.wait_queue;
|
||||||
|
spin_unlock_irqrestore(phba->host->host_lock, iflags);
|
||||||
|
if (pdone_q)
|
||||||
|
wake_up(pdone_q);
|
||||||
return;
|
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
|
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_sli_ring * pring,
|
||||||
struct lpfc_iocbq * piocb,
|
struct lpfc_iocbq * piocb,
|
||||||
uint32_t flag,
|
struct lpfc_iocbq * prspiocbq,
|
||||||
struct lpfc_iocbq * prspiocbq,
|
uint32_t timeout)
|
||||||
uint32_t timeout)
|
|
||||||
{
|
{
|
||||||
int j, delay_time, retval = IOCB_ERROR;
|
DECLARE_WAIT_QUEUE_HEAD(done_q);
|
||||||
|
long timeleft, timeout_req = 0;
|
||||||
/* The caller must left context1 empty. */
|
int retval = IOCB_SUCCESS;
|
||||||
if (piocb->context_un.hipri_wait_queue != 0) {
|
|
||||||
return IOCB_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the caller has provided a response iocbq buffer, context2 must
|
* If the caller has provided a response iocbq buffer, then context2
|
||||||
* be NULL or its an error.
|
* is NULL or its an error.
|
||||||
*/
|
*/
|
||||||
if (prspiocbq && piocb->context2) {
|
if (prspiocbq) {
|
||||||
return IOCB_ERROR;
|
if (piocb->context2)
|
||||||
|
return IOCB_ERROR;
|
||||||
|
piocb->context2 = prspiocbq;
|
||||||
}
|
}
|
||||||
|
|
||||||
piocb->context2 = prspiocbq;
|
piocb->iocb_cmpl = lpfc_sli_wake_iocb_wait;
|
||||||
|
piocb->context_un.wait_queue = &done_q;
|
||||||
|
piocb->iocb_flag &= ~LPFC_IO_WAKE;
|
||||||
|
|
||||||
/* Setup callback routine and issue the command. */
|
retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0);
|
||||||
piocb->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
|
if (retval == IOCB_SUCCESS) {
|
||||||
retval = lpfc_sli_issue_iocb(phba, pring, piocb,
|
timeout_req = timeout * HZ;
|
||||||
flag | SLI_IOCB_HIGH_PRIORITY);
|
spin_unlock_irq(phba->host->host_lock);
|
||||||
if (retval != IOCB_SUCCESS) {
|
timeleft = wait_event_timeout(done_q,
|
||||||
piocb->context2 = NULL;
|
piocb->iocb_flag & LPFC_IO_WAKE,
|
||||||
return IOCB_ERROR;
|
timeout_req);
|
||||||
}
|
spin_lock_irq(phba->host->host_lock);
|
||||||
|
|
||||||
/*
|
if (timeleft == 0) {
|
||||||
* This high-priority iocb was sent out-of-band. Poll for its
|
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||||
* completion rather than wait for a signal. Note that the host_lock
|
"%d:0329 IOCB wait timeout error - no "
|
||||||
* is held by the midlayer and must be released here to allow the
|
"wake response Data x%x\n",
|
||||||
* interrupt handlers to complete the IO and signal this routine via
|
phba->brd_no, timeout);
|
||||||
* the iocb_flag.
|
retval = IOCB_TIMEDOUT;
|
||||||
* Also, the delay_time is computed to be one second longer than
|
} else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) {
|
||||||
* the scsi command timeout to give the FW time to abort on
|
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||||
* timeout rather than the driver just giving up. Typically,
|
"%d:0330 IOCB wake NOT set, "
|
||||||
* the midlayer does not specify a time for this command so the
|
"Data x%x x%lx\n", phba->brd_no,
|
||||||
* driver is free to enforce its own timeout.
|
timeout, (timeleft / jiffies));
|
||||||
*/
|
retval = IOCB_TIMEDOUT;
|
||||||
|
} else {
|
||||||
delay_time = ((timeout + 1) * 1000) >> 6;
|
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||||
retval = IOCB_ERROR;
|
"%d:0331 IOCB wake signaled\n",
|
||||||
spin_unlock_irq(phba->host->host_lock);
|
phba->brd_no);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
} 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->context2 = NULL;
|
||||||
|
|
||||||
|
piocb->context_un.wait_queue = NULL;
|
||||||
|
piocb->iocb_cmpl = NULL;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
|
lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
|
||||||
uint32_t timeout)
|
uint32_t timeout)
|
||||||
|
@ -39,10 +39,8 @@ struct lpfc_iocbq {
|
|||||||
IOCB_t iocb; /* IOCB cmd */
|
IOCB_t iocb; /* IOCB cmd */
|
||||||
uint8_t retry; /* retry counter for IOCB cmd - if needed */
|
uint8_t retry; /* retry counter for IOCB cmd - if needed */
|
||||||
uint8_t iocb_flag;
|
uint8_t iocb_flag;
|
||||||
#define LPFC_IO_POLL 1 /* Polling mode iocb */
|
#define LPFC_IO_LIBDFC 1 /* libdfc iocb */
|
||||||
#define LPFC_IO_LIBDFC 2 /* libdfc iocb */
|
#define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */
|
||||||
#define LPFC_IO_WAIT 4
|
|
||||||
#define LPFC_IO_HIPRI 8 /* High Priority Queue signal flag */
|
|
||||||
|
|
||||||
uint8_t abort_count;
|
uint8_t abort_count;
|
||||||
uint8_t rsvd2;
|
uint8_t rsvd2;
|
||||||
@ -51,8 +49,7 @@ struct lpfc_iocbq {
|
|||||||
void *context2; /* caller context information */
|
void *context2; /* caller context information */
|
||||||
void *context3; /* caller context information */
|
void *context3; /* caller context information */
|
||||||
union {
|
union {
|
||||||
wait_queue_head_t *hipri_wait_queue; /* High Priority Queue wait
|
wait_queue_head_t *wait_queue;
|
||||||
queue */
|
|
||||||
struct lpfc_iocbq *rsp_iocb;
|
struct lpfc_iocbq *rsp_iocb;
|
||||||
struct lpfcMboxq *mbox;
|
struct lpfcMboxq *mbox;
|
||||||
} context_un;
|
} context_un;
|
||||||
|
Loading…
Reference in New Issue
Block a user