diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2009-10-13 18:16:45 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:00:10 -0500 |
commit | 3420d36cac2f1d28fc99290de12dd66dfaf65d8e (patch) | |
tree | f506e7c91fc8a0b801e594412f264dfd3ebe3ed1 | |
parent | f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2e (diff) |
[SCSI] qla2xxx: Add firmware-dump kobject uevent notification.
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>
-rw-r--r-- | Documentation/ABI/stable/sysfs-driver-qla2xxx | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 78 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 5 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 35 |
5 files changed, 72 insertions, 55 deletions
diff --git a/Documentation/ABI/stable/sysfs-driver-qla2xxx b/Documentation/ABI/stable/sysfs-driver-qla2xxx new file mode 100644 index 000000000000..9a59d84497ed --- /dev/null +++ b/Documentation/ABI/stable/sysfs-driver-qla2xxx | |||
@@ -0,0 +1,8 @@ | |||
1 | What: /sys/bus/pci/drivers/qla2xxx/.../devices/* | ||
2 | Date: September 2009 | ||
3 | Contact: QLogic Linux Driver <linux-driver@qlogic.com> | ||
4 | Description: qla2xxx-udev.sh currently looks for uevent CHANGE events to | ||
5 | signal a firmware-dump has been generated by the driver and is | ||
6 | ready for retrieval. | ||
7 | Users: qla2xxx-udev.sh. Proposed changes should be mailed to | ||
8 | linux-driver@qlogic.com | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index cca8e4ab0372..cb2eca4c26d8 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -377,6 +377,24 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | |||
377 | return ptr + sizeof(struct qla2xxx_mq_chain); | 377 | return ptr + sizeof(struct qla2xxx_mq_chain); |
378 | } | 378 | } |
379 | 379 | ||
380 | static void | ||
381 | qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval) | ||
382 | { | ||
383 | struct qla_hw_data *ha = vha->hw; | ||
384 | |||
385 | if (rval != QLA_SUCCESS) { | ||
386 | qla_printk(KERN_WARNING, ha, | ||
387 | "Failed to dump firmware (%x)!!!\n", rval); | ||
388 | ha->fw_dumped = 0; | ||
389 | } else { | ||
390 | qla_printk(KERN_INFO, ha, | ||
391 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
392 | vha->host_no, ha->fw_dump); | ||
393 | ha->fw_dumped = 1; | ||
394 | qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); | ||
395 | } | ||
396 | } | ||
397 | |||
380 | /** | 398 | /** |
381 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 399 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
382 | * @ha: HA context | 400 | * @ha: HA context |
@@ -530,17 +548,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
530 | if (rval == QLA_SUCCESS) | 548 | if (rval == QLA_SUCCESS) |
531 | qla2xxx_copy_queues(ha, nxt); | 549 | qla2xxx_copy_queues(ha, nxt); |
532 | 550 | ||
533 | if (rval != QLA_SUCCESS) { | 551 | qla2xxx_dump_post_process(base_vha, rval); |
534 | qla_printk(KERN_WARNING, ha, | ||
535 | "Failed to dump firmware (%x)!!!\n", rval); | ||
536 | ha->fw_dumped = 0; | ||
537 | |||
538 | } else { | ||
539 | qla_printk(KERN_INFO, ha, | ||
540 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
541 | base_vha->host_no, ha->fw_dump); | ||
542 | ha->fw_dumped = 1; | ||
543 | } | ||
544 | 552 | ||
545 | qla2300_fw_dump_failed: | 553 | qla2300_fw_dump_failed: |
546 | if (!hardware_locked) | 554 | if (!hardware_locked) |
@@ -737,17 +745,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
737 | if (rval == QLA_SUCCESS) | 745 | if (rval == QLA_SUCCESS) |
738 | qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]); | 746 | qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]); |
739 | 747 | ||
740 | if (rval != QLA_SUCCESS) { | 748 | qla2xxx_dump_post_process(base_vha, rval); |
741 | qla_printk(KERN_WARNING, ha, | ||
742 | "Failed to dump firmware (%x)!!!\n", rval); | ||
743 | ha->fw_dumped = 0; | ||
744 | |||
745 | } else { | ||
746 | qla_printk(KERN_INFO, ha, | ||
747 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
748 | base_vha->host_no, ha->fw_dump); | ||
749 | ha->fw_dumped = 1; | ||
750 | } | ||
751 | 749 | ||
752 | qla2100_fw_dump_failed: | 750 | qla2100_fw_dump_failed: |
753 | if (!hardware_locked) | 751 | if (!hardware_locked) |
@@ -984,17 +982,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
984 | qla24xx_copy_eft(ha, nxt); | 982 | qla24xx_copy_eft(ha, nxt); |
985 | 983 | ||
986 | qla24xx_fw_dump_failed_0: | 984 | qla24xx_fw_dump_failed_0: |
987 | if (rval != QLA_SUCCESS) { | 985 | qla2xxx_dump_post_process(base_vha, rval); |
988 | qla_printk(KERN_WARNING, ha, | ||
989 | "Failed to dump firmware (%x)!!!\n", rval); | ||
990 | ha->fw_dumped = 0; | ||
991 | |||
992 | } else { | ||
993 | qla_printk(KERN_INFO, ha, | ||
994 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
995 | base_vha->host_no, ha->fw_dump); | ||
996 | ha->fw_dumped = 1; | ||
997 | } | ||
998 | 986 | ||
999 | qla24xx_fw_dump_failed: | 987 | qla24xx_fw_dump_failed: |
1000 | if (!hardware_locked) | 988 | if (!hardware_locked) |
@@ -1305,17 +1293,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1305 | } | 1293 | } |
1306 | 1294 | ||
1307 | qla25xx_fw_dump_failed_0: | 1295 | qla25xx_fw_dump_failed_0: |
1308 | if (rval != QLA_SUCCESS) { | 1296 | qla2xxx_dump_post_process(base_vha, rval); |
1309 | qla_printk(KERN_WARNING, ha, | ||
1310 | "Failed to dump firmware (%x)!!!\n", rval); | ||
1311 | ha->fw_dumped = 0; | ||
1312 | |||
1313 | } else { | ||
1314 | qla_printk(KERN_INFO, ha, | ||
1315 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
1316 | base_vha->host_no, ha->fw_dump); | ||
1317 | ha->fw_dumped = 1; | ||
1318 | } | ||
1319 | 1297 | ||
1320 | qla25xx_fw_dump_failed: | 1298 | qla25xx_fw_dump_failed: |
1321 | if (!hardware_locked) | 1299 | if (!hardware_locked) |
@@ -1628,17 +1606,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1628 | } | 1606 | } |
1629 | 1607 | ||
1630 | qla81xx_fw_dump_failed_0: | 1608 | qla81xx_fw_dump_failed_0: |
1631 | if (rval != QLA_SUCCESS) { | 1609 | qla2xxx_dump_post_process(base_vha, rval); |
1632 | qla_printk(KERN_WARNING, ha, | ||
1633 | "Failed to dump firmware (%x)!!!\n", rval); | ||
1634 | ha->fw_dumped = 0; | ||
1635 | |||
1636 | } else { | ||
1637 | qla_printk(KERN_INFO, ha, | ||
1638 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
1639 | base_vha->host_no, ha->fw_dump); | ||
1640 | ha->fw_dumped = 1; | ||
1641 | } | ||
1642 | 1610 | ||
1643 | qla81xx_fw_dump_failed: | 1611 | qla81xx_fw_dump_failed: |
1644 | if (!hardware_locked) | 1612 | if (!hardware_locked) |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 215061861794..d8ce31040b51 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2123,6 +2123,7 @@ enum qla_work_type { | |||
2123 | QLA_EVT_ASYNC_LOGIN_DONE, | 2123 | QLA_EVT_ASYNC_LOGIN_DONE, |
2124 | QLA_EVT_ASYNC_LOGOUT, | 2124 | QLA_EVT_ASYNC_LOGOUT, |
2125 | QLA_EVT_ASYNC_LOGOUT_DONE, | 2125 | QLA_EVT_ASYNC_LOGOUT_DONE, |
2126 | QLA_EVT_UEVENT, | ||
2126 | }; | 2127 | }; |
2127 | 2128 | ||
2128 | 2129 | ||
@@ -2146,6 +2147,10 @@ struct qla_work_evt { | |||
2146 | #define QLA_LOGIO_LOGIN_RETRIED BIT_0 | 2147 | #define QLA_LOGIO_LOGIN_RETRIED BIT_0 |
2147 | u16 data[2]; | 2148 | u16 data[2]; |
2148 | } logio; | 2149 | } logio; |
2150 | struct { | ||
2151 | u32 code; | ||
2152 | #define QLA_UEVENT_CODE_FW_DUMP 0 | ||
2153 | } uevent; | ||
2149 | } u; | 2154 | } u; |
2150 | }; | 2155 | }; |
2151 | 2156 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f3d1d1afa95b..14e0562851cb 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -92,6 +92,7 @@ extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *, | |||
92 | uint16_t *); | 92 | uint16_t *); |
93 | extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *, | 93 | extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *, |
94 | fc_port_t *, uint16_t *); | 94 | fc_port_t *, uint16_t *); |
95 | extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); | ||
95 | 96 | ||
96 | extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); | 97 | extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); |
97 | 98 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b79fca7d461b..ecf2a40d70be 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/kthread.h> | 12 | #include <linux/kthread.h> |
13 | #include <linux/mutex.h> | 13 | #include <linux/mutex.h> |
14 | #include <linux/kobject.h> | ||
14 | 15 | ||
15 | #include <scsi/scsi_tcq.h> | 16 | #include <scsi/scsi_tcq.h> |
16 | #include <scsi/scsicam.h> | 17 | #include <scsi/scsicam.h> |
@@ -2653,6 +2654,37 @@ qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE); | |||
2653 | qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); | 2654 | qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); |
2654 | qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); | 2655 | qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); |
2655 | 2656 | ||
2657 | int | ||
2658 | qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code) | ||
2659 | { | ||
2660 | struct qla_work_evt *e; | ||
2661 | |||
2662 | e = qla2x00_alloc_work(vha, QLA_EVT_UEVENT); | ||
2663 | if (!e) | ||
2664 | return QLA_FUNCTION_FAILED; | ||
2665 | |||
2666 | e->u.uevent.code = code; | ||
2667 | return qla2x00_post_work(vha, e); | ||
2668 | } | ||
2669 | |||
2670 | static void | ||
2671 | qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code) | ||
2672 | { | ||
2673 | char event_string[40]; | ||
2674 | char *envp[] = { event_string, NULL }; | ||
2675 | |||
2676 | switch (code) { | ||
2677 | case QLA_UEVENT_CODE_FW_DUMP: | ||
2678 | snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", | ||
2679 | vha->host_no); | ||
2680 | break; | ||
2681 | default: | ||
2682 | /* do nothing */ | ||
2683 | break; | ||
2684 | } | ||
2685 | kobject_uevent_env(&vha->hw->pdev->dev.kobj, KOBJ_CHANGE, envp); | ||
2686 | } | ||
2687 | |||
2656 | void | 2688 | void |
2657 | qla2x00_do_work(struct scsi_qla_host *vha) | 2689 | qla2x00_do_work(struct scsi_qla_host *vha) |
2658 | { | 2690 | { |
@@ -2690,6 +2722,9 @@ qla2x00_do_work(struct scsi_qla_host *vha) | |||
2690 | qla2x00_async_logout_done(vha, e->u.logio.fcport, | 2722 | qla2x00_async_logout_done(vha, e->u.logio.fcport, |
2691 | e->u.logio.data); | 2723 | e->u.logio.data); |
2692 | break; | 2724 | break; |
2725 | case QLA_EVT_UEVENT: | ||
2726 | qla2x00_uevent_emit(vha, e->u.uevent.code); | ||
2727 | break; | ||
2693 | } | 2728 | } |
2694 | if (e->flags & QLA_EVT_FLAG_FREE) | 2729 | if (e->flags & QLA_EVT_FLAG_FREE) |
2695 | kfree(e); | 2730 | kfree(e); |