diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 122 |
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 | |||
1047 | static void | ||
1048 | lpfc_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 | */ |
2459 | struct lpfc_nodelist * | 2460 | struct lpfc_nodelist * |
2460 | lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) | 2461 | lpfc_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 | */ | ||
2477 | struct lpfc_nodelist * | ||
2478 | lpfc_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 | */ | ||
2512 | void | ||
2513 | lpfc_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 | ||
2525 | void | 2479 | void |