aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-04-25 09:52:34 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-06 10:33:14 -0400
commit7054a606e6724674a5acd103ed74eacb02c73393 (patch)
tree271327c20a1e4bff9475ef7a9d98afd4644d6570 /drivers/scsi/lpfc/lpfc_sli.c
parentde0c5b32b50ef2673f4cd434b9c2732237d715dd (diff)
[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.c66
1 files changed, 43 insertions, 23 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 16825243e603..dba94c68feb1 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)
528 * If pdone_q is empty, the driver thread gave up waiting and 528 * If pdone_q is empty, the driver thread gave up waiting and
529 * continued running. 529 * continued running.
530 */ 530 */
531 pmboxq->mbox_flag |= LPFC_MBX_WAKE;
531 pdone_q = (wait_queue_head_t *) pmboxq->context1; 532 pdone_q = (wait_queue_head_t *) pmboxq->context1;
532 if (pdone_q) 533 if (pdone_q)
533 wake_up_interruptible(pdone_q); 534 wake_up_interruptible(pdone_q);
@@ -538,11 +539,32 @@ void
538lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 539lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
539{ 540{
540 struct lpfc_dmabuf *mp; 541 struct lpfc_dmabuf *mp;
542 uint16_t rpi;
543 int rc;
544
541 mp = (struct lpfc_dmabuf *) (pmb->context1); 545 mp = (struct lpfc_dmabuf *) (pmb->context1);
546
542 if (mp) { 547 if (mp) {
543 lpfc_mbuf_free(phba, mp->virt, mp->phys); 548 lpfc_mbuf_free(phba, mp->virt, mp->phys);
544 kfree(mp); 549 kfree(mp);
545 } 550 }
551
552 /*
553 * If a REG_LOGIN succeeded after node is destroyed or node
554 * is in re-discovery driver need to cleanup the RPI.
555 */
556 if (!(phba->fc_flag & FC_UNLOADING) &&
557 (pmb->mb.mbxCommand == MBX_REG_LOGIN64) &&
558 (!pmb->mb.mbxStatus)) {
559
560 rpi = pmb->mb.un.varWords[0];
561 lpfc_unreg_login(phba, rpi, pmb);
562 pmb->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
563 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
564 if (rc != MBX_NOT_FINISHED)
565 return;
566 }
567
546 mempool_free( pmb, phba->mbox_mem_pool); 568 mempool_free( pmb, phba->mbox_mem_pool);
547 return; 569 return;
548} 570}
@@ -2862,9 +2884,11 @@ void
2862lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, 2884lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
2863 struct lpfc_iocbq * rspiocb) 2885 struct lpfc_iocbq * rspiocb)
2864{ 2886{
2865 spin_lock_irq(phba->host->host_lock); 2887 unsigned long iflags;
2888
2889 spin_lock_irqsave(phba->host->host_lock, iflags);
2866 lpfc_sli_release_iocbq(phba, cmdiocb); 2890 lpfc_sli_release_iocbq(phba, cmdiocb);
2867 spin_unlock_irq(phba->host->host_lock); 2891 spin_unlock_irqrestore(phba->host->host_lock, iflags);
2868 return; 2892 return;
2869} 2893}
2870 2894
@@ -2987,22 +3011,22 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
2987 timeout_req); 3011 timeout_req);
2988 spin_lock_irq(phba->host->host_lock); 3012 spin_lock_irq(phba->host->host_lock);
2989 3013
2990 if (timeleft == 0) { 3014 if (piocb->iocb_flag & LPFC_IO_WAKE) {
3015 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
3016 "%d:0331 IOCB wake signaled\n",
3017 phba->brd_no);
3018 } else if (timeleft == 0) {
2991 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 3019 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
2992 "%d:0338 IOCB wait timeout error - no " 3020 "%d:0338 IOCB wait timeout error - no "
2993 "wake response Data x%x\n", 3021 "wake response Data x%x\n",
2994 phba->brd_no, timeout); 3022 phba->brd_no, timeout);
2995 retval = IOCB_TIMEDOUT; 3023 retval = IOCB_TIMEDOUT;
2996 } else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) { 3024 } else {
2997 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 3025 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
2998 "%d:0330 IOCB wake NOT set, " 3026 "%d:0330 IOCB wake NOT set, "
2999 "Data x%x x%lx\n", phba->brd_no, 3027 "Data x%x x%lx\n", phba->brd_no,
3000 timeout, (timeleft / jiffies)); 3028 timeout, (timeleft / jiffies));
3001 retval = IOCB_TIMEDOUT; 3029 retval = IOCB_TIMEDOUT;
3002 } else {
3003 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
3004 "%d:0331 IOCB wake signaled\n",
3005 phba->brd_no);
3006 } 3030 }
3007 } else { 3031 } else {
3008 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, 3032 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,
3031 uint32_t timeout) 3055 uint32_t timeout)
3032{ 3056{
3033 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); 3057 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
3034 DECLARE_WAITQUEUE(wq_entry, current);
3035 uint32_t timeleft = 0;
3036 int retval; 3058 int retval;
3037 3059
3038 /* The caller must leave context1 empty. */ 3060 /* The caller must leave context1 empty. */
@@ -3045,27 +3067,25 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
3045 /* setup context field to pass wait_queue pointer to wake function */ 3067 /* setup context field to pass wait_queue pointer to wake function */
3046 pmboxq->context1 = &done_q; 3068 pmboxq->context1 = &done_q;
3047 3069
3048 /* start to sleep before we wait, to avoid races */
3049 set_current_state(TASK_INTERRUPTIBLE);
3050 add_wait_queue(&done_q, &wq_entry);
3051
3052 /* now issue the command */ 3070 /* now issue the command */
3053 retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); 3071 retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
3054 3072
3055 if (retval == MBX_BUSY || retval == MBX_SUCCESS) { 3073 if (retval == MBX_BUSY || retval == MBX_SUCCESS) {
3056 timeleft = schedule_timeout(timeout * HZ); 3074 wait_event_interruptible_timeout(done_q,
3075 pmboxq->mbox_flag & LPFC_MBX_WAKE,
3076 timeout * HZ);
3077
3057 pmboxq->context1 = NULL; 3078 pmboxq->context1 = NULL;
3058 /* if schedule_timeout returns 0, we timed out and were not 3079 /*
3059 woken up */ 3080 * if LPFC_MBX_WAKE flag is set the mailbox is completed
3060 if ((timeleft == 0) || signal_pending(current)) 3081 * else do not free the resources.
3061 retval = MBX_TIMEOUT; 3082 */
3062 else 3083 if (pmboxq->mbox_flag & LPFC_MBX_WAKE)
3063 retval = MBX_SUCCESS; 3084 retval = MBX_SUCCESS;
3085 else
3086 retval = MBX_TIMEOUT;
3064 } 3087 }
3065 3088
3066
3067 set_current_state(TASK_RUNNING);
3068 remove_wait_queue(&done_q, &wq_entry);
3069 return retval; 3089 return retval;
3070} 3090}
3071 3091