diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2008-09-12 00:22:50 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-03 12:46:18 -0400 |
commit | 272976ca186982f7bbc4f22876c53d6c9f7b6e32 (patch) | |
tree | a0e3ecbf54d24da4ccccf881a60a2b788ac7c455 /drivers/scsi/qla2xxx/qla_sup.c | |
parent | c00d8994d91e51aa6b891ad0e877f66cc1011de2 (diff) |
[SCSI] qla2xxx: Add NPIV-Config Table support.
To instatiate pre-configured vport entities defined within an
HBA's flash memory.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_sup.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 98 |
1 files changed, 96 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 6de1e3bc62a8..e2432ef1ecea 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -686,6 +686,14 @@ qla2xxx_get_flt_info(scsi_qla_host_t *ha, uint32_t flt_addr) | |||
686 | if (PCI_FUNC(ha->pdev->devfn)) | 686 | if (PCI_FUNC(ha->pdev->devfn)) |
687 | ha->flt_region_hw_event = start; | 687 | ha->flt_region_hw_event = start; |
688 | break; | 688 | break; |
689 | case FLT_REG_NPIV_CONF_0: | ||
690 | if (!PCI_FUNC(ha->pdev->devfn)) | ||
691 | ha->flt_region_npiv_conf = start; | ||
692 | break; | ||
693 | case FLT_REG_NPIV_CONF_1: | ||
694 | if (PCI_FUNC(ha->pdev->devfn)) | ||
695 | ha->flt_region_npiv_conf = start; | ||
696 | break; | ||
689 | } | 697 | } |
690 | } | 698 | } |
691 | goto done; | 699 | goto done; |
@@ -700,11 +708,15 @@ no_flash_data: | |||
700 | FA_FLASH_DESCR_ADDR; | 708 | FA_FLASH_DESCR_ADDR; |
701 | ha->flt_region_hw_event = !PCI_FUNC(ha->pdev->devfn) ? | 709 | ha->flt_region_hw_event = !PCI_FUNC(ha->pdev->devfn) ? |
702 | FA_HW_EVENT0_ADDR: FA_HW_EVENT1_ADDR; | 710 | FA_HW_EVENT0_ADDR: FA_HW_EVENT1_ADDR; |
711 | ha->flt_region_npiv_conf = !PCI_FUNC(ha->pdev->devfn) ? | ||
712 | (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF0_ADDR_24: FA_NPIV_CONF0_ADDR): | ||
713 | (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF1_ADDR_24: FA_NPIV_CONF1_ADDR); | ||
703 | done: | 714 | done: |
704 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x " | 715 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x " |
705 | "vpd_nvram=0x%x fdt=0x%x flt=0x%x hwe=0x%x.\n", loc, | 716 | "vpd_nvram=0x%x fdt=0x%x flt=0x%x hwe=0x%x npiv=0x%x.\n", loc, |
706 | ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram, | 717 | ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram, |
707 | ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_hw_event)); | 718 | ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_hw_event, |
719 | ha->flt_region_npiv_conf)); | ||
708 | } | 720 | } |
709 | 721 | ||
710 | static void | 722 | static void |
@@ -814,6 +826,88 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha) | |||
814 | return QLA_SUCCESS; | 826 | return QLA_SUCCESS; |
815 | } | 827 | } |
816 | 828 | ||
829 | void | ||
830 | qla2xxx_flash_npiv_conf(scsi_qla_host_t *ha) | ||
831 | { | ||
832 | #define NPIV_CONFIG_SIZE (16*1024) | ||
833 | void *data; | ||
834 | uint16_t *wptr; | ||
835 | uint16_t cnt, chksum; | ||
836 | struct qla_npiv_header hdr; | ||
837 | struct qla_npiv_entry *entry; | ||
838 | |||
839 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) | ||
840 | return; | ||
841 | |||
842 | ha->isp_ops->read_optrom(ha, (uint8_t *)&hdr, | ||
843 | ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header)); | ||
844 | if (hdr.version == __constant_cpu_to_le16(0xffff)) | ||
845 | return; | ||
846 | if (hdr.version != __constant_cpu_to_le16(1)) { | ||
847 | DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported NPIV-Config " | ||
848 | "detected: version=0x%x entries=0x%x checksum=0x%x.\n", | ||
849 | le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries), | ||
850 | le16_to_cpu(hdr.checksum))); | ||
851 | return; | ||
852 | } | ||
853 | |||
854 | data = kmalloc(NPIV_CONFIG_SIZE, GFP_KERNEL); | ||
855 | if (!data) { | ||
856 | DEBUG2(qla_printk(KERN_INFO, ha, "NPIV-Config: Unable to " | ||
857 | "allocate memory.\n")); | ||
858 | return; | ||
859 | } | ||
860 | |||
861 | ha->isp_ops->read_optrom(ha, (uint8_t *)data, | ||
862 | ha->flt_region_npiv_conf << 2, NPIV_CONFIG_SIZE); | ||
863 | |||
864 | cnt = (sizeof(struct qla_npiv_header) + le16_to_cpu(hdr.entries) * | ||
865 | sizeof(struct qla_npiv_entry)) >> 1; | ||
866 | for (wptr = data, chksum = 0; cnt; cnt--) | ||
867 | chksum += le16_to_cpu(*wptr++); | ||
868 | if (chksum) { | ||
869 | DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent NPIV-Config " | ||
870 | "detected: version=0x%x entries=0x%x checksum=0x%x.\n", | ||
871 | le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries), | ||
872 | chksum)); | ||
873 | goto done; | ||
874 | } | ||
875 | |||
876 | entry = data + sizeof(struct qla_npiv_header); | ||
877 | cnt = le16_to_cpu(hdr.entries); | ||
878 | for ( ; cnt; cnt--, entry++) { | ||
879 | uint16_t flags; | ||
880 | struct fc_vport_identifiers vid; | ||
881 | struct fc_vport *vport; | ||
882 | |||
883 | flags = le16_to_cpu(entry->flags); | ||
884 | if (flags == 0xffff) | ||
885 | continue; | ||
886 | if ((flags & BIT_0) == 0) | ||
887 | continue; | ||
888 | |||
889 | memset(&vid, 0, sizeof(vid)); | ||
890 | vid.roles = FC_PORT_ROLE_FCP_INITIATOR; | ||
891 | vid.vport_type = FC_PORTTYPE_NPIV; | ||
892 | vid.disable = false; | ||
893 | vid.port_name = wwn_to_u64(entry->port_name); | ||
894 | vid.node_name = wwn_to_u64(entry->node_name); | ||
895 | |||
896 | DEBUG2(qla_printk(KERN_DEBUG, ha, "NPIV[%02x]: wwpn=%llx " | ||
897 | "wwnn=%llx vf_id=0x%x qos=0x%x.\n", cnt, vid.port_name, | ||
898 | vid.node_name, le16_to_cpu(entry->vf_id), | ||
899 | le16_to_cpu(entry->qos))); | ||
900 | |||
901 | vport = fc_vport_create(ha->host, 0, &vid); | ||
902 | if (!vport) | ||
903 | qla_printk(KERN_INFO, ha, "NPIV-Config: Failed to " | ||
904 | "create vport [%02x]: wwpn=%llx wwnn=%llx.\n", cnt, | ||
905 | vid.port_name, vid.node_name); | ||
906 | } | ||
907 | done: | ||
908 | kfree(data); | ||
909 | } | ||
910 | |||
817 | static void | 911 | static void |
818 | qla24xx_unprotect_flash(scsi_qla_host_t *ha) | 912 | qla24xx_unprotect_flash(scsi_qla_host_t *ha) |
819 | { | 913 | { |