diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/lpfc/lpfc_mbox.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mbox.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 147 |
1 files changed, 128 insertions, 19 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 1ab405902a18..72e6adb0643e 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -21,12 +21,13 @@ | |||
21 | 21 | ||
22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/slab.h> | ||
24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
25 | 26 | ||
26 | #include <scsi/scsi_device.h> | 27 | #include <scsi/scsi_device.h> |
27 | #include <scsi/scsi_transport_fc.h> | 28 | #include <scsi/scsi_transport_fc.h> |
28 | |||
29 | #include <scsi/scsi.h> | 29 | #include <scsi/scsi.h> |
30 | #include <scsi/fc/fc_fs.h> | ||
30 | 31 | ||
31 | #include "lpfc_hw4.h" | 32 | #include "lpfc_hw4.h" |
32 | #include "lpfc_hw.h" | 33 | #include "lpfc_hw.h" |
@@ -820,6 +821,10 @@ lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb) | |||
820 | mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base; | 821 | mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base; |
821 | mb->un.varRegVpi.sid = vport->fc_myDID; | 822 | mb->un.varRegVpi.sid = vport->fc_myDID; |
822 | mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base; | 823 | mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base; |
824 | memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname, | ||
825 | sizeof(struct lpfc_name)); | ||
826 | mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]); | ||
827 | mb->un.varRegVpi.wwn[1] = cpu_to_le32(mb->un.varRegVpi.wwn[1]); | ||
823 | 828 | ||
824 | mb->mbxCommand = MBX_REG_VPI; | 829 | mb->mbxCommand = MBX_REG_VPI; |
825 | mb->mbxOwner = OWN_HOST; | 830 | mb->mbxOwner = OWN_HOST; |
@@ -849,7 +854,10 @@ lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) | |||
849 | MAILBOX_t *mb = &pmb->u.mb; | 854 | MAILBOX_t *mb = &pmb->u.mb; |
850 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 855 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
851 | 856 | ||
852 | mb->un.varUnregVpi.vpi = vpi + phba->vpi_base; | 857 | if (phba->sli_rev < LPFC_SLI_REV4) |
858 | mb->un.varUnregVpi.vpi = vpi + phba->vpi_base; | ||
859 | else | ||
860 | mb->un.varUnregVpi.sli4_vpi = vpi + phba->vpi_base; | ||
853 | 861 | ||
854 | mb->mbxCommand = MBX_UNREG_VPI; | 862 | mb->mbxCommand = MBX_UNREG_VPI; |
855 | mb->mbxOwner = OWN_HOST; | 863 | mb->mbxOwner = OWN_HOST; |
@@ -1132,7 +1140,7 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) | |||
1132 | /* Otherwise we setup specific rctl / type masks for this ring */ | 1140 | /* Otherwise we setup specific rctl / type masks for this ring */ |
1133 | for (i = 0; i < pring->num_mask; i++) { | 1141 | for (i = 0; i < pring->num_mask; i++) { |
1134 | mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl; | 1142 | mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl; |
1135 | if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ) | 1143 | if (mb->un.varCfgRing.rrRegs[i].rval != FC_RCTL_ELS_REQ) |
1136 | mb->un.varCfgRing.rrRegs[i].rmask = 0xff; | 1144 | mb->un.varCfgRing.rrRegs[i].rmask = 0xff; |
1137 | else | 1145 | else |
1138 | mb->un.varCfgRing.rrRegs[i].rmask = 0xfe; | 1146 | mb->un.varCfgRing.rrRegs[i].rmask = 0xfe; |
@@ -1654,9 +1662,12 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox, | |||
1654 | /* Allocate record for keeping SGE virtual addresses */ | 1662 | /* Allocate record for keeping SGE virtual addresses */ |
1655 | mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt), | 1663 | mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt), |
1656 | GFP_KERNEL); | 1664 | GFP_KERNEL); |
1657 | if (!mbox->sge_array) | 1665 | if (!mbox->sge_array) { |
1666 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
1667 | "2527 Failed to allocate non-embedded SGE " | ||
1668 | "array.\n"); | ||
1658 | return 0; | 1669 | return 0; |
1659 | 1670 | } | |
1660 | for (pagen = 0, alloc_len = 0; pagen < pcount; pagen++) { | 1671 | for (pagen = 0, alloc_len = 0; pagen < pcount; pagen++) { |
1661 | /* The DMA memory is always allocated in the length of a | 1672 | /* The DMA memory is always allocated in the length of a |
1662 | * page even though the last SGE might not fill up to a | 1673 | * page even though the last SGE might not fill up to a |
@@ -1697,7 +1708,8 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox, | |||
1697 | alloc_len - sizeof(union lpfc_sli4_cfg_shdr); | 1708 | alloc_len - sizeof(union lpfc_sli4_cfg_shdr); |
1698 | } | 1709 | } |
1699 | /* The sub-header is in DMA memory, which needs endian converstion */ | 1710 | /* The sub-header is in DMA memory, which needs endian converstion */ |
1700 | lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr, | 1711 | if (cfg_shdr) |
1712 | lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr, | ||
1701 | sizeof(union lpfc_sli4_cfg_shdr)); | 1713 | sizeof(union lpfc_sli4_cfg_shdr)); |
1702 | 1714 | ||
1703 | return alloc_len; | 1715 | return alloc_len; |
@@ -1737,6 +1749,65 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | |||
1737 | } | 1749 | } |
1738 | 1750 | ||
1739 | /** | 1751 | /** |
1752 | * lpfc_sli4_mbx_read_fcf_rec - Allocate and construct read fcf mbox cmd | ||
1753 | * @phba: pointer to lpfc hba data structure. | ||
1754 | * @fcf_index: index to fcf table. | ||
1755 | * | ||
1756 | * This routine routine allocates and constructs non-embedded mailbox command | ||
1757 | * for reading a FCF table entry refered by @fcf_index. | ||
1758 | * | ||
1759 | * Return: pointer to the mailbox command constructed if successful, otherwise | ||
1760 | * NULL. | ||
1761 | **/ | ||
1762 | int | ||
1763 | lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba, | ||
1764 | struct lpfcMboxq *mboxq, | ||
1765 | uint16_t fcf_index) | ||
1766 | { | ||
1767 | void *virt_addr; | ||
1768 | dma_addr_t phys_addr; | ||
1769 | uint8_t *bytep; | ||
1770 | struct lpfc_mbx_sge sge; | ||
1771 | uint32_t alloc_len, req_len; | ||
1772 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | ||
1773 | |||
1774 | if (!mboxq) | ||
1775 | return -ENOMEM; | ||
1776 | |||
1777 | req_len = sizeof(struct fcf_record) + | ||
1778 | sizeof(union lpfc_sli4_cfg_shdr) + 2 * sizeof(uint32_t); | ||
1779 | |||
1780 | /* Set up READ_FCF SLI4_CONFIG mailbox-ioctl command */ | ||
1781 | alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
1782 | LPFC_MBOX_OPCODE_FCOE_READ_FCF_TABLE, req_len, | ||
1783 | LPFC_SLI4_MBX_NEMBED); | ||
1784 | |||
1785 | if (alloc_len < req_len) { | ||
1786 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
1787 | "0291 Allocated DMA memory size (x%x) is " | ||
1788 | "less than the requested DMA memory " | ||
1789 | "size (x%x)\n", alloc_len, req_len); | ||
1790 | return -ENOMEM; | ||
1791 | } | ||
1792 | |||
1793 | /* Get the first SGE entry from the non-embedded DMA memory. This | ||
1794 | * routine only uses a single SGE. | ||
1795 | */ | ||
1796 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
1797 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
1798 | virt_addr = mboxq->sge_array->addr[0]; | ||
1799 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | ||
1800 | |||
1801 | /* Set up command fields */ | ||
1802 | bf_set(lpfc_mbx_read_fcf_tbl_indx, &read_fcf->u.request, fcf_index); | ||
1803 | /* Perform necessary endian conversion */ | ||
1804 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
1805 | lpfc_sli_pcimem_bcopy(bytep, bytep, sizeof(uint32_t)); | ||
1806 | |||
1807 | return 0; | ||
1808 | } | ||
1809 | |||
1810 | /** | ||
1740 | * lpfc_request_features: Configure SLI4 REQUEST_FEATURES mailbox | 1811 | * lpfc_request_features: Configure SLI4 REQUEST_FEATURES mailbox |
1741 | * @mboxq: pointer to lpfc mbox command. | 1812 | * @mboxq: pointer to lpfc mbox command. |
1742 | * | 1813 | * |
@@ -1753,11 +1824,6 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq) | |||
1753 | /* Set up host requested features. */ | 1824 | /* Set up host requested features. */ |
1754 | bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1); | 1825 | bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1); |
1755 | 1826 | ||
1756 | if (phba->cfg_enable_fip) | ||
1757 | bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0); | ||
1758 | else | ||
1759 | bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 1); | ||
1760 | |||
1761 | /* Enable DIF (block guard) only if configured to do so. */ | 1827 | /* Enable DIF (block guard) only if configured to do so. */ |
1762 | if (phba->cfg_enable_bg) | 1828 | if (phba->cfg_enable_bg) |
1763 | bf_set(lpfc_mbx_rq_ftr_rq_dif, &mboxq->u.mqe.un.req_ftrs, 1); | 1829 | bf_set(lpfc_mbx_rq_ftr_rq_dif, &mboxq->u.mqe.un.req_ftrs, 1); |
@@ -1817,6 +1883,9 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) | |||
1817 | bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base); | 1883 | bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base); |
1818 | bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi); | 1884 | bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi); |
1819 | bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base); | 1885 | bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base); |
1886 | memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name)); | ||
1887 | reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]); | ||
1888 | reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]); | ||
1820 | reg_vfi->bde.addrHigh = putPaddrHigh(phys); | 1889 | reg_vfi->bde.addrHigh = putPaddrHigh(phys); |
1821 | reg_vfi->bde.addrLow = putPaddrLow(phys); | 1890 | reg_vfi->bde.addrLow = putPaddrLow(phys); |
1822 | reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam); | 1891 | reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam); |
@@ -1850,7 +1919,7 @@ lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi) | |||
1850 | /** | 1919 | /** |
1851 | * lpfc_unreg_vfi - Initialize the UNREG_VFI mailbox command | 1920 | * lpfc_unreg_vfi - Initialize the UNREG_VFI mailbox command |
1852 | * @mbox: pointer to lpfc mbox command to initialize. | 1921 | * @mbox: pointer to lpfc mbox command to initialize. |
1853 | * @vfi: VFI to be unregistered. | 1922 | * @vport: vport associated with the VF. |
1854 | * | 1923 | * |
1855 | * The UNREG_VFI mailbox command causes the SLI Host to put a virtual fabric | 1924 | * The UNREG_VFI mailbox command causes the SLI Host to put a virtual fabric |
1856 | * (logical NPort) into the inactive state. The SLI Host must have logged out | 1925 | * (logical NPort) into the inactive state. The SLI Host must have logged out |
@@ -1859,11 +1928,12 @@ lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi) | |||
1859 | * fabric inactive. | 1928 | * fabric inactive. |
1860 | **/ | 1929 | **/ |
1861 | void | 1930 | void |
1862 | lpfc_unreg_vfi(struct lpfcMboxq *mbox, uint16_t vfi) | 1931 | lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport) |
1863 | { | 1932 | { |
1864 | memset(mbox, 0, sizeof(*mbox)); | 1933 | memset(mbox, 0, sizeof(*mbox)); |
1865 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI); | 1934 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI); |
1866 | bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, vfi); | 1935 | bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, |
1936 | vport->vfi + vport->phba->vfi_base); | ||
1867 | } | 1937 | } |
1868 | 1938 | ||
1869 | /** | 1939 | /** |
@@ -1937,13 +2007,14 @@ lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | |||
1937 | bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID); | 2007 | bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID); |
1938 | bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID); | 2008 | bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID); |
1939 | bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID); | 2009 | bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID); |
1940 | bf_set(lpfc_reg_fcfi_info_index, reg_fcfi, phba->fcf.fcf_indx); | 2010 | bf_set(lpfc_reg_fcfi_info_index, reg_fcfi, |
2011 | phba->fcf.current_rec.fcf_indx); | ||
1941 | /* reg_fcf addr mode is bit wise inverted value of fcf addr_mode */ | 2012 | /* reg_fcf addr mode is bit wise inverted value of fcf addr_mode */ |
1942 | bf_set(lpfc_reg_fcfi_mam, reg_fcfi, | 2013 | bf_set(lpfc_reg_fcfi_mam, reg_fcfi, (~phba->fcf.addr_mode) & 0x3); |
1943 | (~phba->fcf.addr_mode) & 0x3); | 2014 | if (phba->fcf.current_rec.vlan_id != 0xFFFF) { |
1944 | if (phba->fcf.fcf_flag & FCF_VALID_VLAN) { | ||
1945 | bf_set(lpfc_reg_fcfi_vv, reg_fcfi, 1); | 2015 | bf_set(lpfc_reg_fcfi_vv, reg_fcfi, 1); |
1946 | bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi, phba->fcf.vlan_id); | 2016 | bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi, |
2017 | phba->fcf.current_rec.vlan_id); | ||
1947 | } | 2018 | } |
1948 | } | 2019 | } |
1949 | 2020 | ||
@@ -1983,3 +2054,41 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp) | |||
1983 | bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI); | 2054 | bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI); |
1984 | resume_rpi->event_tag = ndlp->phba->fc_eventTag; | 2055 | resume_rpi->event_tag = ndlp->phba->fc_eventTag; |
1985 | } | 2056 | } |
2057 | |||
2058 | /** | ||
2059 | * lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages | ||
2060 | * mailbox command. | ||
2061 | * @mbox: pointer to lpfc mbox command to initialize. | ||
2062 | * | ||
2063 | * The PORT_CAPABILITIES supported pages mailbox command is issued to | ||
2064 | * retrieve the particular feature pages supported by the port. | ||
2065 | **/ | ||
2066 | void | ||
2067 | lpfc_supported_pages(struct lpfcMboxq *mbox) | ||
2068 | { | ||
2069 | struct lpfc_mbx_supp_pages *supp_pages; | ||
2070 | |||
2071 | memset(mbox, 0, sizeof(*mbox)); | ||
2072 | supp_pages = &mbox->u.mqe.un.supp_pages; | ||
2073 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES); | ||
2074 | bf_set(cpn, supp_pages, LPFC_SUPP_PAGES); | ||
2075 | } | ||
2076 | |||
2077 | /** | ||
2078 | * lpfc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params | ||
2079 | * mailbox command. | ||
2080 | * @mbox: pointer to lpfc mbox command to initialize. | ||
2081 | * | ||
2082 | * The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to | ||
2083 | * retrieve the particular SLI4 features supported by the port. | ||
2084 | **/ | ||
2085 | void | ||
2086 | lpfc_sli4_params(struct lpfcMboxq *mbox) | ||
2087 | { | ||
2088 | struct lpfc_mbx_sli4_params *sli4_params; | ||
2089 | |||
2090 | memset(mbox, 0, sizeof(*mbox)); | ||
2091 | sli4_params = &mbox->u.mqe.un.sli4_params; | ||
2092 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES); | ||
2093 | bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS); | ||
2094 | } | ||