mirror of https://gitee.com/openkylin/linux.git
[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>
This commit is contained in:
parent
40859ae5f1
commit
cbc8eb67da
|
@ -2223,6 +2223,7 @@ struct qla_hw_data {
|
|||
uint32_t fac_supported :1;
|
||||
uint32_t chip_reset_done :1;
|
||||
uint32_t port0 :1;
|
||||
uint32_t running_gold_fw :1;
|
||||
} flags;
|
||||
|
||||
/* This spinlock is used to protect "io transactions", you must
|
||||
|
@ -2523,6 +2524,7 @@ struct qla_hw_data {
|
|||
uint32_t flt_region_vpd;
|
||||
uint32_t flt_region_nvram;
|
||||
uint32_t flt_region_npiv_conf;
|
||||
uint32_t flt_region_gold_fw;
|
||||
|
||||
/* Needed for BEACON */
|
||||
uint16_t beacon_blink_led;
|
||||
|
|
|
@ -1241,6 +1241,7 @@ struct qla_flt_header {
|
|||
#define FLT_REG_HW_EVENT_1 0x1f
|
||||
#define FLT_REG_NPIV_CONF_0 0x29
|
||||
#define FLT_REG_NPIV_CONF_1 0x2a
|
||||
#define FLT_REG_GOLD_FW 0x2f
|
||||
|
||||
struct qla_flt_region {
|
||||
uint32_t code;
|
||||
|
|
|
@ -3806,11 +3806,11 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
|
|||
}
|
||||
|
||||
static int
|
||||
qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr)
|
||||
qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
uint32_t faddr)
|
||||
{
|
||||
int rval = QLA_SUCCESS;
|
||||
int segments, fragment;
|
||||
uint32_t faddr;
|
||||
uint32_t *dcode, dlen;
|
||||
uint32_t risc_addr;
|
||||
uint32_t risc_size;
|
||||
|
@ -3819,12 +3819,11 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr)
|
|||
struct req_que *req = ha->req_q_map[0];
|
||||
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"FW: Loading from flash (%x)...\n", ha->flt_region_fw);
|
||||
"FW: Loading from flash (%x)...\n", faddr);
|
||||
|
||||
rval = QLA_SUCCESS;
|
||||
|
||||
segments = FA_RISC_CODE_SEGMENTS;
|
||||
faddr = ha->flt_region_fw;
|
||||
dcode = (uint32_t *)req->ring;
|
||||
*srisc_addr = 0;
|
||||
|
||||
|
@ -4124,27 +4123,45 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
|
|||
if (rval == QLA_SUCCESS)
|
||||
return rval;
|
||||
|
||||
return qla24xx_load_risc_flash(vha, srisc_addr);
|
||||
return qla24xx_load_risc_flash(vha, srisc_addr,
|
||||
vha->hw->flt_region_fw);
|
||||
}
|
||||
|
||||
int
|
||||
qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
|
||||
{
|
||||
int rval;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (ql2xfwloadbin == 2)
|
||||
return qla24xx_load_risc(vha, srisc_addr);
|
||||
goto try_blob_fw;
|
||||
|
||||
/*
|
||||
* FW Load priority:
|
||||
* 1) Firmware residing in flash.
|
||||
* 2) Firmware via request-firmware interface (.bin file).
|
||||
* 3) Golden-Firmware residing in flash -- limited operation.
|
||||
*/
|
||||
rval = qla24xx_load_risc_flash(vha, srisc_addr);
|
||||
rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw);
|
||||
if (rval == QLA_SUCCESS)
|
||||
return rval;
|
||||
|
||||
return qla24xx_load_risc_blob(vha, srisc_addr);
|
||||
try_blob_fw:
|
||||
rval = qla24xx_load_risc_blob(vha, srisc_addr);
|
||||
if (rval == QLA_SUCCESS || !ha->flt_region_gold_fw)
|
||||
return rval;
|
||||
|
||||
qla_printk(KERN_ERR, ha,
|
||||
"FW: Attempting to fallback to golden firmware...\n");
|
||||
rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_gold_fw);
|
||||
if (rval != QLA_SUCCESS)
|
||||
return rval;
|
||||
|
||||
qla_printk(KERN_ERR, ha,
|
||||
"FW: Please update operational firmware...\n");
|
||||
ha->flags.running_gold_fw = 1;
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1690,6 +1690,9 @@ qla2xxx_scan_start(struct Scsi_Host *shost)
|
|||
{
|
||||
scsi_qla_host_t *vha = shost_priv(shost);
|
||||
|
||||
if (vha->hw->flags.running_gold_fw)
|
||||
return;
|
||||
|
||||
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
|
||||
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
|
||||
set_bit(RSCN_UPDATE, &vha->dpc_flags);
|
||||
|
@ -1962,6 +1965,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
"Can't create queues, falling back to single"
|
||||
" queue mode\n");
|
||||
|
||||
if (ha->flags.running_gold_fw)
|
||||
goto skip_dpc;
|
||||
|
||||
/*
|
||||
* Startup the kernel thread for this host adapter
|
||||
*/
|
||||
|
@ -1974,6 +1980,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
goto probe_failed;
|
||||
}
|
||||
|
||||
skip_dpc:
|
||||
list_add_tail(&base_vha->list, &ha->vp_list);
|
||||
base_vha->host->irq = ha->pdev->irq;
|
||||
|
||||
|
|
|
@ -728,6 +728,9 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
|
|||
if (!ha->flags.port0)
|
||||
ha->flt_region_npiv_conf = start;
|
||||
break;
|
||||
case FLT_REG_GOLD_FW:
|
||||
ha->flt_region_gold_fw = start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
|
|
Loading…
Reference in New Issue