[SCSI] qla2xxx: Add firmware-dump kobject uevent notification.
authorAndrew Vasquez <andrew.vasquez@qlogic.com>
Tue, 13 Oct 2009 22:16:45 +0000 (15:16 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Fri, 4 Dec 2009 18:00:10 +0000 (12:00 -0600)
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Documentation/ABI/stable/sysfs-driver-qla2xxx [new file with mode: 0644]
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_os.c

diff --git a/Documentation/ABI/stable/sysfs-driver-qla2xxx b/Documentation/ABI/stable/sysfs-driver-qla2xxx
new file mode 100644 (file)
index 0000000..9a59d84
--- /dev/null
@@ -0,0 +1,8 @@
+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
index cca8e4ab0372fb4625d0e269e0c07a67ea14fa64..cb2eca4c26d801b24faccd43f622647f7c655ae7 100644 (file)
@@ -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);
 }
 
+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.
  * @ha: HA context
@@ -530,17 +548,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
        if (rval == QLA_SUCCESS)
                qla2xxx_copy_queues(ha, nxt);
 
-       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",
-                   base_vha->host_no, ha->fw_dump);
-               ha->fw_dumped = 1;
-       }
+       qla2xxx_dump_post_process(base_vha, rval);
 
 qla2300_fw_dump_failed:
        if (!hardware_locked)
@@ -737,17 +745,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
        if (rval == QLA_SUCCESS)
                qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
 
-       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",
-                   base_vha->host_no, ha->fw_dump);
-               ha->fw_dumped = 1;
-       }
+       qla2xxx_dump_post_process(base_vha, rval);
 
 qla2100_fw_dump_failed:
        if (!hardware_locked)
@@ -984,17 +982,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
        qla24xx_copy_eft(ha, nxt);
 
 qla24xx_fw_dump_failed_0:
-       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",
-                   base_vha->host_no, ha->fw_dump);
-               ha->fw_dumped = 1;
-       }
+       qla2xxx_dump_post_process(base_vha, rval);
 
 qla24xx_fw_dump_failed:
        if (!hardware_locked)
@@ -1305,17 +1293,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
        }
 
 qla25xx_fw_dump_failed_0:
-       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",
-                   base_vha->host_no, ha->fw_dump);
-               ha->fw_dumped = 1;
-       }
+       qla2xxx_dump_post_process(base_vha, rval);
 
 qla25xx_fw_dump_failed:
        if (!hardware_locked)
@@ -1628,17 +1606,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
        }
 
 qla81xx_fw_dump_failed_0:
-       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",
-                   base_vha->host_no, ha->fw_dump);
-               ha->fw_dumped = 1;
-       }
+       qla2xxx_dump_post_process(base_vha, rval);
 
 qla81xx_fw_dump_failed:
        if (!hardware_locked)
index 21506186179435eca813a772b463526dde10aef9..d8ce31040b51d438dd734df0873351372c937942 100644 (file)
@@ -2123,6 +2123,7 @@ enum qla_work_type {
        QLA_EVT_ASYNC_LOGIN_DONE,
        QLA_EVT_ASYNC_LOGOUT,
        QLA_EVT_ASYNC_LOGOUT_DONE,
+       QLA_EVT_UEVENT,
 };
 
 
@@ -2146,6 +2147,10 @@ struct qla_work_evt {
 #define QLA_LOGIO_LOGIN_RETRIED        BIT_0
                        u16 data[2];
                } logio;
+               struct {
+                       u32 code;
+#define QLA_UEVENT_CODE_FW_DUMP        0
+               } uevent;
        } u;
 };
 
index f3d1d1afa95b268a6ac47626e004f522b7223918..14e0562851cb682147921d2ef0a8342b07d4a321 100644 (file)
@@ -92,6 +92,7 @@ extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
     uint16_t *);
 extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
     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 *);
 
index b79fca7d461b46bf827802e94e98149cc73c00b7..ecf2a40d70beee11aba4e974ed97552579ed68d3 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
+#include <linux/kobject.h>
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsicam.h>
@@ -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_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
 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,
                            e->u.logio.data);
                        break;
+               case QLA_EVT_UEVENT:
+                       qla2x00_uevent_emit(vha, e->u.uevent.code);
+                       break;
                }
                if (e->flags & QLA_EVT_FLAG_FREE)
                        kfree(e);