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 10:33:14 -0400 |
commit | 7054a606e6724674a5acd103ed74eacb02c73393 (patch) | |
tree | 271327c20a1e4bff9475ef7a9d98afd4644d6570 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | de0c5b32b50ef2673f4cd434b9c2732237d715dd (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.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 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 | |||
538 | lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 539 | lpfc_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 | |||
2862 | lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2884 | lpfc_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 | ||