aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c122
1 files changed, 38 insertions, 84 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 56052f4510c3..259eeb161b82 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -890,10 +890,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
890 890
891 pmb->context1 = NULL; 891 pmb->context1 = NULL;
892 892
893 if (ndlp->nlp_rpi != 0)
894 lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
895 ndlp->nlp_rpi = mb->un.varWords[0]; 893 ndlp->nlp_rpi = mb->un.varWords[0];
896 lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
897 ndlp->nlp_type |= NLP_FABRIC; 894 ndlp->nlp_type |= NLP_FABRIC;
898 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; 895 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
899 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); 896 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -981,10 +978,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
981 978
982 pmb->context1 = NULL; 979 pmb->context1 = NULL;
983 980
984 if (ndlp->nlp_rpi != 0)
985 lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
986 ndlp->nlp_rpi = mb->un.varWords[0]; 981 ndlp->nlp_rpi = mb->un.varWords[0];
987 lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
988 ndlp->nlp_type |= NLP_FABRIC; 982 ndlp->nlp_type |= NLP_FABRIC;
989 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; 983 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
990 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); 984 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -1028,6 +1022,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
1028 if (ndlp->nlp_type & NLP_FCP_INITIATOR) 1022 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
1029 rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR; 1023 rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
1030 1024
1025 scsi_block_requests(phba->host);
1031 ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); 1026 ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
1032 if (!rport) { 1027 if (!rport) {
1033 dev_printk(KERN_WARNING, &phba->pcidev->dev, 1028 dev_printk(KERN_WARNING, &phba->pcidev->dev,
@@ -1044,6 +1039,23 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
1044 } 1039 }
1045 rdata = rport->dd_data; 1040 rdata = rport->dd_data;
1046 rdata->pnode = ndlp; 1041 rdata->pnode = ndlp;
1042 scsi_unblock_requests(phba->host);
1043
1044 return;
1045}
1046
1047static void
1048lpfc_unregister_remote_port(struct lpfc_hba * phba,
1049 struct lpfc_nodelist * ndlp)
1050{
1051 struct fc_rport *rport = ndlp->rport;
1052 struct lpfc_rport_data *rdata = rport->dd_data;
1053
1054 ndlp->rport = NULL;
1055 rdata->pnode = NULL;
1056 scsi_block_requests(phba->host);
1057 fc_remote_port_delete(rport);
1058 scsi_unblock_requests(phba->host);
1047 1059
1048 return; 1060 return;
1049} 1061}
@@ -1260,7 +1272,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1260 * may have removed the remote port. 1272 * may have removed the remote port.
1261 */ 1273 */
1262 if ((rport_del != none) && nlp->rport) 1274 if ((rport_del != none) && nlp->rport)
1263 fc_remote_port_block(nlp->rport); 1275 lpfc_unregister_remote_port(phba, nlp);
1264 1276
1265 if (rport_add != none) { 1277 if (rport_add != none) {
1266 /* 1278 /*
@@ -1270,8 +1282,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1270 */ 1282 */
1271 if (!nlp->rport) 1283 if (!nlp->rport)
1272 lpfc_register_remote_port(phba, nlp); 1284 lpfc_register_remote_port(phba, nlp);
1273 else
1274 fc_remote_port_unblock(nlp->rport);
1275 1285
1276 /* 1286 /*
1277 * if we added to Mapped list, but the remote port 1287 * if we added to Mapped list, but the remote port
@@ -1435,10 +1445,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1435 iocb, iocb); 1445 iocb, iocb);
1436 spin_lock_irq(phba->host-> 1446 spin_lock_irq(phba->host->
1437 host_lock); 1447 host_lock);
1438 } else { 1448 } else
1439 list_add_tail(&iocb->list, 1449 lpfc_sli_release_iocbq(phba,
1440 &phba->lpfc_iocb_list); 1450 iocb);
1441 }
1442 } 1451 }
1443 } 1452 }
1444 spin_unlock_irq(phba->host->host_lock); 1453 spin_unlock_irq(phba->host->host_lock);
@@ -1472,7 +1481,6 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1472 if (rc == MBX_NOT_FINISHED) 1481 if (rc == MBX_NOT_FINISHED)
1473 mempool_free( mbox, phba->mbox_mem_pool); 1482 mempool_free( mbox, phba->mbox_mem_pool);
1474 } 1483 }
1475 lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
1476 lpfc_no_rpi(phba, ndlp); 1484 lpfc_no_rpi(phba, ndlp);
1477 ndlp->nlp_rpi = 0; 1485 ndlp->nlp_rpi = 0;
1478 return 1; 1486 return 1;
@@ -1490,7 +1498,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1490 LPFC_MBOXQ_t *mb; 1498 LPFC_MBOXQ_t *mb;
1491 LPFC_MBOXQ_t *nextmb; 1499 LPFC_MBOXQ_t *nextmb;
1492 struct lpfc_dmabuf *mp; 1500 struct lpfc_dmabuf *mp;
1493 struct fc_rport *rport;
1494 1501
1495 /* Cleanup node for NPort <nlp_DID> */ 1502 /* Cleanup node for NPort <nlp_DID> */
1496 lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1503 lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
@@ -1507,10 +1514,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1507 * and flush cache's w/o generating flush errors. 1514 * and flush cache's w/o generating flush errors.
1508 */ 1515 */
1509 if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { 1516 if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
1510 rport = ndlp->rport; 1517 lpfc_unregister_remote_port(phba, ndlp);
1511 ndlp->rport = NULL;
1512 fc_remote_port_unblock(rport);
1513 fc_remote_port_delete(rport);
1514 ndlp->nlp_sid = NLP_NO_SID; 1518 ndlp->nlp_sid = NLP_NO_SID;
1515 } 1519 }
1516 1520
@@ -2422,10 +2426,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
2422 2426
2423 pmb->context1 = NULL; 2427 pmb->context1 = NULL;
2424 2428
2425 if (ndlp->nlp_rpi != 0)
2426 lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
2427 ndlp->nlp_rpi = mb->un.varWords[0]; 2429 ndlp->nlp_rpi = mb->un.varWords[0];
2428 lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
2429 ndlp->nlp_type |= NLP_FABRIC; 2430 ndlp->nlp_type |= NLP_FABRIC;
2430 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; 2431 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
2431 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); 2432 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -2451,75 +2452,28 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
2451} 2452}
2452 2453
2453/* 2454/*
2454 * This routine looks up the ndlp hash 2455 * This routine looks up the ndlp lists
2455 * table for the given RPI. If rpi found 2456 * for the given RPI. If rpi found
2456 * it return the node list pointer 2457 * it return the node list pointer
2457 * else return 0. 2458 * else return NULL.
2458 */ 2459 */
2459struct lpfc_nodelist * 2460struct lpfc_nodelist *
2460lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) 2461lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
2461{ 2462{
2462 struct lpfc_nodelist *ret; 2463 struct lpfc_nodelist *ndlp;
2463 2464 struct list_head * lists[]={&phba->fc_nlpunmap_list,
2464 ret = phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)]; 2465 &phba->fc_nlpmap_list,
2465 while ((ret != 0) && (ret->nlp_rpi != rpi)) { 2466 &phba->fc_plogi_list,
2466 ret = ret->nlp_rpi_hash_next; 2467 &phba->fc_adisc_list,
2467 } 2468 &phba->fc_reglogin_list};
2468 return ret; 2469 int i;
2469}
2470
2471/*
2472 * This routine looks up the ndlp hash table for the
2473 * given RPI. If rpi found it return the node list
2474 * pointer else return 0 after deleting the entry
2475 * from hash table.
2476 */
2477struct lpfc_nodelist *
2478lpfc_findnode_remove_rpi(struct lpfc_hba * phba, uint16_t rpi)
2479{
2480 struct lpfc_nodelist *ret, *temp;;
2481
2482 ret = phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)];
2483 if (ret == 0)
2484 return NULL;
2485
2486 if (ret->nlp_rpi == rpi) {
2487 phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)] =
2488 ret->nlp_rpi_hash_next;
2489 ret->nlp_rpi_hash_next = NULL;
2490 return ret;
2491 }
2492
2493 while ((ret->nlp_rpi_hash_next != 0) &&
2494 (ret->nlp_rpi_hash_next->nlp_rpi != rpi)) {
2495 ret = ret->nlp_rpi_hash_next;
2496 }
2497
2498 if (ret->nlp_rpi_hash_next != 0) {
2499 temp = ret->nlp_rpi_hash_next;
2500 ret->nlp_rpi_hash_next = temp->nlp_rpi_hash_next;
2501 temp->nlp_rpi_hash_next = NULL;
2502 return temp;
2503 } else {
2504 return NULL;
2505 }
2506}
2507
2508/*
2509 * This routine adds the node list entry to the
2510 * ndlp hash table.
2511 */
2512void
2513lpfc_addnode_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
2514 uint16_t rpi)
2515{
2516 2470
2517 uint32_t index; 2471 for (i = 0; i < ARRAY_SIZE(lists); i++ )
2472 list_for_each_entry(ndlp, lists[i], nlp_listp)
2473 if (ndlp->nlp_rpi == rpi)
2474 return (ndlp);
2518 2475
2519 index = LPFC_RPI_HASH_FUNC(rpi); 2476 return NULL;
2520 ndlp->nlp_rpi_hash_next = phba->fc_nlplookup[index];
2521 phba->fc_nlplookup[index] = ndlp;
2522 return;
2523} 2477}
2524 2478
2525void 2479void