aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2009-06-03 12:55:17 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-08 15:46:41 -0400
commitcbc8eb67da11a4972834f61fe4729f4c037a17c9 (patch)
tree52880ae49bce8a8b733d0d59bd84b324eb0871ef /drivers/scsi/qla2xxx
parent40859ae5f13534624cc35a05179b4f93ecbf531a (diff)
[SCSI] qla2xxx: Fallback to 'golden-firmware' operation on supported ISPs.
In case the onboard firmware is unable to be read or loaded for operation, attempt to fallback to a limited-operational firmware image stored in a different flash region. This will allow a user to reflash and correct a board with proper operational firmware. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c33
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c3
5 files changed, 38 insertions, 8 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 4e846ae928aa..88ddae0e2b88 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2223,6 +2223,7 @@ struct qla_hw_data {
2223 uint32_t fac_supported :1; 2223 uint32_t fac_supported :1;
2224 uint32_t chip_reset_done :1; 2224 uint32_t chip_reset_done :1;
2225 uint32_t port0 :1; 2225 uint32_t port0 :1;
2226 uint32_t running_gold_fw :1;
2226 } flags; 2227 } flags;
2227 2228
2228 /* This spinlock is used to protect "io transactions", you must 2229 /* This spinlock is used to protect "io transactions", you must
@@ -2523,6 +2524,7 @@ struct qla_hw_data {
2523 uint32_t flt_region_vpd; 2524 uint32_t flt_region_vpd;
2524 uint32_t flt_region_nvram; 2525 uint32_t flt_region_nvram;
2525 uint32_t flt_region_npiv_conf; 2526 uint32_t flt_region_npiv_conf;
2527 uint32_t flt_region_gold_fw;
2526 2528
2527 /* Needed for BEACON */ 2529 /* Needed for BEACON */
2528 uint16_t beacon_blink_led; 2530 uint16_t beacon_blink_led;
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 152d16c77f3e..9e56d4a4cb75 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1241,6 +1241,7 @@ struct qla_flt_header {
1241#define FLT_REG_HW_EVENT_1 0x1f 1241#define FLT_REG_HW_EVENT_1 0x1f
1242#define FLT_REG_NPIV_CONF_0 0x29 1242#define FLT_REG_NPIV_CONF_0 0x29
1243#define FLT_REG_NPIV_CONF_1 0x2a 1243#define FLT_REG_NPIV_CONF_1 0x2a
1244#define FLT_REG_GOLD_FW 0x2f
1244 1245
1245struct qla_flt_region { 1246struct qla_flt_region {
1246 uint32_t code; 1247 uint32_t code;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a7abc1035481..34e6508bbab0 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3806,11 +3806,11 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
3806} 3806}
3807 3807
3808static int 3808static int
3809qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr) 3809qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
3810 uint32_t faddr)
3810{ 3811{
3811 int rval = QLA_SUCCESS; 3812 int rval = QLA_SUCCESS;
3812 int segments, fragment; 3813 int segments, fragment;
3813 uint32_t faddr;
3814 uint32_t *dcode, dlen; 3814 uint32_t *dcode, dlen;
3815 uint32_t risc_addr; 3815 uint32_t risc_addr;
3816 uint32_t risc_size; 3816 uint32_t risc_size;
@@ -3819,12 +3819,11 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr)
3819 struct req_que *req = ha->req_q_map[0]; 3819 struct req_que *req = ha->req_q_map[0];
3820 3820
3821 qla_printk(KERN_INFO, ha, 3821 qla_printk(KERN_INFO, ha,
3822 "FW: Loading from flash (%x)...\n", ha->flt_region_fw); 3822 "FW: Loading from flash (%x)...\n", faddr);
3823 3823
3824 rval = QLA_SUCCESS; 3824 rval = QLA_SUCCESS;
3825 3825
3826 segments = FA_RISC_CODE_SEGMENTS; 3826 segments = FA_RISC_CODE_SEGMENTS;
3827 faddr = ha->flt_region_fw;
3828 dcode = (uint32_t *)req->ring; 3827 dcode = (uint32_t *)req->ring;
3829 *srisc_addr = 0; 3828 *srisc_addr = 0;
3830 3829
@@ -4124,27 +4123,45 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
4124 if (rval == QLA_SUCCESS) 4123 if (rval == QLA_SUCCESS)
4125 return rval; 4124 return rval;
4126 4125
4127 return qla24xx_load_risc_flash(vha, srisc_addr); 4126 return qla24xx_load_risc_flash(vha, srisc_addr,
4127 vha->hw->flt_region_fw);
4128} 4128}
4129 4129
4130int 4130int
4131qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) 4131qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
4132{ 4132{
4133 int rval; 4133 int rval;
4134 struct qla_hw_data *ha = vha->hw;
4134 4135
4135 if (ql2xfwloadbin == 2) 4136 if (ql2xfwloadbin == 2)
4136 return qla24xx_load_risc(vha, srisc_addr); 4137 goto try_blob_fw;
4137 4138
4138 /* 4139 /*
4139 * FW Load priority: 4140 * FW Load priority:
4140 * 1) Firmware residing in flash. 4141 * 1) Firmware residing in flash.
4141 * 2) Firmware via request-firmware interface (.bin file). 4142 * 2) Firmware via request-firmware interface (.bin file).
4143 * 3) Golden-Firmware residing in flash -- limited operation.
4142 */ 4144 */
4143 rval = qla24xx_load_risc_flash(vha, srisc_addr); 4145 rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw);
4144 if (rval == QLA_SUCCESS) 4146 if (rval == QLA_SUCCESS)
4145 return rval; 4147 return rval;
4146 4148
4147 return qla24xx_load_risc_blob(vha, srisc_addr); 4149try_blob_fw:
4150 rval = qla24xx_load_risc_blob(vha, srisc_addr);
4151 if (rval == QLA_SUCCESS || !ha->flt_region_gold_fw)
4152 return rval;
4153
4154 qla_printk(KERN_ERR, ha,
4155 "FW: Attempting to fallback to golden firmware...\n");
4156 rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_gold_fw);
4157 if (rval != QLA_SUCCESS)
4158 return rval;
4159
4160 qla_printk(KERN_ERR, ha,
4161 "FW: Please update operational firmware...\n");
4162 ha->flags.running_gold_fw = 1;
4163
4164 return rval;
4148} 4165}
4149 4166
4150void 4167void
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 181ed971a2ff..128b3d5c9663 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1690,6 +1690,9 @@ qla2xxx_scan_start(struct Scsi_Host *shost)
1690{ 1690{
1691 scsi_qla_host_t *vha = shost_priv(shost); 1691 scsi_qla_host_t *vha = shost_priv(shost);
1692 1692
1693 if (vha->hw->flags.running_gold_fw)
1694 return;
1695
1693 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 1696 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
1694 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 1697 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
1695 set_bit(RSCN_UPDATE, &vha->dpc_flags); 1698 set_bit(RSCN_UPDATE, &vha->dpc_flags);
@@ -1962,6 +1965,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1962 "Can't create queues, falling back to single" 1965 "Can't create queues, falling back to single"
1963 " queue mode\n"); 1966 " queue mode\n");
1964 1967
1968 if (ha->flags.running_gold_fw)
1969 goto skip_dpc;
1970
1965 /* 1971 /*
1966 * Startup the kernel thread for this host adapter 1972 * Startup the kernel thread for this host adapter
1967 */ 1973 */
@@ -1974,6 +1980,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1974 goto probe_failed; 1980 goto probe_failed;
1975 } 1981 }
1976 1982
1983skip_dpc:
1977 list_add_tail(&base_vha->list, &ha->vp_list); 1984 list_add_tail(&base_vha->list, &ha->vp_list);
1978 base_vha->host->irq = ha->pdev->irq; 1985 base_vha->host->irq = ha->pdev->irq;
1979 1986
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index e239203f19f7..6260505dceb5 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -728,6 +728,9 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
728 if (!ha->flags.port0) 728 if (!ha->flags.port0)
729 ha->flt_region_npiv_conf = start; 729 ha->flt_region_npiv_conf = start;
730 break; 730 break;
731 case FLT_REG_GOLD_FW:
732 ha->flt_region_gold_fw = start;
733 break;
731 } 734 }
732 } 735 }
733 goto done; 736 goto done;