aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-10-02 15:16:39 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:39 -0500
commit4d9ab994e214d35107017c342aca42477b137316 (patch)
tree0ee7dd76ce9938eceeac20e4dab287194dc42c41 /drivers/scsi/lpfc/lpfc_hbadisc.c
parent1796e72291b2b6aafaec5954e666d0b5a95da935 (diff)
[SCSI] lpfc 8.3.5: fix reset path, ELS ordering and discovery issues
This patch includes the following fixes: - Fixed panic during HBA reset. - Fixed FCoE event tag passed in resume_rpi. - Fix out of order ELS commands - Fixed discovery issues found during VLAN testing. - Fix UNREG_VPI failure on extended link pull - Fixed crash while processing unsolicited FC frames. - Clear retry count in the delayed ELS handler - Fixed discovery failure during quick link bounce. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c67
1 files changed, 56 insertions, 11 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index e6a47e25b21..5073c127bfe 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -525,8 +525,6 @@ lpfc_work_done(struct lpfc_hba *phba)
525 spin_unlock_irq(&phba->hbalock); 525 spin_unlock_irq(&phba->hbalock);
526 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); 526 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
527 } 527 }
528 if (phba->hba_flag & HBA_RECEIVE_BUFFER)
529 lpfc_sli4_handle_received_buffer(phba);
530 } 528 }
531 529
532 vports = lpfc_create_vport_work_array(phba); 530 vports = lpfc_create_vport_work_array(phba);
@@ -568,8 +566,9 @@ lpfc_work_done(struct lpfc_hba *phba)
568 pring = &phba->sli.ring[LPFC_ELS_RING]; 566 pring = &phba->sli.ring[LPFC_ELS_RING];
569 status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); 567 status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING)));
570 status >>= (4*LPFC_ELS_RING); 568 status >>= (4*LPFC_ELS_RING);
571 if ((status & HA_RXMASK) 569 if ((status & HA_RXMASK) ||
572 || (pring->flag & LPFC_DEFERRED_RING_EVENT)) { 570 (pring->flag & LPFC_DEFERRED_RING_EVENT) ||
571 (phba->hba_flag & HBA_RECEIVE_BUFFER)) {
573 if (pring->flag & LPFC_STOP_IOCB_EVENT) { 572 if (pring->flag & LPFC_STOP_IOCB_EVENT) {
574 pring->flag |= LPFC_DEFERRED_RING_EVENT; 573 pring->flag |= LPFC_DEFERRED_RING_EVENT;
575 /* Set the lpfc data pending flag */ 574 /* Set the lpfc data pending flag */
@@ -688,7 +687,8 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
688 lpfc_unreg_rpi(vport, ndlp); 687 lpfc_unreg_rpi(vport, ndlp);
689 688
690 /* Leave Fabric nodes alone on link down */ 689 /* Leave Fabric nodes alone on link down */
691 if (!remove && ndlp->nlp_type & NLP_FABRIC) 690 if ((phba->sli_rev < LPFC_SLI_REV4) &&
691 (!remove && ndlp->nlp_type & NLP_FABRIC))
692 continue; 692 continue;
693 rc = lpfc_disc_state_machine(vport, ndlp, NULL, 693 rc = lpfc_disc_state_machine(vport, ndlp, NULL,
694 remove 694 remove
@@ -1015,10 +1015,10 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1015 mempool_free(mboxq, phba->mbox_mem_pool); 1015 mempool_free(mboxq, phba->mbox_mem_pool);
1016 return; 1016 return;
1017 } 1017 }
1018 phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
1019 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1018 if (vport->port_state != LPFC_FLOGI) { 1020 if (vport->port_state != LPFC_FLOGI) {
1019 spin_lock_irqsave(&phba->hbalock, flags); 1021 spin_lock_irqsave(&phba->hbalock, flags);
1020 phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
1021 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1022 spin_unlock_irqrestore(&phba->hbalock, flags); 1022 spin_unlock_irqrestore(&phba->hbalock, flags);
1023 lpfc_initial_flogi(vport); 1023 lpfc_initial_flogi(vport);
1024 } 1024 }
@@ -1199,6 +1199,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
1199 1199
1200 /* If the FCF is not availabe do nothing. */ 1200 /* If the FCF is not availabe do nothing. */
1201 if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) { 1201 if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) {
1202 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1202 spin_unlock_irqrestore(&phba->hbalock, flags); 1203 spin_unlock_irqrestore(&phba->hbalock, flags);
1203 return; 1204 return;
1204 } 1205 }
@@ -1216,15 +1217,23 @@ lpfc_register_fcf(struct lpfc_hba *phba)
1216 1217
1217 fcf_mbxq = mempool_alloc(phba->mbox_mem_pool, 1218 fcf_mbxq = mempool_alloc(phba->mbox_mem_pool,
1218 GFP_KERNEL); 1219 GFP_KERNEL);
1219 if (!fcf_mbxq) 1220 if (!fcf_mbxq) {
1221 spin_lock_irqsave(&phba->hbalock, flags);
1222 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1223 spin_unlock_irqrestore(&phba->hbalock, flags);
1220 return; 1224 return;
1225 }
1221 1226
1222 lpfc_reg_fcfi(phba, fcf_mbxq); 1227 lpfc_reg_fcfi(phba, fcf_mbxq);
1223 fcf_mbxq->vport = phba->pport; 1228 fcf_mbxq->vport = phba->pport;
1224 fcf_mbxq->mbox_cmpl = lpfc_mbx_cmpl_reg_fcfi; 1229 fcf_mbxq->mbox_cmpl = lpfc_mbx_cmpl_reg_fcfi;
1225 rc = lpfc_sli_issue_mbox(phba, fcf_mbxq, MBX_NOWAIT); 1230 rc = lpfc_sli_issue_mbox(phba, fcf_mbxq, MBX_NOWAIT);
1226 if (rc == MBX_NOT_FINISHED) 1231 if (rc == MBX_NOT_FINISHED) {
1232 spin_lock_irqsave(&phba->hbalock, flags);
1233 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1234 spin_unlock_irqrestore(&phba->hbalock, flags);
1227 mempool_free(fcf_mbxq, phba->mbox_mem_pool); 1235 mempool_free(fcf_mbxq, phba->mbox_mem_pool);
1236 }
1228 1237
1229 return; 1238 return;
1230} 1239}
@@ -1253,6 +1262,20 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1253 uint16_t *vlan_id) 1262 uint16_t *vlan_id)
1254{ 1263{
1255 struct lpfc_fcf_conn_entry *conn_entry; 1264 struct lpfc_fcf_conn_entry *conn_entry;
1265 int i, j, fcf_vlan_id = 0;
1266
1267 /* Find the lowest VLAN id in the FCF record */
1268 for (i = 0; i < 512; i++) {
1269 if (new_fcf_record->vlan_bitmap[i]) {
1270 fcf_vlan_id = i * 8;
1271 j = 0;
1272 while (!((new_fcf_record->vlan_bitmap[i] >> j) & 1)) {
1273 j++;
1274 fcf_vlan_id++;
1275 }
1276 break;
1277 }
1278 }
1256 1279
1257 /* If FCF not available return 0 */ 1280 /* If FCF not available return 0 */
1258 if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) || 1281 if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) ||
@@ -1286,7 +1309,11 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1286 if (*addr_mode & LPFC_FCF_FPMA) 1309 if (*addr_mode & LPFC_FCF_FPMA)
1287 *addr_mode = LPFC_FCF_FPMA; 1310 *addr_mode = LPFC_FCF_FPMA;
1288 1311
1289 *vlan_id = 0xFFFF; 1312 /* If FCF record report a vlan id use that vlan id */
1313 if (fcf_vlan_id)
1314 *vlan_id = fcf_vlan_id;
1315 else
1316 *vlan_id = 0xFFFF;
1290 return 1; 1317 return 1;
1291 } 1318 }
1292 1319
@@ -1384,8 +1411,15 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1384 (*addr_mode & LPFC_FCF_FPMA)) 1411 (*addr_mode & LPFC_FCF_FPMA))
1385 *addr_mode = LPFC_FCF_FPMA; 1412 *addr_mode = LPFC_FCF_FPMA;
1386 1413
1414 /* If matching connect list has a vlan id, use it */
1387 if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) 1415 if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID)
1388 *vlan_id = conn_entry->conn_rec.vlan_tag; 1416 *vlan_id = conn_entry->conn_rec.vlan_tag;
1417 /*
1418 * If no vlan id is specified in connect list, use the vlan id
1419 * in the FCF record
1420 */
1421 else if (fcf_vlan_id)
1422 *vlan_id = fcf_vlan_id;
1389 else 1423 else
1390 *vlan_id = 0xFFFF; 1424 *vlan_id = 0xFFFF;
1391 1425
@@ -1423,6 +1457,12 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
1423 1457
1424 if (phba->link_state >= LPFC_LINK_UP) 1458 if (phba->link_state >= LPFC_LINK_UP)
1425 lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); 1459 lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
1460 else
1461 /*
1462 * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS
1463 * flag
1464 */
1465 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1426 1466
1427 if (unreg_fcf) { 1467 if (unreg_fcf) {
1428 spin_lock_irq(&phba->hbalock); 1468 spin_lock_irq(&phba->hbalock);
@@ -2085,6 +2125,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2085 else 2125 else
2086 phba->sli.sli_flag &= ~LPFC_MENLO_MAINT; 2126 phba->sli.sli_flag &= ~LPFC_MENLO_MAINT;
2087 2127
2128 phba->link_events++;
2088 if (la->attType == AT_LINK_UP && (!la->mm)) { 2129 if (la->attType == AT_LINK_UP && (!la->mm)) {
2089 phba->fc_stat.LinkUp++; 2130 phba->fc_stat.LinkUp++;
2090 if (phba->link_flag & LS_LOOPBACK_MODE) { 2131 if (phba->link_flag & LS_LOOPBACK_MODE) {
@@ -4409,6 +4450,8 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
4409 if (lpfc_fcf_inuse(phba)) 4450 if (lpfc_fcf_inuse(phba))
4410 return; 4451 return;
4411 4452
4453 /* At this point, all discovery is aborted */
4454 phba->pport->port_state = LPFC_VPORT_UNKNOWN;
4412 4455
4413 /* Unregister VPIs */ 4456 /* Unregister VPIs */
4414 vports = lpfc_create_vport_work_array(phba); 4457 vports = lpfc_create_vport_work_array(phba);
@@ -4512,8 +4555,10 @@ lpfc_read_fcf_conn_tbl(struct lpfc_hba *phba,
4512 4555
4513 /* Free the current connect table */ 4556 /* Free the current connect table */
4514 list_for_each_entry_safe(conn_entry, next_conn_entry, 4557 list_for_each_entry_safe(conn_entry, next_conn_entry,
4515 &phba->fcf_conn_rec_list, list) 4558 &phba->fcf_conn_rec_list, list) {
4559 list_del_init(&conn_entry->list);
4516 kfree(conn_entry); 4560 kfree(conn_entry);
4561 }
4517 4562
4518 conn_hdr = (struct lpfc_fcf_conn_hdr *) buff; 4563 conn_hdr = (struct lpfc_fcf_conn_hdr *) buff;
4519 record_count = conn_hdr->length * sizeof(uint32_t)/ 4564 record_count = conn_hdr->length * sizeof(uint32_t)/