diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-04-06 18:48:10 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-04-27 10:42:47 -0400 |
commit | a257bf905efd22fd2c055580b0ab2e8e7ed1b6a1 (patch) | |
tree | e0f2ef6b9627d86456c92d56fa2c088c6d6544bf /drivers/scsi/lpfc/lpfc_hbadisc.c | |
parent | 3621a710a7dbb2d22a8e95d94bcf0c2d13ef57fc (diff) |
[SCSI] lpfc 8.3.1: misc fixes/changes
8.3.1 Fixes/Changes :
- Fix incorrect byte-swapping on word 4 of IOCB (data length) which
caused LUNs to not be discovered on big-endian (e.g. PPC)
- Remove a bad cast of MBslimaddr which loses the __iomem (sparse)
- Make lpfc_debugfs_mask_disc_trc static (sparse)
- Correct misspelled word BlockGuard in lpfc_logmsg.h comment
- Replaced repeated code segment for canceling IOCBs from a list with
a function call, lpfc_sli_cancel_iocbs().
- Increased HBQ buffers to support 40KB SSC sequences.
- Added sysfs interface to update speed and topology parameter without
link bounce.
- Fixed bug with sysfs fc_host WWNs not being updated after changing
the WWNs.
- Check if the active mailbox is NULL in the beginning of the mailbox
timeout handler - fixes panic in the mailbox timeout handler while
running IO stress test
- Fixed system panic in lpfc_pci_remove_one() due to ndlp indirect
reference to phba through vport
- Removed de-reference of scsi device after call to scsi_done() to fix
panic in scsi completion path while accessing scsi device after
scsi_done is called.
- Fixed "Nodelist not empty" message when unloading the driver after
target reboot test
- Added LP2105 HBA model description
- Added code to print all 16 words of unrecognized ASYNC events
- Fixed memory leak in vport create + delete loop
- Added support for handling dual error bit from HBA
- Fixed a driver NULL pointer dereference in lpfc_sli_process_sol_iocb
- Fixed a discovery bug with FC switch reboot in lpfc_setup_disc_node
- Take NULL termintator into account when calculating available buffer space
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 80 |
1 files changed, 35 insertions, 45 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 9373a9e7485a..e764ce0bf704 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -78,7 +78,7 @@ lpfc_terminate_rport_io(struct fc_rport *rport) | |||
78 | return; | 78 | return; |
79 | } | 79 | } |
80 | 80 | ||
81 | phba = ndlp->vport->phba; | 81 | phba = ndlp->phba; |
82 | 82 | ||
83 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_RPORT, | 83 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_RPORT, |
84 | "rport terminate: sid:x%x did:x%x flg:x%x", | 84 | "rport terminate: sid:x%x did:x%x flg:x%x", |
@@ -1862,9 +1862,14 @@ lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1862 | * @vport: Pointer to Virtual Port object. | 1862 | * @vport: Pointer to Virtual Port object. |
1863 | * @ndlp: Pointer to FC node object. | 1863 | * @ndlp: Pointer to FC node object. |
1864 | * @did: FC_ID of the node. | 1864 | * @did: FC_ID of the node. |
1865 | * This function is always called when node object need to | 1865 | * |
1866 | * be initialized. It initializes all the fields of the node | 1866 | * This function is always called when node object need to be initialized. |
1867 | * object. | 1867 | * It initializes all the fields of the node object. Although the reference |
1868 | * to phba from @ndlp can be obtained indirectly through it's reference to | ||
1869 | * @vport, a direct reference to phba is taken here by @ndlp. This is due | ||
1870 | * to the life-span of the @ndlp might go beyond the existence of @vport as | ||
1871 | * the final release of ndlp is determined by its reference count. And, the | ||
1872 | * operation on @ndlp needs the reference to phba. | ||
1868 | **/ | 1873 | **/ |
1869 | static inline void | 1874 | static inline void |
1870 | lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 1875 | lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
@@ -1877,6 +1882,7 @@ lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1877 | ndlp->nlp_delayfunc.data = (unsigned long)ndlp; | 1882 | ndlp->nlp_delayfunc.data = (unsigned long)ndlp; |
1878 | ndlp->nlp_DID = did; | 1883 | ndlp->nlp_DID = did; |
1879 | ndlp->vport = vport; | 1884 | ndlp->vport = vport; |
1885 | ndlp->phba = vport->phba; | ||
1880 | ndlp->nlp_sid = NLP_NO_SID; | 1886 | ndlp->nlp_sid = NLP_NO_SID; |
1881 | kref_init(&ndlp->kref); | 1887 | kref_init(&ndlp->kref); |
1882 | NLP_INT_NODE_ACT(ndlp); | 1888 | NLP_INT_NODE_ACT(ndlp); |
@@ -2086,7 +2092,6 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
2086 | struct lpfc_sli *psli; | 2092 | struct lpfc_sli *psli; |
2087 | struct lpfc_sli_ring *pring; | 2093 | struct lpfc_sli_ring *pring; |
2088 | struct lpfc_iocbq *iocb, *next_iocb; | 2094 | struct lpfc_iocbq *iocb, *next_iocb; |
2089 | IOCB_t *icmd; | ||
2090 | uint32_t rpi, i; | 2095 | uint32_t rpi, i; |
2091 | 2096 | ||
2092 | lpfc_fabric_abort_nport(ndlp); | 2097 | lpfc_fabric_abort_nport(ndlp); |
@@ -2122,19 +2127,9 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
2122 | } | 2127 | } |
2123 | } | 2128 | } |
2124 | 2129 | ||
2125 | while (!list_empty(&completions)) { | 2130 | /* Cancel all the IOCBs from the completions list */ |
2126 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 2131 | lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, |
2127 | list_del_init(&iocb->list); | 2132 | IOERR_SLI_ABORTED); |
2128 | |||
2129 | if (!iocb->iocb_cmpl) | ||
2130 | lpfc_sli_release_iocbq(phba, iocb); | ||
2131 | else { | ||
2132 | icmd = &iocb->iocb; | ||
2133 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
2134 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
2135 | (iocb->iocb_cmpl)(phba, iocb, iocb); | ||
2136 | } | ||
2137 | } | ||
2138 | 2133 | ||
2139 | return 0; | 2134 | return 0; |
2140 | } | 2135 | } |
@@ -2186,9 +2181,13 @@ lpfc_unreg_all_rpis(struct lpfc_vport *vport) | |||
2186 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 2181 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
2187 | mbox->context1 = NULL; | 2182 | mbox->context1 = NULL; |
2188 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | 2183 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); |
2189 | if (rc == MBX_NOT_FINISHED) { | 2184 | if (rc != MBX_TIMEOUT) |
2190 | mempool_free(mbox, phba->mbox_mem_pool); | 2185 | mempool_free(mbox, phba->mbox_mem_pool); |
2191 | } | 2186 | |
2187 | if ((rc == MBX_TIMEOUT) || (rc == MBX_NOT_FINISHED)) | ||
2188 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, | ||
2189 | "1836 Could not issue " | ||
2190 | "unreg_login(all_rpis) status %d\n", rc); | ||
2192 | } | 2191 | } |
2193 | } | 2192 | } |
2194 | 2193 | ||
@@ -2206,12 +2205,14 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport) | |||
2206 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 2205 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
2207 | mbox->context1 = NULL; | 2206 | mbox->context1 = NULL; |
2208 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | 2207 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); |
2209 | if (rc == MBX_NOT_FINISHED) { | 2208 | if (rc != MBX_TIMEOUT) |
2209 | mempool_free(mbox, phba->mbox_mem_pool); | ||
2210 | |||
2211 | if ((rc == MBX_TIMEOUT) || (rc == MBX_NOT_FINISHED)) | ||
2210 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, | 2212 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, |
2211 | "1815 Could not issue " | 2213 | "1815 Could not issue " |
2212 | "unreg_did (default rpis)\n"); | 2214 | "unreg_did (default rpis) status %d\n", |
2213 | mempool_free(mbox, phba->mbox_mem_pool); | 2215 | rc); |
2214 | } | ||
2215 | } | 2216 | } |
2216 | } | 2217 | } |
2217 | 2218 | ||
@@ -2470,14 +2471,13 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
2470 | if (ndlp->nlp_flag & NLP_RCV_PLOGI) | 2471 | if (ndlp->nlp_flag & NLP_RCV_PLOGI) |
2471 | return NULL; | 2472 | return NULL; |
2472 | 2473 | ||
2473 | spin_lock_irq(shost->host_lock); | ||
2474 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | ||
2475 | spin_unlock_irq(shost->host_lock); | ||
2476 | |||
2477 | /* Since this node is marked for discovery, | 2474 | /* Since this node is marked for discovery, |
2478 | * delay timeout is not needed. | 2475 | * delay timeout is not needed. |
2479 | */ | 2476 | */ |
2480 | lpfc_cancel_retry_delay_tmo(vport, ndlp); | 2477 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
2478 | spin_lock_irq(shost->host_lock); | ||
2479 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | ||
2480 | spin_unlock_irq(shost->host_lock); | ||
2481 | } else | 2481 | } else |
2482 | ndlp = NULL; | 2482 | ndlp = NULL; |
2483 | } else { | 2483 | } else { |
@@ -2740,19 +2740,9 @@ lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
2740 | } | 2740 | } |
2741 | spin_unlock_irq(&phba->hbalock); | 2741 | spin_unlock_irq(&phba->hbalock); |
2742 | 2742 | ||
2743 | while (!list_empty(&completions)) { | 2743 | /* Cancel all the IOCBs from the completions list */ |
2744 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 2744 | lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, |
2745 | list_del_init(&iocb->list); | 2745 | IOERR_SLI_ABORTED); |
2746 | |||
2747 | if (!iocb->iocb_cmpl) | ||
2748 | lpfc_sli_release_iocbq(phba, iocb); | ||
2749 | else { | ||
2750 | icmd = &iocb->iocb; | ||
2751 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
2752 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
2753 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
2754 | } | ||
2755 | } | ||
2756 | } | 2746 | } |
2757 | 2747 | ||
2758 | static void | 2748 | static void |
@@ -3173,7 +3163,7 @@ lpfc_nlp_release(struct kref *kref) | |||
3173 | lpfc_nlp_remove(ndlp->vport, ndlp); | 3163 | lpfc_nlp_remove(ndlp->vport, ndlp); |
3174 | 3164 | ||
3175 | /* clear the ndlp active flag for all release cases */ | 3165 | /* clear the ndlp active flag for all release cases */ |
3176 | phba = ndlp->vport->phba; | 3166 | phba = ndlp->phba; |
3177 | spin_lock_irqsave(&phba->ndlp_lock, flags); | 3167 | spin_lock_irqsave(&phba->ndlp_lock, flags); |
3178 | NLP_CLR_NODE_ACT(ndlp); | 3168 | NLP_CLR_NODE_ACT(ndlp); |
3179 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | 3169 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); |
@@ -3181,7 +3171,7 @@ lpfc_nlp_release(struct kref *kref) | |||
3181 | /* free ndlp memory for final ndlp release */ | 3171 | /* free ndlp memory for final ndlp release */ |
3182 | if (NLP_CHK_FREE_REQ(ndlp)) { | 3172 | if (NLP_CHK_FREE_REQ(ndlp)) { |
3183 | kfree(ndlp->lat_data); | 3173 | kfree(ndlp->lat_data); |
3184 | mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); | 3174 | mempool_free(ndlp, ndlp->phba->nlp_mem_pool); |
3185 | } | 3175 | } |
3186 | } | 3176 | } |
3187 | 3177 | ||
@@ -3204,7 +3194,7 @@ lpfc_nlp_get(struct lpfc_nodelist *ndlp) | |||
3204 | * ndlp reference count that is in the process of being | 3194 | * ndlp reference count that is in the process of being |
3205 | * released. | 3195 | * released. |
3206 | */ | 3196 | */ |
3207 | phba = ndlp->vport->phba; | 3197 | phba = ndlp->phba; |
3208 | spin_lock_irqsave(&phba->ndlp_lock, flags); | 3198 | spin_lock_irqsave(&phba->ndlp_lock, flags); |
3209 | if (!NLP_CHK_NODE_ACT(ndlp) || NLP_CHK_FREE_ACK(ndlp)) { | 3199 | if (!NLP_CHK_NODE_ACT(ndlp) || NLP_CHK_FREE_ACK(ndlp)) { |
3210 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | 3200 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); |
@@ -3240,7 +3230,7 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp) | |||
3240 | "node put: did:x%x flg:x%x refcnt:x%x", | 3230 | "node put: did:x%x flg:x%x refcnt:x%x", |
3241 | ndlp->nlp_DID, ndlp->nlp_flag, | 3231 | ndlp->nlp_DID, ndlp->nlp_flag, |
3242 | atomic_read(&ndlp->kref.refcount)); | 3232 | atomic_read(&ndlp->kref.refcount)); |
3243 | phba = ndlp->vport->phba; | 3233 | phba = ndlp->phba; |
3244 | spin_lock_irqsave(&phba->ndlp_lock, flags); | 3234 | spin_lock_irqsave(&phba->ndlp_lock, flags); |
3245 | /* Check the ndlp memory free acknowledge flag to avoid the | 3235 | /* Check the ndlp memory free acknowledge flag to avoid the |
3246 | * possible race condition that kref_put got invoked again | 3236 | * possible race condition that kref_put got invoked again |