aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_sup.c
diff options
context:
space:
mode:
authorJoe Carnuccio <joe.carnuccio@qlogic.com>2009-03-24 12:08:06 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-03 10:22:48 -0400
commit1d2874de809a14e6780246b99a18bbc0fc0a8f2a (patch)
tree0f9dc305dc6f802c27bcef6edc607832864b7687 /drivers/scsi/qla2xxx/qla_sup.c
parentb9978769877c6c90c8d6777df13b9ae427af40b7 (diff)
[SCSI] qla2xxx: Add Flash-Access-Control support for recent ISPs.
Given the low-level interface varies from one flash-part manufacturer to the next, the Flash-Access-Control (FAC) mailbox command makes the specific flash type transparent to the driver by encapsulating a basic set of accessor and update routines. Use these new routines where applicable by querying FAC opcode get-sector-size at init-time. Additional cleanups and 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.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 5b24af86aaf..ff5aa75109f 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -931,31 +931,41 @@ done:
931 ha->npiv_info = NULL; 931 ha->npiv_info = NULL;
932} 932}
933 933
934static void 934static int
935qla24xx_unprotect_flash(struct qla_hw_data *ha) 935qla24xx_unprotect_flash(scsi_qla_host_t *vha)
936{ 936{
937 struct qla_hw_data *ha = vha->hw;
937 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 938 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
938 939
940 if (ha->flags.fac_supported)
941 return qla81xx_fac_do_write_enable(vha, 1);
942
939 /* Enable flash write. */ 943 /* Enable flash write. */
940 WRT_REG_DWORD(&reg->ctrl_status, 944 WRT_REG_DWORD(&reg->ctrl_status,
941 RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE); 945 RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
942 RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */ 946 RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
943 947
944 if (!ha->fdt_wrt_disable) 948 if (!ha->fdt_wrt_disable)
945 return; 949 goto done;
946 950
947 /* Disable flash write-protection, first clear SR protection bit */ 951 /* Disable flash write-protection, first clear SR protection bit */
948 qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0); 952 qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
949 /* Then write zero again to clear remaining SR bits.*/ 953 /* Then write zero again to clear remaining SR bits.*/
950 qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0); 954 qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
955done:
956 return QLA_SUCCESS;
951} 957}
952 958
953static void 959static int
954qla24xx_protect_flash(struct qla_hw_data *ha) 960qla24xx_protect_flash(scsi_qla_host_t *vha)
955{ 961{
956 uint32_t cnt; 962 uint32_t cnt;
963 struct qla_hw_data *ha = vha->hw;
957 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 964 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
958 965
966 if (ha->flags.fac_supported)
967 return qla81xx_fac_do_write_enable(vha, 0);
968
959 if (!ha->fdt_wrt_disable) 969 if (!ha->fdt_wrt_disable)
960 goto skip_wrt_protect; 970 goto skip_wrt_protect;
961 971
@@ -973,6 +983,26 @@ skip_wrt_protect:
973 WRT_REG_DWORD(&reg->ctrl_status, 983 WRT_REG_DWORD(&reg->ctrl_status,
974 RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE); 984 RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
975 RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */ 985 RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
986
987 return QLA_SUCCESS;
988}
989
990static int
991qla24xx_erase_sector(scsi_qla_host_t *vha, uint32_t fdata)
992{
993 struct qla_hw_data *ha = vha->hw;
994 uint32_t start, finish;
995
996 if (ha->flags.fac_supported) {
997 start = fdata >> 2;
998 finish = start + (ha->fdt_block_size >> 2) - 1;
999 return qla81xx_fac_erase_sector(vha, flash_data_addr(ha,
1000 start), flash_data_addr(ha, finish));
1001 }
1002
1003 return qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd,
1004 (fdata & 0xff00) | ((fdata << 16) & 0xff0000) |
1005 ((fdata >> 16) & 0xff));
976} 1006}
977 1007
978static int 1008static int
@@ -987,8 +1017,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
987 void *optrom = NULL; 1017 void *optrom = NULL;
988 struct qla_hw_data *ha = vha->hw; 1018 struct qla_hw_data *ha = vha->hw;
989 1019
990 ret = QLA_SUCCESS;
991
992 /* Prepare burst-capable write on supported ISPs. */ 1020 /* Prepare burst-capable write on supported ISPs. */
993 if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) && 1021 if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) &&
994 dwords > OPTROM_BURST_DWORDS) { 1022 dwords > OPTROM_BURST_DWORDS) {
@@ -1004,7 +1032,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; 1032 rest_addr = (ha->fdt_block_size >> 2) - 1;
1005 sec_mask = ~rest_addr; 1033 sec_mask = ~rest_addr;
1006 1034
1007 qla24xx_unprotect_flash(ha); 1035 ret = qla24xx_unprotect_flash(vha);
1036 if (ret != QLA_SUCCESS) {
1037 qla_printk(KERN_WARNING, ha,
1038 "Unable to unprotect flash for update.\n");
1039 goto done;
1040 }
1008 1041
1009 for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { 1042 for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
1010 fdata = (faddr & sec_mask) << 2; 1043 fdata = (faddr & sec_mask) << 2;
@@ -1017,9 +1050,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
1017 ha->fdt_unprotect_sec_cmd, 1050 ha->fdt_unprotect_sec_cmd,
1018 (fdata & 0xff00) | ((fdata << 16) & 1051 (fdata & 0xff00) | ((fdata << 16) &
1019 0xff0000) | ((fdata >> 16) & 0xff)); 1052 0xff0000) | ((fdata >> 16) & 0xff));
1020 ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd, 1053 ret = qla24xx_erase_sector(vha, fdata);
1021 (fdata & 0xff00) |((fdata << 16) &
1022 0xff0000) | ((fdata >> 16) & 0xff));
1023 if (ret != QLA_SUCCESS) { 1054 if (ret != QLA_SUCCESS) {
1024 DEBUG9(qla_printk("Unable to erase sector: " 1055 DEBUG9(qla_printk("Unable to erase sector: "
1025 "address=%x.\n", faddr)); 1056 "address=%x.\n", faddr));
@@ -1073,8 +1104,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
1073 0xff0000) | ((fdata >> 16) & 0xff)); 1104 0xff0000) | ((fdata >> 16) & 0xff));
1074 } 1105 }
1075 1106
1076 qla24xx_protect_flash(ha); 1107 ret = qla24xx_protect_flash(vha);
1077 1108 if (ret != QLA_SUCCESS)
1109 qla_printk(KERN_WARNING, ha,
1110 "Unable to protect flash after update.\n");
1111done:
1078 if (optrom) 1112 if (optrom)
1079 dma_free_coherent(&ha->pdev->dev, 1113 dma_free_coherent(&ha->pdev->dev,
1080 OPTROM_BURST_SIZE, optrom, optrom_dma); 1114 OPTROM_BURST_SIZE, optrom, optrom_dma);