diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_sup.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 103 |
1 files changed, 80 insertions, 23 deletions
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 284827926eff..152ecfc26cd2 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -612,8 +612,8 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) | |||
612 | 612 | ||
613 | /* Good data. Use specified location. */ | 613 | /* Good data. Use specified location. */ |
614 | loc = locations[1]; | 614 | loc = locations[1]; |
615 | *start = le16_to_cpu(fltl->start_hi) << 16 | | 615 | *start = (le16_to_cpu(fltl->start_hi) << 16 | |
616 | le16_to_cpu(fltl->start_lo); | 616 | le16_to_cpu(fltl->start_lo)) >> 2; |
617 | end: | 617 | end: |
618 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start)); | 618 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start)); |
619 | return QLA_SUCCESS; | 619 | return QLA_SUCCESS; |
@@ -629,6 +629,14 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
629 | { FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR_81 }; | 629 | { FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR_81 }; |
630 | const uint32_t def_vpd_nvram[] = | 630 | const uint32_t def_vpd_nvram[] = |
631 | { FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR_81 }; | 631 | { FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR_81 }; |
632 | const uint32_t def_vpd0[] = | ||
633 | { 0, 0, FA_VPD0_ADDR_81 }; | ||
634 | const uint32_t def_vpd1[] = | ||
635 | { 0, 0, FA_VPD1_ADDR_81 }; | ||
636 | const uint32_t def_nvram0[] = | ||
637 | { 0, 0, FA_NVRAM0_ADDR_81 }; | ||
638 | const uint32_t def_nvram1[] = | ||
639 | { 0, 0, FA_NVRAM1_ADDR_81 }; | ||
632 | const uint32_t def_fdt[] = | 640 | const uint32_t def_fdt[] = |
633 | { FA_FLASH_DESCR_ADDR_24, FA_FLASH_DESCR_ADDR, | 641 | { FA_FLASH_DESCR_ADDR_24, FA_FLASH_DESCR_ADDR, |
634 | FA_FLASH_DESCR_ADDR_81 }; | 642 | FA_FLASH_DESCR_ADDR_81 }; |
@@ -693,6 +701,20 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
693 | break; | 701 | break; |
694 | case FLT_REG_VPD_0: | 702 | case FLT_REG_VPD_0: |
695 | ha->flt_region_vpd_nvram = start; | 703 | ha->flt_region_vpd_nvram = start; |
704 | if (!(PCI_FUNC(ha->pdev->devfn) & 1)) | ||
705 | ha->flt_region_vpd = start; | ||
706 | break; | ||
707 | case FLT_REG_VPD_1: | ||
708 | if (PCI_FUNC(ha->pdev->devfn) & 1) | ||
709 | ha->flt_region_vpd = start; | ||
710 | break; | ||
711 | case FLT_REG_NVRAM_0: | ||
712 | if (!(PCI_FUNC(ha->pdev->devfn) & 1)) | ||
713 | ha->flt_region_nvram = start; | ||
714 | break; | ||
715 | case FLT_REG_NVRAM_1: | ||
716 | if (PCI_FUNC(ha->pdev->devfn) & 1) | ||
717 | ha->flt_region_nvram = start; | ||
696 | break; | 718 | break; |
697 | case FLT_REG_FDT: | 719 | case FLT_REG_FDT: |
698 | ha->flt_region_fdt = start; | 720 | ha->flt_region_fdt = start; |
@@ -722,13 +744,18 @@ no_flash_data: | |||
722 | ha->flt_region_fw = def_fw[def]; | 744 | ha->flt_region_fw = def_fw[def]; |
723 | ha->flt_region_boot = def_boot[def]; | 745 | ha->flt_region_boot = def_boot[def]; |
724 | ha->flt_region_vpd_nvram = def_vpd_nvram[def]; | 746 | ha->flt_region_vpd_nvram = def_vpd_nvram[def]; |
747 | ha->flt_region_vpd = !(PCI_FUNC(ha->pdev->devfn) & 1) ? | ||
748 | def_vpd0[def]: def_vpd1[def]; | ||
749 | ha->flt_region_nvram = !(PCI_FUNC(ha->pdev->devfn) & 1) ? | ||
750 | def_nvram0[def]: def_nvram1[def]; | ||
725 | ha->flt_region_fdt = def_fdt[def]; | 751 | ha->flt_region_fdt = def_fdt[def]; |
726 | ha->flt_region_npiv_conf = !(PCI_FUNC(ha->pdev->devfn) & 1) ? | 752 | ha->flt_region_npiv_conf = !(PCI_FUNC(ha->pdev->devfn) & 1) ? |
727 | def_npiv_conf0[def]: def_npiv_conf1[def]; | 753 | def_npiv_conf0[def]: def_npiv_conf1[def]; |
728 | done: | 754 | done: |
729 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x " | 755 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x " |
730 | "vpd_nvram=0x%x fdt=0x%x flt=0x%x npiv=0x%x.\n", loc, | 756 | "vpd_nvram=0x%x vpd=0x%x nvram=0x%x fdt=0x%x flt=0x%x " |
731 | ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram, | 757 | "npiv=0x%x.\n", loc, ha->flt_region_boot, ha->flt_region_fw, |
758 | ha->flt_region_vpd_nvram, ha->flt_region_vpd, ha->flt_region_nvram, | ||
732 | ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_npiv_conf)); | 759 | ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_npiv_conf)); |
733 | } | 760 | } |
734 | 761 | ||
@@ -931,31 +958,41 @@ done: | |||
931 | ha->npiv_info = NULL; | 958 | ha->npiv_info = NULL; |
932 | } | 959 | } |
933 | 960 | ||
934 | static void | 961 | static int |
935 | qla24xx_unprotect_flash(struct qla_hw_data *ha) | 962 | qla24xx_unprotect_flash(scsi_qla_host_t *vha) |
936 | { | 963 | { |
964 | struct qla_hw_data *ha = vha->hw; | ||
937 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 965 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
938 | 966 | ||
967 | if (ha->flags.fac_supported) | ||
968 | return qla81xx_fac_do_write_enable(vha, 1); | ||
969 | |||
939 | /* Enable flash write. */ | 970 | /* Enable flash write. */ |
940 | WRT_REG_DWORD(®->ctrl_status, | 971 | WRT_REG_DWORD(®->ctrl_status, |
941 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 972 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); |
942 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 973 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
943 | 974 | ||
944 | if (!ha->fdt_wrt_disable) | 975 | if (!ha->fdt_wrt_disable) |
945 | return; | 976 | goto done; |
946 | 977 | ||
947 | /* Disable flash write-protection, first clear SR protection bit */ | 978 | /* Disable flash write-protection, first clear SR protection bit */ |
948 | qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0); | 979 | qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0); |
949 | /* Then write zero again to clear remaining SR bits.*/ | 980 | /* Then write zero again to clear remaining SR bits.*/ |
950 | qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0); | 981 | qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0); |
982 | done: | ||
983 | return QLA_SUCCESS; | ||
951 | } | 984 | } |
952 | 985 | ||
953 | static void | 986 | static int |
954 | qla24xx_protect_flash(struct qla_hw_data *ha) | 987 | qla24xx_protect_flash(scsi_qla_host_t *vha) |
955 | { | 988 | { |
956 | uint32_t cnt; | 989 | uint32_t cnt; |
990 | struct qla_hw_data *ha = vha->hw; | ||
957 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 991 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
958 | 992 | ||
993 | if (ha->flags.fac_supported) | ||
994 | return qla81xx_fac_do_write_enable(vha, 0); | ||
995 | |||
959 | if (!ha->fdt_wrt_disable) | 996 | if (!ha->fdt_wrt_disable) |
960 | goto skip_wrt_protect; | 997 | goto skip_wrt_protect; |
961 | 998 | ||
@@ -973,6 +1010,26 @@ skip_wrt_protect: | |||
973 | WRT_REG_DWORD(®->ctrl_status, | 1010 | WRT_REG_DWORD(®->ctrl_status, |
974 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | 1011 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); |
975 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 1012 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
1013 | |||
1014 | return QLA_SUCCESS; | ||
1015 | } | ||
1016 | |||
1017 | static int | ||
1018 | qla24xx_erase_sector(scsi_qla_host_t *vha, uint32_t fdata) | ||
1019 | { | ||
1020 | struct qla_hw_data *ha = vha->hw; | ||
1021 | uint32_t start, finish; | ||
1022 | |||
1023 | if (ha->flags.fac_supported) { | ||
1024 | start = fdata >> 2; | ||
1025 | finish = start + (ha->fdt_block_size >> 2) - 1; | ||
1026 | return qla81xx_fac_erase_sector(vha, flash_data_addr(ha, | ||
1027 | start), flash_data_addr(ha, finish)); | ||
1028 | } | ||
1029 | |||
1030 | return qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd, | ||
1031 | (fdata & 0xff00) | ((fdata << 16) & 0xff0000) | | ||
1032 | ((fdata >> 16) & 0xff)); | ||
976 | } | 1033 | } |
977 | 1034 | ||
978 | static int | 1035 | static int |
@@ -987,8 +1044,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | |||
987 | void *optrom = NULL; | 1044 | void *optrom = NULL; |
988 | struct qla_hw_data *ha = vha->hw; | 1045 | struct qla_hw_data *ha = vha->hw; |
989 | 1046 | ||
990 | ret = QLA_SUCCESS; | ||
991 | |||
992 | /* Prepare burst-capable write on supported ISPs. */ | 1047 | /* Prepare burst-capable write on supported ISPs. */ |
993 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) && | 1048 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) && |
994 | dwords > OPTROM_BURST_DWORDS) { | 1049 | dwords > OPTROM_BURST_DWORDS) { |
@@ -1004,7 +1059,12 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | |||
1004 | rest_addr = (ha->fdt_block_size >> 2) - 1; | 1059 | rest_addr = (ha->fdt_block_size >> 2) - 1; |
1005 | sec_mask = ~rest_addr; | 1060 | sec_mask = ~rest_addr; |
1006 | 1061 | ||
1007 | qla24xx_unprotect_flash(ha); | 1062 | ret = qla24xx_unprotect_flash(vha); |
1063 | if (ret != QLA_SUCCESS) { | ||
1064 | qla_printk(KERN_WARNING, ha, | ||
1065 | "Unable to unprotect flash for update.\n"); | ||
1066 | goto done; | ||
1067 | } | ||
1008 | 1068 | ||
1009 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { | 1069 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { |
1010 | fdata = (faddr & sec_mask) << 2; | 1070 | fdata = (faddr & sec_mask) << 2; |
@@ -1017,9 +1077,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | |||
1017 | ha->fdt_unprotect_sec_cmd, | 1077 | ha->fdt_unprotect_sec_cmd, |
1018 | (fdata & 0xff00) | ((fdata << 16) & | 1078 | (fdata & 0xff00) | ((fdata << 16) & |
1019 | 0xff0000) | ((fdata >> 16) & 0xff)); | 1079 | 0xff0000) | ((fdata >> 16) & 0xff)); |
1020 | ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd, | 1080 | ret = qla24xx_erase_sector(vha, fdata); |
1021 | (fdata & 0xff00) |((fdata << 16) & | ||
1022 | 0xff0000) | ((fdata >> 16) & 0xff)); | ||
1023 | if (ret != QLA_SUCCESS) { | 1081 | if (ret != QLA_SUCCESS) { |
1024 | DEBUG9(qla_printk("Unable to erase sector: " | 1082 | DEBUG9(qla_printk("Unable to erase sector: " |
1025 | "address=%x.\n", faddr)); | 1083 | "address=%x.\n", faddr)); |
@@ -1073,8 +1131,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | |||
1073 | 0xff0000) | ((fdata >> 16) & 0xff)); | 1131 | 0xff0000) | ((fdata >> 16) & 0xff)); |
1074 | } | 1132 | } |
1075 | 1133 | ||
1076 | qla24xx_protect_flash(ha); | 1134 | ret = qla24xx_protect_flash(vha); |
1077 | 1135 | if (ret != QLA_SUCCESS) | |
1136 | qla_printk(KERN_WARNING, ha, | ||
1137 | "Unable to protect flash after update.\n"); | ||
1138 | done: | ||
1078 | if (optrom) | 1139 | if (optrom) |
1079 | dma_free_coherent(&ha->pdev->dev, | 1140 | dma_free_coherent(&ha->pdev->dev, |
1080 | OPTROM_BURST_SIZE, optrom, optrom_dma); | 1141 | OPTROM_BURST_SIZE, optrom, optrom_dma); |
@@ -1915,7 +1976,7 @@ qla2x00_resume_hba(struct scsi_qla_host *vha) | |||
1915 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 1976 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
1916 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | 1977 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
1917 | qla2xxx_wake_dpc(vha); | 1978 | qla2xxx_wake_dpc(vha); |
1918 | qla2x00_wait_for_hba_online(vha); | 1979 | qla2x00_wait_for_chip_reset(vha); |
1919 | scsi_unblock_requests(vha->host); | 1980 | scsi_unblock_requests(vha->host); |
1920 | } | 1981 | } |
1921 | 1982 | ||
@@ -2206,11 +2267,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2206 | rval = qla24xx_write_flash_data(vha, (uint32_t *)buf, offset >> 2, | 2267 | rval = qla24xx_write_flash_data(vha, (uint32_t *)buf, offset >> 2, |
2207 | length >> 2); | 2268 | length >> 2); |
2208 | 2269 | ||
2209 | /* Resume HBA -- RISC reset needed. */ | ||
2210 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 2270 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
2211 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | ||
2212 | qla2xxx_wake_dpc(vha); | ||
2213 | qla2x00_wait_for_hba_online(vha); | ||
2214 | scsi_unblock_requests(vha->host); | 2271 | scsi_unblock_requests(vha->host); |
2215 | 2272 | ||
2216 | return rval; | 2273 | return rval; |
@@ -2518,7 +2575,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
2518 | dcode = mbuf; | 2575 | dcode = mbuf; |
2519 | 2576 | ||
2520 | /* Begin with first PCI expansion ROM header. */ | 2577 | /* Begin with first PCI expansion ROM header. */ |
2521 | pcihdr = ha->flt_region_boot; | 2578 | pcihdr = ha->flt_region_boot << 2; |
2522 | last_image = 1; | 2579 | last_image = 1; |
2523 | do { | 2580 | do { |
2524 | /* Verify PCI expansion ROM header. */ | 2581 | /* Verify PCI expansion ROM header. */ |