diff options
-rw-r--r-- | drivers/scsi/lpfc/lpfc_disc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 98 |
3 files changed, 79 insertions, 22 deletions
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 8932b1be2b60..41cf5d3ea6ce 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h | |||
@@ -113,6 +113,7 @@ struct lpfc_nodelist { | |||
113 | #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from | 113 | #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from |
114 | NPR list */ | 114 | NPR list */ |
115 | #define NLP_DELAY_REMOVE 0x4000000 /* Defer removal till end of DSM */ | 115 | #define NLP_DELAY_REMOVE 0x4000000 /* Defer removal till end of DSM */ |
116 | #define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ | ||
116 | 117 | ||
117 | /* Defines for list searchs */ | 118 | /* Defines for list searchs */ |
118 | #define NLP_SEARCH_MAPPED 0x1 /* search mapped */ | 119 | #define NLP_SEARCH_MAPPED 0x1 /* search mapped */ |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 6721e679df62..2a2e2eb406ac 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1238,6 +1238,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1238 | evt_listp); | 1238 | evt_listp); |
1239 | 1239 | ||
1240 | } | 1240 | } |
1241 | nlp->nlp_flag &= ~NLP_NODEV_REMOVE; | ||
1241 | nlp->nlp_type |= NLP_FC_NODE; | 1242 | nlp->nlp_type |= NLP_FC_NODE; |
1242 | break; | 1243 | break; |
1243 | case NLP_MAPPED_LIST: | 1244 | case NLP_MAPPED_LIST: |
@@ -1258,6 +1259,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1258 | evt_listp); | 1259 | evt_listp); |
1259 | 1260 | ||
1260 | } | 1261 | } |
1262 | nlp->nlp_flag &= ~NLP_NODEV_REMOVE; | ||
1261 | break; | 1263 | break; |
1262 | case NLP_NPR_LIST: | 1264 | case NLP_NPR_LIST: |
1263 | nlp->nlp_flag |= list; | 1265 | nlp->nlp_flag |= list; |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 3d77bd999b70..c48ec631a33b 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -832,11 +832,17 @@ static uint32_t | |||
832 | lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, | 832 | lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, |
833 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 833 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
834 | { | 834 | { |
835 | /* software abort outstanding PLOGI */ | 835 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
836 | lpfc_els_abort(phba, ndlp, 1); | 836 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
837 | return ndlp->nlp_state; | ||
838 | } | ||
839 | else { | ||
840 | /* software abort outstanding PLOGI */ | ||
841 | lpfc_els_abort(phba, ndlp, 1); | ||
837 | 842 | ||
838 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 843 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
839 | return NLP_STE_FREED_NODE; | 844 | return NLP_STE_FREED_NODE; |
845 | } | ||
840 | } | 846 | } |
841 | 847 | ||
842 | static uint32_t | 848 | static uint32_t |
@@ -851,7 +857,7 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, | |||
851 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 857 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
852 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 858 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
853 | spin_lock_irq(phba->host->host_lock); | 859 | spin_lock_irq(phba->host->host_lock); |
854 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 860 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
855 | spin_unlock_irq(phba->host->host_lock); | 861 | spin_unlock_irq(phba->host->host_lock); |
856 | 862 | ||
857 | return ndlp->nlp_state; | 863 | return ndlp->nlp_state; |
@@ -987,11 +993,17 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, | |||
987 | struct lpfc_nodelist * ndlp, void *arg, | 993 | struct lpfc_nodelist * ndlp, void *arg, |
988 | uint32_t evt) | 994 | uint32_t evt) |
989 | { | 995 | { |
990 | /* software abort outstanding ADISC */ | 996 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
991 | lpfc_els_abort(phba, ndlp, 1); | 997 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
998 | return ndlp->nlp_state; | ||
999 | } | ||
1000 | else { | ||
1001 | /* software abort outstanding ADISC */ | ||
1002 | lpfc_els_abort(phba, ndlp, 1); | ||
992 | 1003 | ||
993 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1004 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
994 | return NLP_STE_FREED_NODE; | 1005 | return NLP_STE_FREED_NODE; |
1006 | } | ||
995 | } | 1007 | } |
996 | 1008 | ||
997 | static uint32_t | 1009 | static uint32_t |
@@ -1006,7 +1018,7 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, | |||
1006 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1018 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1007 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1019 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1008 | spin_lock_irq(phba->host->host_lock); | 1020 | spin_lock_irq(phba->host->host_lock); |
1009 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1021 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1010 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 1022 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
1011 | spin_unlock_irq(phba->host->host_lock); | 1023 | spin_unlock_irq(phba->host->host_lock); |
1012 | 1024 | ||
@@ -1133,8 +1145,14 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, | |||
1133 | struct lpfc_nodelist * ndlp, void *arg, | 1145 | struct lpfc_nodelist * ndlp, void *arg, |
1134 | uint32_t evt) | 1146 | uint32_t evt) |
1135 | { | 1147 | { |
1136 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1148 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
1137 | return NLP_STE_FREED_NODE; | 1149 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
1150 | return ndlp->nlp_state; | ||
1151 | } | ||
1152 | else { | ||
1153 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
1154 | return NLP_STE_FREED_NODE; | ||
1155 | } | ||
1138 | } | 1156 | } |
1139 | 1157 | ||
1140 | static uint32_t | 1158 | static uint32_t |
@@ -1146,7 +1164,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, | |||
1146 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1164 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1147 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1165 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1148 | spin_lock_irq(phba->host->host_lock); | 1166 | spin_lock_irq(phba->host->host_lock); |
1149 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1167 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1150 | spin_unlock_irq(phba->host->host_lock); | 1168 | spin_unlock_irq(phba->host->host_lock); |
1151 | return ndlp->nlp_state; | 1169 | return ndlp->nlp_state; |
1152 | } | 1170 | } |
@@ -1278,11 +1296,17 @@ static uint32_t | |||
1278 | lpfc_device_rm_prli_issue(struct lpfc_hba * phba, | 1296 | lpfc_device_rm_prli_issue(struct lpfc_hba * phba, |
1279 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1297 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
1280 | { | 1298 | { |
1281 | /* software abort outstanding PRLI */ | 1299 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
1282 | lpfc_els_abort(phba, ndlp, 1); | 1300 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
1301 | return ndlp->nlp_state; | ||
1302 | } | ||
1303 | else { | ||
1304 | /* software abort outstanding PLOGI */ | ||
1305 | lpfc_els_abort(phba, ndlp, 1); | ||
1283 | 1306 | ||
1284 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1307 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1285 | return NLP_STE_FREED_NODE; | 1308 | return NLP_STE_FREED_NODE; |
1309 | } | ||
1286 | } | 1310 | } |
1287 | 1311 | ||
1288 | 1312 | ||
@@ -1313,7 +1337,7 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, | |||
1313 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1337 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1314 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1338 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1315 | spin_lock_irq(phba->host->host_lock); | 1339 | spin_lock_irq(phba->host->host_lock); |
1316 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1340 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1317 | spin_unlock_irq(phba->host->host_lock); | 1341 | spin_unlock_irq(phba->host->host_lock); |
1318 | return ndlp->nlp_state; | 1342 | return ndlp->nlp_state; |
1319 | } | 1343 | } |
@@ -1386,7 +1410,7 @@ lpfc_device_recov_unmap_node(struct lpfc_hba * phba, | |||
1386 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; | 1410 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; |
1387 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1411 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1388 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1412 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1389 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1413 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1390 | lpfc_disc_set_adisc(phba, ndlp); | 1414 | lpfc_disc_set_adisc(phba, ndlp); |
1391 | 1415 | ||
1392 | return ndlp->nlp_state; | 1416 | return ndlp->nlp_state; |
@@ -1469,7 +1493,7 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, | |||
1469 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1493 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1470 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1494 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1471 | spin_lock_irq(phba->host->host_lock); | 1495 | spin_lock_irq(phba->host->host_lock); |
1472 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1496 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1473 | spin_unlock_irq(phba->host->host_lock); | 1497 | spin_unlock_irq(phba->host->host_lock); |
1474 | lpfc_disc_set_adisc(phba, ndlp); | 1498 | lpfc_disc_set_adisc(phba, ndlp); |
1475 | return ndlp->nlp_state; | 1499 | return ndlp->nlp_state; |
@@ -1617,9 +1641,16 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, | |||
1617 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1641 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
1618 | { | 1642 | { |
1619 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1643 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1644 | IOCB_t *irsp; | ||
1620 | 1645 | ||
1621 | cmdiocb = (struct lpfc_iocbq *) arg; | 1646 | cmdiocb = (struct lpfc_iocbq *) arg; |
1622 | rspiocb = cmdiocb->context_un.rsp_iocb; | 1647 | rspiocb = cmdiocb->context_un.rsp_iocb; |
1648 | |||
1649 | irsp = &rspiocb->iocb; | ||
1650 | if (irsp->ulpStatus) { | ||
1651 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
1652 | return NLP_STE_FREED_NODE; | ||
1653 | } | ||
1623 | return ndlp->nlp_state; | 1654 | return ndlp->nlp_state; |
1624 | } | 1655 | } |
1625 | 1656 | ||
@@ -1628,9 +1659,16 @@ lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, | |||
1628 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1659 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
1629 | { | 1660 | { |
1630 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1661 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1662 | IOCB_t *irsp; | ||
1631 | 1663 | ||
1632 | cmdiocb = (struct lpfc_iocbq *) arg; | 1664 | cmdiocb = (struct lpfc_iocbq *) arg; |
1633 | rspiocb = cmdiocb->context_un.rsp_iocb; | 1665 | rspiocb = cmdiocb->context_un.rsp_iocb; |
1666 | |||
1667 | irsp = &rspiocb->iocb; | ||
1668 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { | ||
1669 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
1670 | return NLP_STE_FREED_NODE; | ||
1671 | } | ||
1634 | return ndlp->nlp_state; | 1672 | return ndlp->nlp_state; |
1635 | } | 1673 | } |
1636 | 1674 | ||
@@ -1649,9 +1687,16 @@ lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, | |||
1649 | uint32_t evt) | 1687 | uint32_t evt) |
1650 | { | 1688 | { |
1651 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1689 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1690 | IOCB_t *irsp; | ||
1652 | 1691 | ||
1653 | cmdiocb = (struct lpfc_iocbq *) arg; | 1692 | cmdiocb = (struct lpfc_iocbq *) arg; |
1654 | rspiocb = cmdiocb->context_un.rsp_iocb; | 1693 | rspiocb = cmdiocb->context_un.rsp_iocb; |
1694 | |||
1695 | irsp = &rspiocb->iocb; | ||
1696 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { | ||
1697 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
1698 | return NLP_STE_FREED_NODE; | ||
1699 | } | ||
1655 | return ndlp->nlp_state; | 1700 | return ndlp->nlp_state; |
1656 | } | 1701 | } |
1657 | 1702 | ||
@@ -1668,7 +1713,12 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, | |||
1668 | 1713 | ||
1669 | if (!mb->mbxStatus) | 1714 | if (!mb->mbxStatus) |
1670 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1715 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1671 | 1716 | else { | |
1717 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { | ||
1718 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
1719 | return NLP_STE_FREED_NODE; | ||
1720 | } | ||
1721 | } | ||
1672 | return ndlp->nlp_state; | 1722 | return ndlp->nlp_state; |
1673 | } | 1723 | } |
1674 | 1724 | ||
@@ -1677,6 +1727,10 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba, | |||
1677 | struct lpfc_nodelist * ndlp, void *arg, | 1727 | struct lpfc_nodelist * ndlp, void *arg, |
1678 | uint32_t evt) | 1728 | uint32_t evt) |
1679 | { | 1729 | { |
1730 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
1731 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | ||
1732 | return ndlp->nlp_state; | ||
1733 | } | ||
1680 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1734 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1681 | return NLP_STE_FREED_NODE; | 1735 | return NLP_STE_FREED_NODE; |
1682 | } | 1736 | } |
@@ -1687,7 +1741,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, | |||
1687 | uint32_t evt) | 1741 | uint32_t evt) |
1688 | { | 1742 | { |
1689 | spin_lock_irq(phba->host->host_lock); | 1743 | spin_lock_irq(phba->host->host_lock); |
1690 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1744 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1691 | spin_unlock_irq(phba->host->host_lock); | 1745 | spin_unlock_irq(phba->host->host_lock); |
1692 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1746 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1693 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1747 | lpfc_cancel_retry_delay_tmo(phba, ndlp); |