提交 d4e3e04d 编写于 作者: A Andrew Vasquez 提交者: James Bottomley

[SCSI] qla2xxx: Consolidate firmware-dump handling across ISPs.

Simplify and centralise buffer allocation/deallocation, as
there's no point in having two memory request methods.
Signed-off-by: NAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 cb63067a
...@@ -46,22 +46,16 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, ...@@ -46,22 +46,16 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
case 0: case 0:
if (ha->fw_dump_reading == 1) { if (ha->fw_dump_reading == 1) {
qla_printk(KERN_INFO, ha, qla_printk(KERN_INFO, ha,
"Firmware dump cleared on (%ld).\n", "Firmware dump cleared on (%ld).\n", ha->host_no);
ha->host_no);
vfree(ha->fw_dump_buffer); vfree(ha->fw_dump_buffer);
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
free_pages((unsigned long)ha->fw_dump,
ha->fw_dump_order);
ha->fw_dump_reading = 0;
ha->fw_dump_buffer = NULL; ha->fw_dump_buffer = NULL;
ha->fw_dump = NULL; ha->fw_dump_reading = 0;
ha->fw_dumped = 0; ha->fw_dumped = 0;
} }
break; break;
case 1: case 1:
if ((ha->fw_dump || ha->fw_dumped) && !ha->fw_dump_reading) { if (ha->fw_dumped && !ha->fw_dump_reading) {
ha->fw_dump_reading = 1; ha->fw_dump_reading = 1;
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
......
...@@ -28,7 +28,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -28,7 +28,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
uint16_t __iomem *dmp_reg; uint16_t __iomem *dmp_reg;
unsigned long flags; unsigned long flags;
struct qla2300_fw_dump *fw; struct qla2300_fw_dump *fw;
uint32_t dump_size, data_ram_cnt; uint32_t data_ram_cnt;
risc_address = data_ram_cnt = 0; risc_address = data_ram_cnt = 0;
mb0 = mb2 = 0; mb0 = mb2 = 0;
...@@ -37,23 +37,16 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -37,23 +37,16 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
if (!hardware_locked) if (!hardware_locked)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
if (ha->fw_dump != NULL) { if (!ha->fw_dump) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Firmware has been previously dumped (%p) -- ignoring " "No buffer available for dump!!!\n");
"request...\n", ha->fw_dump);
goto qla2300_fw_dump_failed; goto qla2300_fw_dump_failed;
} }
/* Allocate (large) dump buffer. */ if (ha->fw_dumped) {
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, qla_printk(KERN_WARNING, ha,
"Unable to allocated memory for firmware dump (%d/%d).\n", "Firmware has been previously dumped (%p) -- ignoring "
ha->fw_dump_order, dump_size); "request...\n", ha->fw_dump);
goto qla2300_fw_dump_failed; goto qla2300_fw_dump_failed;
} }
fw = ha->fw_dump; fw = ha->fw_dump;
...@@ -358,17 +351,16 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -358,17 +351,16 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
} }
} }
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Failed to dump firmware (%x)!!!\n", rval); "Failed to dump firmware (%x)!!!\n", rval);
ha->fw_dumped = 0;
free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);
ha->fw_dump = NULL;
} else { } else {
qla_printk(KERN_INFO, ha, qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n", "Firmware dump saved to temp buffer (%ld/%p).\n",
ha->host_no, ha->fw_dump); ha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
} }
qla2300_fw_dump_failed: qla2300_fw_dump_failed:
...@@ -587,21 +579,16 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -587,21 +579,16 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
if (!hardware_locked) if (!hardware_locked)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
if (ha->fw_dump != NULL) { if (!ha->fw_dump) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Firmware has been previously dumped (%p) -- ignoring " "No buffer available for dump!!!\n");
"request...\n", ha->fw_dump);
goto qla2100_fw_dump_failed; goto qla2100_fw_dump_failed;
} }
/* Allocate (large) dump buffer. */ if (ha->fw_dumped) {
ha->fw_dump_order = get_order(sizeof(struct qla2100_fw_dump));
ha->fw_dump = (struct qla2100_fw_dump *) __get_free_pages(GFP_ATOMIC,
ha->fw_dump_order);
if (ha->fw_dump == NULL) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Unable to allocated memory for firmware dump (%d/%Zd).\n", "Firmware has been previously dumped (%p) -- ignoring "
ha->fw_dump_order, sizeof(struct qla2100_fw_dump)); "request...\n", ha->fw_dump);
goto qla2100_fw_dump_failed; goto qla2100_fw_dump_failed;
} }
fw = ha->fw_dump; fw = ha->fw_dump;
...@@ -777,13 +764,13 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -777,13 +764,13 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Failed to dump firmware (%x)!!!\n", rval); "Failed to dump firmware (%x)!!!\n", rval);
ha->fw_dumped = 0;
free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);
ha->fw_dump = NULL;
} else { } else {
qla_printk(KERN_INFO, ha, qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n", "Firmware dump saved to temp buffer (%ld/%p).\n",
ha->host_no, ha->fw_dump); ha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
} }
qla2100_fw_dump_failed: qla2100_fw_dump_failed:
...@@ -988,7 +975,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -988,7 +975,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
if (!hardware_locked) if (!hardware_locked)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
if (!ha->fw_dump24) { if (!ha->fw_dump) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"No buffer available for dump!!!\n"); "No buffer available for dump!!!\n");
goto qla24xx_fw_dump_failed; goto qla24xx_fw_dump_failed;
...@@ -997,10 +984,10 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -997,10 +984,10 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
if (ha->fw_dumped) { if (ha->fw_dumped) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Firmware has been previously dumped (%p) -- ignoring " "Firmware has been previously dumped (%p) -- ignoring "
"request...\n", ha->fw_dump24); "request...\n", ha->fw_dump);
goto qla24xx_fw_dump_failed; goto qla24xx_fw_dump_failed;
} }
fw = (struct qla24xx_fw_dump *) ha->fw_dump24; fw = ha->fw_dump;
rval = QLA_SUCCESS; rval = QLA_SUCCESS;
fw->host_status = RD_REG_DWORD(&reg->host_status); fw->host_status = RD_REG_DWORD(&reg->host_status);
...@@ -1654,7 +1641,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) ...@@ -1654,7 +1641,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
} else { } else {
qla_printk(KERN_INFO, ha, qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n", "Firmware dump saved to temp buffer (%ld/%p).\n",
ha->host_no, ha->fw_dump24); ha->host_no, ha->fw_dump);
ha->fw_dumped = 1; ha->fw_dumped = 1;
} }
...@@ -1672,7 +1659,7 @@ qla24xx_ascii_fw_dump(scsi_qla_host_t *ha) ...@@ -1672,7 +1659,7 @@ qla24xx_ascii_fw_dump(scsi_qla_host_t *ha)
uint32_t ext_mem_cnt; uint32_t ext_mem_cnt;
uiter = ha->fw_dump_buffer; uiter = ha->fw_dump_buffer;
fw = ha->fw_dump24; fw = ha->fw_dump;
qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n", qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n",
ha->fw_major_version, ha->fw_minor_version, ha->fw_major_version, ha->fw_minor_version,
......
...@@ -2304,15 +2304,11 @@ typedef struct scsi_qla_host { ...@@ -2304,15 +2304,11 @@ typedef struct scsi_qla_host {
/* Firmware dump information. */ /* Firmware dump information. */
void *fw_dump; void *fw_dump;
int fw_dump_order; int fw_dumped;
int fw_dump_reading; int fw_dump_reading;
char *fw_dump_buffer; char *fw_dump_buffer;
int fw_dump_buffer_len; int fw_dump_buffer_len;
int fw_dumped;
void *fw_dump24;
int fw_dump24_len;
uint8_t host_str[16]; uint8_t host_str[16];
uint32_t pci_attr; uint32_t pci_attr;
......
...@@ -773,16 +773,26 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) ...@@ -773,16 +773,26 @@ qla24xx_chip_diag(scsi_qla_host_t *ha)
static void static void
qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) qla2x00_alloc_fw_dump(scsi_qla_host_t *ha)
{ {
uint32_t dump_size = 0;
ha->fw_dumped = 0; ha->fw_dumped = 0;
ha->fw_dump24_len = sizeof(struct qla24xx_fw_dump); if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
ha->fw_dump24_len += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t); dump_size = sizeof(struct qla2100_fw_dump);
ha->fw_dump24 = vmalloc(ha->fw_dump24_len); } else if (IS_QLA23XX(ha)) {
if (ha->fw_dump24) dump_size = sizeof(struct qla2300_fw_dump);
dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t);
} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
dump_size = sizeof(struct qla24xx_fw_dump);
dump_size += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t);
}
ha->fw_dump = vmalloc(dump_size);
if (ha->fw_dump)
qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware " qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware "
"dump...\n", ha->fw_dump24_len / 1024); "dump...\n", dump_size / 1024);
else else
qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for "
"firmware dump!!!\n", ha->fw_dump24_len / 1024); "firmware dump!!!\n", dump_size / 1024);
} }
/** /**
...@@ -800,13 +810,12 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) ...@@ -800,13 +810,12 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha)
dma_addr_t request_dma; dma_addr_t request_dma;
request_t *request_ring; request_t *request_ring;
qla2x00_alloc_fw_dump(ha);
/* Valid only on recent ISPs. */ /* Valid only on recent ISPs. */
if (IS_QLA2100(ha) || IS_QLA2200(ha)) if (IS_QLA2100(ha) || IS_QLA2200(ha))
return; return;
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
qla2x00_alloc_fw_dump(ha);
/* Retrieve IOCB counts available to the firmware. */ /* Retrieve IOCB counts available to the firmware. */
rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt); rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt);
if (rval) if (rval)
......
...@@ -2068,15 +2068,10 @@ qla2x00_mem_free(scsi_qla_host_t *ha) ...@@ -2068,15 +2068,10 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
} }
INIT_LIST_HEAD(&ha->fcports); INIT_LIST_HEAD(&ha->fcports);
if (ha->fw_dump) vfree(ha->fw_dump);
free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);
vfree(ha->fw_dump24);
vfree(ha->fw_dump_buffer); vfree(ha->fw_dump_buffer);
ha->fw_dump = NULL; ha->fw_dump = NULL;
ha->fw_dump24 = NULL;
ha->fw_dumped = 0; ha->fw_dumped = 0;
ha->fw_dump_reading = 0; ha->fw_dump_reading = 0;
ha->fw_dump_buffer = NULL; ha->fw_dump_buffer = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册