[SCSI] qla2xxx: Add ISP81XX support.
[deliverable/linux.git] / drivers / scsi / qla2xxx / qla_sup.c
index 628d79c09733555710bc573244a6069d5e7d06e3..303f8ee11f2550399b439fee5756d3414cffa401 100644 (file)
@@ -425,27 +425,27 @@ qla2x00_set_nvram_protection(struct qla_hw_data *ha, int stat)
 #define OPTROM_BURST_DWORDS    (OPTROM_BURST_SIZE / 4)
 
 static inline uint32_t
-flash_conf_to_access_addr(uint32_t faddr)
+flash_conf_addr(struct qla_hw_data *ha, uint32_t faddr)
 {
-       return FARX_ACCESS_FLASH_CONF | faddr;
+       return ha->flash_conf_off | faddr;
 }
 
 static inline uint32_t
-flash_data_to_access_addr(uint32_t faddr)
+flash_data_addr(struct qla_hw_data *ha, uint32_t faddr)
 {
-       return FARX_ACCESS_FLASH_DATA | faddr;
+       return ha->flash_data_off | faddr;
 }
 
 static inline uint32_t
-nvram_conf_to_access_addr(uint32_t naddr)
+nvram_conf_addr(struct qla_hw_data *ha, uint32_t naddr)
 {
-       return FARX_ACCESS_NVRAM_CONF | naddr;
+       return ha->nvram_conf_off | naddr;
 }
 
 static inline uint32_t
-nvram_data_to_access_addr(uint32_t naddr)
+nvram_data_addr(struct qla_hw_data *ha, uint32_t naddr)
 {
-       return FARX_ACCESS_NVRAM_DATA | naddr;
+       return ha->nvram_data_off | naddr;
 }
 
 static uint32_t
@@ -481,10 +481,12 @@ qla24xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
     uint32_t dwords)
 {
        uint32_t i;
+       struct qla_hw_data *ha = vha->hw;
+
        /* Dword reads to flash. */
        for (i = 0; i < dwords; i++, faddr++)
-               dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(vha->hw,
-                   flash_data_to_access_addr(faddr)));
+               dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
+                   flash_data_addr(ha, faddr)));
 
        return dwptr;
 }
@@ -518,7 +520,7 @@ qla24xx_get_flash_manufacturer(struct qla_hw_data *ha, uint8_t *man_id,
 {
        uint32_t ids;
 
-       ids = qla24xx_read_flash_dword(ha, flash_data_to_access_addr(0xd03ab));
+       ids = qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x03ab));
        *man_id = LSB(ids);
        *flash_id = MSB(ids);
 
@@ -530,8 +532,7 @@ qla24xx_get_flash_manufacturer(struct qla_hw_data *ha, uint8_t *man_id,
                 * Example: ATMEL 0x00 01 45 1F
                 * Extract MFG and Dev ID from last two bytes.
                 */
-               ids = qla24xx_read_flash_dword(ha,
-                   flash_data_to_access_addr(0xd009f));
+               ids = qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x009f));
                *man_id = LSB(ids);
                *flash_id = MSB(ids);
        }
@@ -555,9 +556,13 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
 
        /* Begin with sane defaults. */
        loc = locations[0];
-       *start = IS_QLA24XX_TYPE(ha) ? FA_FLASH_LAYOUT_ADDR_24:
-           FA_FLASH_LAYOUT_ADDR;
-
+       *start = 0;
+       if (IS_QLA24XX_TYPE(ha))
+               *start = FA_FLASH_LAYOUT_ADDR_24;
+       else if (IS_QLA25XX(ha))
+               *start = FA_FLASH_LAYOUT_ADDR;
+       else if (IS_QLA81XX(ha))
+               *start = FA_FLASH_LAYOUT_ADDR_81;
        /* Begin with first PCI expansion ROM header. */
        buf = (uint8_t *)req->ring;
        dcode = (uint32_t *)req->ring;
@@ -618,6 +623,22 @@ static void
 qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 {
        const char *loc, *locations[] = { "DEF", "FLT" };
+       const uint32_t def_fw[] =
+               { FA_RISC_CODE_ADDR, FA_RISC_CODE_ADDR, FA_RISC_CODE_ADDR_81 };
+       const uint32_t def_boot[] =
+               { FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR_81 };
+       const uint32_t def_vpd_nvram[] =
+               { FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR_81 };
+       const uint32_t def_fdt[] =
+               { FA_FLASH_DESCR_ADDR_24, FA_FLASH_DESCR_ADDR,
+                       FA_FLASH_DESCR_ADDR_81 };
+       const uint32_t def_npiv_conf0[] =
+               { FA_NPIV_CONF0_ADDR_24, FA_NPIV_CONF0_ADDR,
+                       FA_NPIV_CONF0_ADDR_81 };
+       const uint32_t def_npiv_conf1[] =
+               { FA_NPIV_CONF1_ADDR_24, FA_NPIV_CONF1_ADDR,
+                       FA_NPIV_CONF1_ADDR_81 };
+       uint32_t def;
        uint16_t *wptr;
        uint16_t cnt, chksum;
        uint32_t start;
@@ -677,11 +698,11 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
                        ha->flt_region_fdt = start;
                        break;
                case FLT_REG_NPIV_CONF_0:
-                       if (!PCI_FUNC(ha->pdev->devfn))
+                       if (!(PCI_FUNC(ha->pdev->devfn) & 1))
                                ha->flt_region_npiv_conf = start;
                        break;
                case FLT_REG_NPIV_CONF_1:
-                       if (PCI_FUNC(ha->pdev->devfn))
+                       if (PCI_FUNC(ha->pdev->devfn) & 1)
                                ha->flt_region_npiv_conf = start;
                        break;
                }
@@ -691,14 +712,19 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 no_flash_data:
        /* Use hardcoded defaults. */
        loc = locations[0];
-       ha->flt_region_fw = FA_RISC_CODE_ADDR;
-       ha->flt_region_boot = FA_BOOT_CODE_ADDR;
-       ha->flt_region_vpd_nvram = FA_VPD_NVRAM_ADDR;
-       ha->flt_region_fdt = IS_QLA24XX_TYPE(ha) ? FA_FLASH_DESCR_ADDR_24:
-           FA_FLASH_DESCR_ADDR;
-       ha->flt_region_npiv_conf = !PCI_FUNC(ha->pdev->devfn) ?
-           (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF0_ADDR_24: FA_NPIV_CONF0_ADDR):
-           (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF1_ADDR_24: FA_NPIV_CONF1_ADDR);
+       def = 0;
+       if (IS_QLA24XX_TYPE(ha))
+               def = 0;
+       else if (IS_QLA25XX(ha))
+               def = 1;
+       else if (IS_QLA81XX(ha))
+               def = 2;
+       ha->flt_region_fw = def_fw[def];
+       ha->flt_region_boot = def_boot[def];
+       ha->flt_region_vpd_nvram = def_vpd_nvram[def];
+       ha->flt_region_fdt = def_fdt[def];
+       ha->flt_region_npiv_conf = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+           def_npiv_conf0[def]: def_npiv_conf1[def];
 done:
        DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
            "vpd_nvram=0x%x fdt=0x%x flt=0x%x npiv=0x%x.\n", loc,
@@ -746,14 +772,14 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha)
        mid = le16_to_cpu(fdt->man_id);
        fid = le16_to_cpu(fdt->id);
        ha->fdt_wrt_disable = fdt->wrt_disable_bits;
-       ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
+       ha->fdt_erase_cmd = flash_conf_addr(ha, 0x0300 | fdt->erase_cmd);
        ha->fdt_block_size = le32_to_cpu(fdt->block_size);
        if (fdt->unprotect_sec_cmd) {
-               ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0300 |
+               ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0300 |
                    fdt->unprotect_sec_cmd);
                ha->fdt_protect_sec_cmd = fdt->protect_sec_cmd ?
-                   flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd):
-                   flash_conf_to_access_addr(0x0336);
+                   flash_conf_addr(ha, 0x0300 | fdt->protect_sec_cmd):
+                   flash_conf_addr(ha, 0x0336);
        }
        goto done;
 no_flash_data:
@@ -762,7 +788,7 @@ no_flash_data:
        mid = man_id;
        fid = flash_id;
        ha->fdt_wrt_disable = 0x9c;
-       ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8);
+       ha->fdt_erase_cmd = flash_conf_addr(ha, 0x03d8);
        switch (man_id) {
        case 0xbf: /* STT flash. */
                if (flash_id == 0x8e)
@@ -771,16 +797,16 @@ no_flash_data:
                        ha->fdt_block_size = FLASH_BLK_SIZE_32K;
 
                if (flash_id == 0x80)
-                       ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0352);
+                       ha->fdt_erase_cmd = flash_conf_addr(ha, 0x0352);
                break;
        case 0x13: /* ST M25P80. */
                ha->fdt_block_size = FLASH_BLK_SIZE_64K;
                break;
        case 0x1f: /* Atmel 26DF081A. */
                ha->fdt_block_size = FLASH_BLK_SIZE_4K;
-               ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320);
-               ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339);
-               ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336);
+               ha->fdt_erase_cmd = flash_conf_addr(ha, 0x0320);
+               ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0339);
+               ha->fdt_protect_sec_cmd = flash_conf_addr(ha, 0x0336);
                break;
        default:
                /* Default to 64 kb sector size. */
@@ -802,7 +828,7 @@ qla2xxx_get_flash_info(scsi_qla_host_t *vha)
        uint32_t flt_addr;
        struct qla_hw_data *ha = vha->hw;
 
-       if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
+       if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA81XX(ha))
                return QLA_SUCCESS;
 
        ret = qla2xxx_find_flt_start(vha, &flt_addr);
@@ -827,7 +853,7 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha)
        struct qla_npiv_entry *entry;
        struct qla_hw_data *ha = vha->hw;
 
-       if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
+       if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA81XX(ha))
                return;
 
        ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr,
@@ -919,9 +945,9 @@ qla24xx_unprotect_flash(struct qla_hw_data *ha)
                return;
 
        /* Disable flash write-protection. */
-       qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0);
+       qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
        /* Some flash parts need an additional zero-write to clear bits.*/
-       qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0);
+       qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
 }
 
 static void
@@ -934,11 +960,10 @@ qla24xx_protect_flash(struct qla_hw_data *ha)
                goto skip_wrt_protect;
 
        /* Enable flash write-protection and wait for completion. */
-       qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101),
+       qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101),
            ha->fdt_wrt_disable);
        for (cnt = 300; cnt &&
-           qla24xx_read_flash_dword(ha,
-                   flash_conf_to_access_addr(0x005)) & BIT_0;
+           qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x005)) & BIT_0;
            cnt--) {
                udelay(10);
        }
@@ -966,7 +991,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
        ret = QLA_SUCCESS;
 
        /* Prepare burst-capable write on supported ISPs. */
-       if (IS_QLA25XX(ha) && !(faddr & 0xfff) &&
+       if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) &&
            dwords > OPTROM_BURST_DWORDS) {
                optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE,
                    &optrom_dma, GFP_KERNEL);
@@ -978,7 +1003,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
        }
 
        rest_addr = (ha->fdt_block_size >> 2) - 1;
-       sec_mask = 0x80000 - (ha->fdt_block_size >> 2);
+       sec_mask = (ha->optrom_size >> 2) - (ha->fdt_block_size >> 2);
 
        qla24xx_unprotect_flash(ha);
 
@@ -1013,13 +1038,13 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
                                *s = cpu_to_le32(*d);
 
                        ret = qla2x00_load_ram(vha, optrom_dma,
-                           flash_data_to_access_addr(faddr),
+                           flash_data_addr(ha, faddr),
                            OPTROM_BURST_DWORDS);
                        if (ret != QLA_SUCCESS) {
                                qla_printk(KERN_WARNING, ha,
                                    "Unable to burst-write optrom segment "
                                    "(%x/%x/%llx).\n", ret,
-                                   flash_data_to_access_addr(faddr),
+                                   flash_data_addr(ha, faddr),
                                    (unsigned long long)optrom_dma);
                                qla_printk(KERN_WARNING, ha,
                                    "Reverting to slow-write.\n");
@@ -1036,7 +1061,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
                }
 
                ret = qla24xx_write_flash_dword(ha,
-                   flash_data_to_access_addr(faddr), cpu_to_le32(*dwptr));
+                   flash_data_addr(ha, faddr), cpu_to_le32(*dwptr));
                if (ret != QLA_SUCCESS) {
                        DEBUG9(printk("%s(%ld) Unable to program flash "
                            "address=%x data=%x.\n", __func__,
@@ -1087,12 +1112,13 @@ qla24xx_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
 {
        uint32_t i;
        uint32_t *dwptr;
+       struct qla_hw_data *ha = vha->hw;
 
        /* Dword reads to flash. */
        dwptr = (uint32_t *)buf;
        for (i = 0; i < bytes >> 2; i++, naddr++)
-               dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(vha->hw,
-                   nvram_data_to_access_addr(naddr)));
+               dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
+                   nvram_data_addr(ha, naddr)));
 
        return buf;
 }
@@ -1149,17 +1175,14 @@ qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
        RD_REG_DWORD(&reg->ctrl_status);        /* PCI Posting. */
 
        /* Disable NVRAM write-protection. */
-       qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
-           0);
-       qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
-           0);
+       qla24xx_write_flash_dword(ha, nvram_conf_addr(ha, 0x101), 0);
+       qla24xx_write_flash_dword(ha, nvram_conf_addr(ha, 0x101), 0);
 
        /* Dword writes to flash. */
        dwptr = (uint32_t *)buf;
        for (i = 0; i < bytes >> 2; i++, naddr++, dwptr++) {
                ret = qla24xx_write_flash_dword(ha,
-                   nvram_data_to_access_addr(naddr),
-                   cpu_to_le32(*dwptr));
+                   nvram_data_addr(ha, naddr), cpu_to_le32(*dwptr));
                if (ret != QLA_SUCCESS) {
                        DEBUG9(qla_printk("Unable to program nvram address=%x "
                            "data=%x.\n", naddr, *dwptr));
@@ -1168,8 +1191,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
        }
 
        /* Enable NVRAM write-protection. */
-       qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
-           0x8c);
+       qla24xx_write_flash_dword(ha, nvram_conf_addr(ha, 0x101), 0x8c);
 
        /* Disable flash write. */
        WRT_REG_DWORD(&reg->ctrl_status,
@@ -1191,8 +1213,7 @@ qla25xx_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
        dwptr = (uint32_t *)buf;
        for (i = 0; i < bytes >> 2; i++, naddr++)
                dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
-                   flash_data_to_access_addr(ha->flt_region_vpd_nvram |
-                   naddr)));
+                   flash_data_addr(ha, ha->flt_region_vpd_nvram | naddr)));
 
        return buf;
 }
@@ -2235,12 +2256,12 @@ qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
                        burst = left;
 
                rval = qla2x00_dump_ram(vha, optrom_dma,
-                   flash_data_to_access_addr(faddr), burst);
+                   flash_data_addr(ha, faddr), burst);
                if (rval) {
                        qla_printk(KERN_WARNING, ha,
                            "Unable to burst-read optrom segment "
                            "(%x/%x/%llx).\n", rval,
-                           flash_data_to_access_addr(faddr),
+                           flash_data_addr(ha, faddr),
                            (unsigned long long)optrom_dma);
                        qla_printk(KERN_WARNING, ha,
                            "Reverting to slow-read.\n");
This page took 0.031738 seconds and 5 git commands to generate.