Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] lpfc 8.1.11 : Discovery Fixes

Discovery Fixes:
- Prevent starting discovery of a node if discovery is in progress.
- Code improvement (reduction) for lpfc_findnode_did().
- Update discovery to send RFF to Fabric on link up
- Bypass unique WWN checks for fabric addresses
- Add ndlp to plogi list prior to issuing the plogi els command

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by

James Smart and committed by
James Bottomley
2fb9bd8b 0e5d030b

+73 -175
+23 -1
drivers/scsi/lpfc/lpfc_ct.c
··· 558 558 return; 559 559 } 560 560 561 + static void 562 + lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, 563 + struct lpfc_iocbq * rspiocb) 564 + { 565 + lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); 566 + return; 567 + } 568 + 561 569 void 562 570 lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) 563 571 { ··· 637 629 bpl->tus.f.bdeSize = RNN_REQUEST_SZ; 638 630 else if (cmdcode == SLI_CTNS_RSNN_NN) 639 631 bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; 632 + else if (cmdcode == SLI_CTNS_RFF_ID) 633 + bpl->tus.f.bdeSize = RFF_REQUEST_SZ; 640 634 else 641 635 bpl->tus.f.bdeSize = 0; 642 636 bpl->tus.w = le32_to_cpu(bpl->tus.w); ··· 668 658 CtReq->un.rft.PortId = be32_to_cpu(phba->fc_myDID); 669 659 CtReq->un.rft.fcpReg = 1; 670 660 cmpl = lpfc_cmpl_ct_cmd_rft_id; 661 + break; 662 + 663 + case SLI_CTNS_RFF_ID: 664 + CtReq->CommandResponse.bits.CmdRsp = 665 + be16_to_cpu(SLI_CTNS_RFF_ID); 666 + CtReq->un.rff.PortId = be32_to_cpu(phba->fc_myDID); 667 + CtReq->un.rff.feature_res = 0; 668 + CtReq->un.rff.feature_tgt = 0; 669 + CtReq->un.rff.type_code = FC_FCP_DATA; 670 + CtReq->un.rff.feature_init = 1; 671 + cmpl = lpfc_cmpl_ct_cmd_rff_id; 671 672 break; 672 673 673 674 case SLI_CTNS_RNN_ID: ··· 955 934 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); 956 935 ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION); 957 936 sprintf(ae->un.OsNameVersion, "%s %s %s", 958 - init_utsname()->sysname, init_utsname()->release, 937 + init_utsname()->sysname, 938 + init_utsname()->release, 959 939 init_utsname()->version); 960 940 len = strlen(ae->un.OsNameVersion); 961 941 len += (len & 3) ? (4 - (len & 3)) : 4;
+7
drivers/scsi/lpfc/lpfc_els.c
··· 657 657 uint8_t name[sizeof (struct lpfc_name)]; 658 658 uint32_t rc; 659 659 660 + /* Fabric nodes can have the same WWPN so we don't bother searching 661 + * by WWPN. Just return the ndlp that was given to us. 662 + */ 663 + if (ndlp->nlp_type & NLP_FABRIC) 664 + return ndlp; 665 + 660 666 lp = (uint32_t *) prsp->virt; 661 667 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); 662 668 memset(name, 0, sizeof (struct lpfc_name)); ··· 2650 2644 ndlp->nlp_type |= NLP_FABRIC; 2651 2645 ndlp->nlp_prev_state = ndlp->nlp_state; 2652 2646 ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; 2647 + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); 2653 2648 lpfc_issue_els_plogi(phba, NameServer_DID, 0); 2654 2649 /* Wait for NameServer login cmpl before we can 2655 2650 continue */
+25 -172
drivers/scsi/lpfc/lpfc_hbadisc.c
··· 1067 1067 lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID); 1068 1068 lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN); 1069 1069 lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID); 1070 + lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFF_ID); 1070 1071 } 1071 1072 1072 1073 phba->fc_ns_retry = 0; ··· 1681 1680 struct lpfc_nodelist * 1682 1681 lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) 1683 1682 { 1684 - struct lpfc_nodelist *ndlp, *next_ndlp; 1683 + struct lpfc_nodelist *ndlp; 1684 + struct list_head *lists[]={&phba->fc_nlpunmap_list, 1685 + &phba->fc_nlpmap_list, 1686 + &phba->fc_plogi_list, 1687 + &phba->fc_adisc_list, 1688 + &phba->fc_reglogin_list, 1689 + &phba->fc_prli_list, 1690 + &phba->fc_npr_list, 1691 + &phba->fc_unused_list}; 1692 + uint32_t search[]={NLP_SEARCH_UNMAPPED, 1693 + NLP_SEARCH_MAPPED, 1694 + NLP_SEARCH_PLOGI, 1695 + NLP_SEARCH_ADISC, 1696 + NLP_SEARCH_REGLOGIN, 1697 + NLP_SEARCH_PRLI, 1698 + NLP_SEARCH_NPR, 1699 + NLP_SEARCH_UNUSED}; 1700 + int i; 1685 1701 uint32_t data1; 1686 1702 1687 1703 spin_lock_irq(phba->host->host_lock); 1688 - if (order & NLP_SEARCH_UNMAPPED) { 1689 - list_for_each_entry_safe(ndlp, next_ndlp, 1690 - &phba->fc_nlpunmap_list, nlp_listp) { 1704 + for (i = 0; i < ARRAY_SIZE(lists); i++ ) { 1705 + if (!(order & search[i])) 1706 + continue; 1707 + list_for_each_entry(ndlp, lists[i], nlp_listp) { 1691 1708 if (lpfc_matchdid(phba, ndlp, did)) { 1692 1709 data1 = (((uint32_t) ndlp->nlp_state << 24) | 1693 1710 ((uint32_t) ndlp->nlp_xri << 16) | 1694 1711 ((uint32_t) ndlp->nlp_type << 8) | 1695 1712 ((uint32_t) ndlp->nlp_rpi & 0xff)); 1696 - /* FIND node DID unmapped */ 1697 1713 lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1698 - "%d:0929 FIND node DID unmapped" 1714 + "%d:0929 FIND node DID " 1699 1715 " Data: x%p x%x x%x x%x\n", 1700 1716 phba->brd_no, 1701 1717 ndlp, ndlp->nlp_DID, ··· 1722 1704 } 1723 1705 } 1724 1706 } 1725 - 1726 - if (order & NLP_SEARCH_MAPPED) { 1727 - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list, 1728 - nlp_listp) { 1729 - if (lpfc_matchdid(phba, ndlp, did)) { 1730 - 1731 - data1 = (((uint32_t) ndlp->nlp_state << 24) | 1732 - ((uint32_t) ndlp->nlp_xri << 16) | 1733 - ((uint32_t) ndlp->nlp_type << 8) | 1734 - ((uint32_t) ndlp->nlp_rpi & 0xff)); 1735 - /* FIND node DID mapped */ 1736 - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1737 - "%d:0930 FIND node DID mapped " 1738 - "Data: x%p x%x x%x x%x\n", 1739 - phba->brd_no, 1740 - ndlp, ndlp->nlp_DID, 1741 - ndlp->nlp_flag, data1); 1742 - spin_unlock_irq(phba->host->host_lock); 1743 - return ndlp; 1744 - } 1745 - } 1746 - } 1747 - 1748 - if (order & NLP_SEARCH_PLOGI) { 1749 - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, 1750 - nlp_listp) { 1751 - if (lpfc_matchdid(phba, ndlp, did)) { 1752 - 1753 - data1 = (((uint32_t) ndlp->nlp_state << 24) | 1754 - ((uint32_t) ndlp->nlp_xri << 16) | 1755 - ((uint32_t) ndlp->nlp_type << 8) | 1756 - ((uint32_t) ndlp->nlp_rpi & 0xff)); 1757 - /* LOG change to PLOGI */ 1758 - /* FIND node DID plogi */ 1759 - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1760 - "%d:0908 FIND node DID plogi " 1761 - "Data: x%p x%x x%x x%x\n", 1762 - phba->brd_no, 1763 - ndlp, ndlp->nlp_DID, 1764 - ndlp->nlp_flag, data1); 1765 - spin_unlock_irq(phba->host->host_lock); 1766 - return ndlp; 1767 - } 1768 - } 1769 - } 1770 - 1771 - if (order & NLP_SEARCH_ADISC) { 1772 - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, 1773 - nlp_listp) { 1774 - if (lpfc_matchdid(phba, ndlp, did)) { 1775 - 1776 - data1 = (((uint32_t) ndlp->nlp_state << 24) | 1777 - ((uint32_t) ndlp->nlp_xri << 16) | 1778 - ((uint32_t) ndlp->nlp_type << 8) | 1779 - ((uint32_t) ndlp->nlp_rpi & 0xff)); 1780 - /* LOG change to ADISC */ 1781 - /* FIND node DID adisc */ 1782 - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1783 - "%d:0931 FIND node DID adisc " 1784 - "Data: x%p x%x x%x x%x\n", 1785 - phba->brd_no, 1786 - ndlp, ndlp->nlp_DID, 1787 - ndlp->nlp_flag, data1); 1788 - spin_unlock_irq(phba->host->host_lock); 1789 - return ndlp; 1790 - } 1791 - } 1792 - } 1793 - 1794 - if (order & NLP_SEARCH_REGLOGIN) { 1795 - list_for_each_entry_safe(ndlp, next_ndlp, 1796 - &phba->fc_reglogin_list, nlp_listp) { 1797 - if (lpfc_matchdid(phba, ndlp, did)) { 1798 - 1799 - data1 = (((uint32_t) ndlp->nlp_state << 24) | 1800 - ((uint32_t) ndlp->nlp_xri << 16) | 1801 - ((uint32_t) ndlp->nlp_type << 8) | 1802 - ((uint32_t) ndlp->nlp_rpi & 0xff)); 1803 - /* LOG change to REGLOGIN */ 1804 - /* FIND node DID reglogin */ 1805 - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1806 - "%d:0901 FIND node DID reglogin" 1807 - " Data: x%p x%x x%x x%x\n", 1808 - phba->brd_no, 1809 - ndlp, ndlp->nlp_DID, 1810 - ndlp->nlp_flag, data1); 1811 - spin_unlock_irq(phba->host->host_lock); 1812 - return ndlp; 1813 - } 1814 - } 1815 - } 1816 - 1817 - if (order & NLP_SEARCH_PRLI) { 1818 - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list, 1819 - nlp_listp) { 1820 - if (lpfc_matchdid(phba, ndlp, did)) { 1821 - 1822 - data1 = (((uint32_t) ndlp->nlp_state << 24) | 1823 - ((uint32_t) ndlp->nlp_xri << 16) | 1824 - ((uint32_t) ndlp->nlp_type << 8) | 1825 - ((uint32_t) ndlp->nlp_rpi & 0xff)); 1826 - /* LOG change to PRLI */ 1827 - /* FIND node DID prli */ 1828 - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1829 - "%d:0902 FIND node DID prli " 1830 - "Data: x%p x%x x%x x%x\n", 1831 - phba->brd_no, 1832 - ndlp, ndlp->nlp_DID, 1833 - ndlp->nlp_flag, data1); 1834 - spin_unlock_irq(phba->host->host_lock); 1835 - return ndlp; 1836 - } 1837 - } 1838 - } 1839 - 1840 - if (order & NLP_SEARCH_NPR) { 1841 - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, 1842 - nlp_listp) { 1843 - if (lpfc_matchdid(phba, ndlp, did)) { 1844 - 1845 - data1 = (((uint32_t) ndlp->nlp_state << 24) | 1846 - ((uint32_t) ndlp->nlp_xri << 16) | 1847 - ((uint32_t) ndlp->nlp_type << 8) | 1848 - ((uint32_t) ndlp->nlp_rpi & 0xff)); 1849 - /* LOG change to NPR */ 1850 - /* FIND node DID npr */ 1851 - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1852 - "%d:0903 FIND node DID npr " 1853 - "Data: x%p x%x x%x x%x\n", 1854 - phba->brd_no, 1855 - ndlp, ndlp->nlp_DID, 1856 - ndlp->nlp_flag, data1); 1857 - spin_unlock_irq(phba->host->host_lock); 1858 - return ndlp; 1859 - } 1860 - } 1861 - } 1862 - 1863 - if (order & NLP_SEARCH_UNUSED) { 1864 - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, 1865 - nlp_listp) { 1866 - if (lpfc_matchdid(phba, ndlp, did)) { 1867 - 1868 - data1 = (((uint32_t) ndlp->nlp_state << 24) | 1869 - ((uint32_t) ndlp->nlp_xri << 16) | 1870 - ((uint32_t) ndlp->nlp_type << 8) | 1871 - ((uint32_t) ndlp->nlp_rpi & 0xff)); 1872 - /* LOG change to UNUSED */ 1873 - /* FIND node DID unused */ 1874 - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1875 - "%d:0905 FIND node DID unused " 1876 - "Data: x%p x%x x%x x%x\n", 1877 - phba->brd_no, 1878 - ndlp, ndlp->nlp_DID, 1879 - ndlp->nlp_flag, data1); 1880 - spin_unlock_irq(phba->host->host_lock); 1881 - return ndlp; 1882 - } 1883 - } 1884 - } 1885 - 1886 1707 spin_unlock_irq(phba->host->host_lock); 1887 1708 1888 1709 /* FIND node did <did> NOT FOUND */ 1889 - lpfc_printf_log(phba, 1890 - KERN_INFO, 1891 - LOG_NODE, 1710 + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1892 1711 "%d:0932 FIND node did x%x NOT FOUND Data: x%x\n", 1893 1712 phba->brd_no, did, order); 1894 - 1895 - /* no match found */ 1896 1713 return NULL; 1897 1714 } 1898 1715
+16
drivers/scsi/lpfc/lpfc_hw.h
··· 121 121 122 122 uint32_t rsvd[7]; 123 123 } rft; 124 + struct rff { 125 + uint32_t PortId; 126 + uint8_t reserved[2]; 127 + #ifdef __BIG_ENDIAN_BITFIELD 128 + uint8_t feature_res:6; 129 + uint8_t feature_init:1; 130 + uint8_t feature_tgt:1; 131 + #else /* __LITTLE_ENDIAN_BITFIELD */ 132 + uint8_t feature_tgt:1; 133 + uint8_t feature_init:1; 134 + uint8_t feature_res:6; 135 + #endif 136 + uint8_t type_code; /* type=8 for FCP */ 137 + } rff; 124 138 struct rnn { 125 139 uint32_t PortId; /* For RNN_ID requests */ 126 140 uint8_t wwnn[8]; ··· 150 136 #define SLI_CT_REVISION 1 151 137 #define GID_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 260) 152 138 #define RFT_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 228) 139 + #define RFF_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 235) 153 140 #define RNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 252) 154 141 #define RSNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request)) 155 142 ··· 240 225 #define SLI_CTNS_RNN_ID 0x0213 241 226 #define SLI_CTNS_RCS_ID 0x0214 242 227 #define SLI_CTNS_RFT_ID 0x0217 228 + #define SLI_CTNS_RFF_ID 0x021F 243 229 #define SLI_CTNS_RSPN_ID 0x0218 244 230 #define SLI_CTNS_RPT_ID 0x021A 245 231 #define SLI_CTNS_RIP_NN 0x0235
+2 -2
drivers/scsi/lpfc/lpfc_nportdisc.c
··· 1620 1620 * or discovery in progress for this node. Starting discovery 1621 1621 * here will affect the counting of discovery threads. 1622 1622 */ 1623 - if ((!(ndlp->nlp_flag & NLP_DELAY_TMO)) && 1624 - (ndlp->nlp_flag & NLP_NPR_2B_DISC)){ 1623 + if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && 1624 + !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){ 1625 1625 if (ndlp->nlp_flag & NLP_NPR_ADISC) { 1626 1626 ndlp->nlp_prev_state = NLP_STE_NPR_NODE; 1627 1627 ndlp->nlp_state = NLP_STE_ADISC_ISSUE;