diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-04-25 09:52:34 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-06 09:33:14 -0500 |
commit | 7054a606e6724674a5acd103ed74eacb02c73393 (patch) | |
tree | 271327c20a1e4bff9475ef7a9d98afd4644d6570 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | de0c5b32b50ef2673f4cd434b9c2732237d715dd (diff) | |
download | op-kernel-dev-7054a606e6724674a5acd103ed74eacb02c73393.zip op-kernel-dev-7054a606e6724674a5acd103ed74eacb02c73393.tar.gz |
[SCSI] lpfc 8.1.12 : Round 2 of Miscellaneous fixes
Round 2 of Miscellaneous fixes:
- Ensure we don't prematurely re-enable IRQs in lpfc_sli_abort_fcp_cmpl().
- Prevent freeing of iocb after IOCB_TIMEDOUT error.
- Added code to cleanup REG_LOGIN mailbox command when a LOGO is received.
- Fix offline window where more work can sneak in after clearing work_ha
- Use target reset instead of LU reset in bus_device_reset_handler
- Fixed system hangs due to leaked host_lock.
- Fixed NULL pointer dereference during I/O with LIP.
- Fixed false iocb timeout.
- Fixed name server query response handling.
- Change rport dev_loss_tmo value when user change lpfc HBA's dev_loss_tmo.
- Fixed a memory leak in lpfc_sli_wake_mbox_wait.
- Fixed check for dropped frames.
- Removed hba queue depth calculation based on device PCI IDs
- Change min cr_count value specified in comment to agree with setting
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.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 1682524..dba94c6 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -528,6 +528,7 @@ lpfc_sli_wake_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) * If pdone_q is empty, the driver thread gave up waiting and * continued running. */ + pmboxq->mbox_flag |= LPFC_MBX_WAKE; pdone_q = (wait_queue_head_t *) pmboxq->context1; if (pdone_q) wake_up_interruptible(pdone_q); @@ -538,11 +539,32 @@ void lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { struct lpfc_dmabuf *mp; + uint16_t rpi; + int rc; + mp = (struct lpfc_dmabuf *) (pmb->context1); + if (mp) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); } + + /* + * If a REG_LOGIN succeeded after node is destroyed or node + * is in re-discovery driver need to cleanup the RPI. + */ + if (!(phba->fc_flag & FC_UNLOADING) && + (pmb->mb.mbxCommand == MBX_REG_LOGIN64) && + (!pmb->mb.mbxStatus)) { + + rpi = pmb->mb.un.varWords[0]; + lpfc_unreg_login(phba, rpi, pmb); + pmb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; + rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); + if (rc != MBX_NOT_FINISHED) + return; + } + mempool_free( pmb, phba->mbox_mem_pool); return; } @@ -2862,9 +2884,11 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) { - spin_lock_irq(phba->host->host_lock); + unsigned long iflags; + + spin_lock_irqsave(phba->host->host_lock, iflags); lpfc_sli_release_iocbq(phba, cmdiocb); - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irqrestore(phba->host->host_lock, iflags); return; } @@ -2987,22 +3011,22 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, timeout_req); spin_lock_irq(phba->host->host_lock); - if (timeleft == 0) { + if (piocb->iocb_flag & LPFC_IO_WAKE) { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "%d:0331 IOCB wake signaled\n", + phba->brd_no); + } else if (timeleft == 0) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "%d:0338 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)) { + } else { 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, @@ -3031,8 +3055,6 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, uint32_t timeout) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); - DECLARE_WAITQUEUE(wq_entry, current); - uint32_t timeleft = 0; int retval; /* The caller must leave context1 empty. */ @@ -3045,27 +3067,25 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, /* setup context field to pass wait_queue pointer to wake function */ pmboxq->context1 = &done_q; - /* start to sleep before we wait, to avoid races */ - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&done_q, &wq_entry); - /* now issue the command */ retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); if (retval == MBX_BUSY || retval == MBX_SUCCESS) { - timeleft = schedule_timeout(timeout * HZ); + wait_event_interruptible_timeout(done_q, + pmboxq->mbox_flag & LPFC_MBX_WAKE, + timeout * HZ); + pmboxq->context1 = NULL; - /* if schedule_timeout returns 0, we timed out and were not - woken up */ - if ((timeleft == 0) || signal_pending(current)) - retval = MBX_TIMEOUT; - else + /* + * if LPFC_MBX_WAKE flag is set the mailbox is completed + * else do not free the resources. + */ + if (pmboxq->mbox_flag & LPFC_MBX_WAKE) retval = MBX_SUCCESS; + else + retval = MBX_TIMEOUT; } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&done_q, &wq_entry); return retval; } |