Commit 3420d36c authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley

[SCSI] qla2xxx: Add firmware-dump kobject uevent notification.

Signed-off-by: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent f8ceafde
What: /sys/bus/pci/drivers/qla2xxx/.../devices/*
Date: September 2009
Contact: QLogic Linux Driver <linux-driver@qlogic.com>
Description: qla2xxx-udev.sh currently looks for uevent CHANGE events to
signal a firmware-dump has been generated by the driver and is
ready for retrieval.
Users: qla2xxx-udev.sh. Proposed changes should be mailed to
linux-driver@qlogic.com
...@@ -377,6 +377,24 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) ...@@ -377,6 +377,24 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
return ptr + sizeof(struct qla2xxx_mq_chain); return ptr + sizeof(struct qla2xxx_mq_chain);
} }
static void
qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
{
struct qla_hw_data *ha = vha->hw;
if (rval != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha,
"Failed to dump firmware (%x)!!!\n", rval);
ha->fw_dumped = 0;
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
}
}
/** /**
* qla2300_fw_dump() - Dumps binary data from the 2300 firmware. * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
* @ha: HA context * @ha: HA context
...@@ -530,17 +548,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked) ...@@ -530,17 +548,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
if (rval == QLA_SUCCESS) if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(ha, nxt); qla2xxx_copy_queues(ha, nxt);
if (rval != QLA_SUCCESS) { qla2xxx_dump_post_process(base_vha, rval);
qla_printk(KERN_WARNING, ha,
"Failed to dump firmware (%x)!!!\n", rval);
ha->fw_dumped = 0;
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}
qla2300_fw_dump_failed: qla2300_fw_dump_failed:
if (!hardware_locked) if (!hardware_locked)
...@@ -737,17 +745,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked) ...@@ -737,17 +745,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
if (rval == QLA_SUCCESS) if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]); qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
if (rval != QLA_SUCCESS) { qla2xxx_dump_post_process(base_vha, rval);
qla_printk(KERN_WARNING, ha,
"Failed to dump firmware (%x)!!!\n", rval);
ha->fw_dumped = 0;
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}
qla2100_fw_dump_failed: qla2100_fw_dump_failed:
if (!hardware_locked) if (!hardware_locked)
...@@ -984,17 +982,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) ...@@ -984,17 +982,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
qla24xx_copy_eft(ha, nxt); qla24xx_copy_eft(ha, nxt);
qla24xx_fw_dump_failed_0: qla24xx_fw_dump_failed_0:
if (rval != QLA_SUCCESS) { qla2xxx_dump_post_process(base_vha, rval);
qla_printk(KERN_WARNING, ha,
"Failed to dump firmware (%x)!!!\n", rval);
ha->fw_dumped = 0;
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}
qla24xx_fw_dump_failed: qla24xx_fw_dump_failed:
if (!hardware_locked) if (!hardware_locked)
...@@ -1305,17 +1293,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) ...@@ -1305,17 +1293,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
} }
qla25xx_fw_dump_failed_0: qla25xx_fw_dump_failed_0:
if (rval != QLA_SUCCESS) { qla2xxx_dump_post_process(base_vha, rval);
qla_printk(KERN_WARNING, ha,
"Failed to dump firmware (%x)!!!\n", rval);
ha->fw_dumped = 0;
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}
qla25xx_fw_dump_failed: qla25xx_fw_dump_failed:
if (!hardware_locked) if (!hardware_locked)
...@@ -1628,17 +1606,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) ...@@ -1628,17 +1606,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
} }
qla81xx_fw_dump_failed_0: qla81xx_fw_dump_failed_0:
if (rval != QLA_SUCCESS) { qla2xxx_dump_post_process(base_vha, rval);
qla_printk(KERN_WARNING, ha,
"Failed to dump firmware (%x)!!!\n", rval);
ha->fw_dumped = 0;
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}
qla81xx_fw_dump_failed: qla81xx_fw_dump_failed:
if (!hardware_locked) if (!hardware_locked)
......
...@@ -2123,6 +2123,7 @@ enum qla_work_type { ...@@ -2123,6 +2123,7 @@ enum qla_work_type {
QLA_EVT_ASYNC_LOGIN_DONE, QLA_EVT_ASYNC_LOGIN_DONE,
QLA_EVT_ASYNC_LOGOUT, QLA_EVT_ASYNC_LOGOUT,
QLA_EVT_ASYNC_LOGOUT_DONE, QLA_EVT_ASYNC_LOGOUT_DONE,
QLA_EVT_UEVENT,
}; };
...@@ -2146,6 +2147,10 @@ struct qla_work_evt { ...@@ -2146,6 +2147,10 @@ struct qla_work_evt {
#define QLA_LOGIO_LOGIN_RETRIED BIT_0 #define QLA_LOGIO_LOGIN_RETRIED BIT_0
u16 data[2]; u16 data[2];
} logio; } logio;
struct {
u32 code;
#define QLA_UEVENT_CODE_FW_DUMP 0
} uevent;
} u; } u;
}; };
......
...@@ -92,6 +92,7 @@ extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *, ...@@ -92,6 +92,7 @@ extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *); uint16_t *);
extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *, extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
fc_port_t *, uint16_t *); fc_port_t *, uint16_t *);
extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/kobject.h>
#include <scsi/scsi_tcq.h> #include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h> #include <scsi/scsicam.h>
...@@ -2653,6 +2654,37 @@ qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE); ...@@ -2653,6 +2654,37 @@ qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
int
qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code)
{
struct qla_work_evt *e;
e = qla2x00_alloc_work(vha, QLA_EVT_UEVENT);
if (!e)
return QLA_FUNCTION_FAILED;
e->u.uevent.code = code;
return qla2x00_post_work(vha, e);
}
static void
qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code)
{
char event_string[40];
char *envp[] = { event_string, NULL };
switch (code) {
case QLA_UEVENT_CODE_FW_DUMP:
snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld",
vha->host_no);
break;
default:
/* do nothing */
break;
}
kobject_uevent_env(&vha->hw->pdev->dev.kobj, KOBJ_CHANGE, envp);
}
void void
qla2x00_do_work(struct scsi_qla_host *vha) qla2x00_do_work(struct scsi_qla_host *vha)
{ {
...@@ -2690,6 +2722,9 @@ qla2x00_do_work(struct scsi_qla_host *vha) ...@@ -2690,6 +2722,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
qla2x00_async_logout_done(vha, e->u.logio.fcport, qla2x00_async_logout_done(vha, e->u.logio.fcport,
e->u.logio.data); e->u.logio.data);
break; break;
case QLA_EVT_UEVENT:
qla2x00_uevent_emit(vha, e->u.uevent.code);
break;
} }
if (e->flags & QLA_EVT_FLAG_FREE) if (e->flags & QLA_EVT_FLAG_FREE)
kfree(e); kfree(e);
......
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