Commit bb738dca authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley

[PATCH] [12/18] qla2xxx: Extend firmware dump support

  Add firmware dump support for ISPs with memory chips larger than
  128KB (512/1024KB).
Signed-off-by: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent b90da76b
......@@ -40,9 +40,10 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
uint16_t *dmp_reg;
unsigned long flags;
struct qla2300_fw_dump *fw;
uint32_t dump_size, data_ram_cnt;
reg = ha->iobase;
risc_address = 0;
risc_address = data_ram_cnt = 0;
mb0 = mb2 = 0;
flags = 0;
......@@ -57,13 +58,15 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
}
/* Allocate (large) dump buffer. */
ha->fw_dump_order = get_order(sizeof(struct qla2300_fw_dump));
dump_size = sizeof(struct qla2300_fw_dump);
dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t);
ha->fw_dump_order = get_order(dump_size);
ha->fw_dump = (struct qla2300_fw_dump *) __get_free_pages(GFP_ATOMIC,
ha->fw_dump_order);
if (ha->fw_dump == NULL) {
qla_printk(KERN_WARNING, ha,
"Unable to allocated memory for firmware dump (%d/%Zd).\n",
ha->fw_dump_order, sizeof(struct qla2300_fw_dump));
"Unable to allocated memory for firmware dump (%d/%d).\n",
ha->fw_dump_order, dump_size);
goto qla2300_fw_dump_failed;
}
fw = ha->fw_dump;
......@@ -304,10 +307,11 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
if (rval == QLA_SUCCESS) {
/* Get data SRAM. */
risc_address = 0x11000;
data_ram_cnt = ha->fw_memory_size - risc_address + 1;
WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);
clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
}
for (cnt = 0; cnt < sizeof(fw->data_ram) / 2 && rval == QLA_SUCCESS;
for (cnt = 0; cnt < data_ram_cnt && rval == QLA_SUCCESS;
cnt++, risc_address++) {
WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address));
WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));
......@@ -386,6 +390,7 @@ qla2300_ascii_fw_dump(scsi_qla_host_t *ha)
char *uiter;
char fw_info[30];
struct qla2300_fw_dump *fw;
uint32_t data_ram_cnt;
uiter = ha->fw_dump_buffer;
fw = ha->fw_dump;
......@@ -550,7 +555,8 @@ qla2300_ascii_fw_dump(scsi_qla_host_t *ha)
}
qla_uprintf(&uiter, "\n\nData RAM Dump:");
for (cnt = 0; cnt < sizeof (fw->data_ram) / 2; cnt++) {
data_ram_cnt = ha->fw_memory_size - 0x11000 + 1;
for (cnt = 0; cnt < data_ram_cnt; cnt++) {
if (cnt % 8 == 0) {
qla_uprintf(&uiter, "\n%05x: ", cnt + 0x11000);
}
......
......@@ -182,7 +182,9 @@
/*
* Firmware Dump structure definition
*/
#define FW_DUMP_SIZE 0xBC000 /* bytes */
#define FW_DUMP_SIZE_128K 0xBC000
#define FW_DUMP_SIZE_512K 0x2FC000
#define FW_DUMP_SIZE_1M 0x5FC000
struct qla2300_fw_dump {
uint16_t hccr;
......@@ -205,7 +207,7 @@ struct qla2300_fw_dump {
uint16_t fpm_b1_reg[64];
uint16_t risc_ram[0xf800];
uint16_t stack_ram[0x1000];
uint16_t data_ram[0xF000];
uint16_t data_ram[1];
};
struct qla2100_fw_dump {
......
......@@ -2303,6 +2303,7 @@ typedef struct scsi_qla_host {
uint16_t fw_minor_version;
uint16_t fw_subminor_version;
uint16_t fw_attributes;
uint32_t fw_memory_size;
uint32_t fw_transfer_size;
uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */
......
......@@ -139,7 +139,7 @@ qla2x00_execute_fw(scsi_qla_host_t *);
extern void
qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *,
uint16_t *, uint16_t *, uint16_t *);
uint16_t *, uint16_t *, uint16_t *, uint32_t *);
extern int
qla2x00_get_fw_options(scsi_qla_host_t *, uint16_t *);
......
......@@ -220,11 +220,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
} while (restart_risc && retry--);
if (rval == QLA_SUCCESS) {
/* Retrieve firmware information */
qla2x00_get_fw_version(ha, &ha->fw_major_version,
&ha->fw_minor_version, &ha->fw_subminor_version,
&ha->fw_attributes);
clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
ha->marker_needed = 1;
qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
......@@ -730,6 +725,14 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
"firmware.\n", ha->host_no));
rval = qla2x00_execute_fw(ha);
/* Retrieve firmware information. */
if (rval == QLA_SUCCESS && ha->fw_major_version == 0) {
qla2x00_get_fw_version(ha,
&ha->fw_major_version,
&ha->fw_minor_version,
&ha->fw_subminor_version,
&ha->fw_attributes, &ha->fw_memory_size);
}
}
else {
DEBUG2(printk(KERN_INFO
......
......@@ -546,7 +546,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha)
*/
void
qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor,
uint16_t *subminor, uint16_t *attributes)
uint16_t *subminor, uint16_t *attributes, uint32_t *memory)
{
int rval;
mbx_cmd_t mc;
......@@ -556,7 +556,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor,
mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
mcp->out_mb = MBX_0;
mcp->in_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->flags = 0;
mcp->tov = 30;
rval = qla2x00_mailbox_command(ha, mcp);
......@@ -566,6 +566,10 @@ qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor,
*minor = mcp->mb[2];
*subminor = mcp->mb[3];
*attributes = mcp->mb[6];
if (IS_QLA2100(ha) || IS_QLA2200(ha))
*memory = 0x1FFFF; /* Defaults to 128KB. */
else
*memory = (mcp->mb[5] << 16) | mcp->mb[4];
if (rval != QLA_SUCCESS) {
/*EMPTY*/
......
......@@ -455,6 +455,7 @@ static ssize_t qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf,
struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
struct device, kobj)));
int reading;
uint32_t dump_size;
if (off != 0)
return (0);
......@@ -480,11 +481,16 @@ static ssize_t qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf,
if (ha->fw_dump != NULL && !ha->fw_dump_reading) {
ha->fw_dump_reading = 1;
ha->fw_dump_buffer = (char *)vmalloc(FW_DUMP_SIZE);
dump_size = FW_DUMP_SIZE_1M;
if (ha->fw_memory_size < 0x20000)
dump_size = FW_DUMP_SIZE_128K;
else if (ha->fw_memory_size < 0x80000)
dump_size = FW_DUMP_SIZE_512K;
ha->fw_dump_buffer = (char *)vmalloc(dump_size);
if (ha->fw_dump_buffer == NULL) {
qla_printk(KERN_WARNING, ha,
"Unable to allocate memory for firmware "
"dump buffer (%d).\n", FW_DUMP_SIZE);
"dump buffer (%d).\n", dump_size);
ha->fw_dump_reading = 0;
return (count);
......@@ -492,7 +498,7 @@ static ssize_t qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf,
qla_printk(KERN_INFO, ha,
"Firmware dump ready for read on (%ld).\n",
ha->host_no);
memset(ha->fw_dump_buffer, 0, FW_DUMP_SIZE);
memset(ha->fw_dump_buffer, 0, dump_size);
if (IS_QLA2100(ha) || IS_QLA2200(ha))
qla2100_ascii_fw_dump(ha);
else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment