aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx
diff options
context:
space:
mode:
authorVikas Chaudhary <vikas.chaudhary@qlogic.com>2011-08-29 14:13:02 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 10:34:04 -0500
commitff884430801c08bd909fd95f6cb1a0446afd30db (patch)
tree19f42d50bcbd0e03add3460221d0c7eb716c9b0b /drivers/scsi/qla4xxx
parenta11e25459558421ec5c4adc3fc46fe320ab74bd3 (diff)
[SCSI] qla4xxx: added support for host event
Added support to post kernel host event to application using netlink interface. Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h18
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c6
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c85
4 files changed, 111 insertions, 0 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index ec48dc30b9a2..f91808ce572e 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -301,7 +301,21 @@ struct ql4_tuple_ddb {
301#define DF_ISNS_DISCOVERED 2 /* Device was discovered via iSNS */ 301#define DF_ISNS_DISCOVERED 2 /* Device was discovered via iSNS */
302#define DF_FO_MASKED 3 302#define DF_FO_MASKED 3
303 303
304enum qla4_work_type {
305 QLA4_EVENT_AEN,
306};
304 307
308struct qla4_work_evt {
309 struct list_head list;
310 enum qla4_work_type type;
311 union {
312 struct {
313 enum iscsi_host_event_code code;
314 uint32_t data_size;
315 uint8_t data[0];
316 } aen;
317 } u;
318};
305 319
306struct ql82xx_hw_data { 320struct ql82xx_hw_data {
307 /* Offsets for flash/nvram access (set to ~0 if not used). */ 321 /* Offsets for flash/nvram access (set to ~0 if not used). */
@@ -672,6 +686,10 @@ struct scsi_qla_host {
672 uint16_t sec_ddb_idx; 686 uint16_t sec_ddb_idx;
673 int is_reset; 687 int is_reset;
674 uint16_t temperature; 688 uint16_t temperature;
689
690 /* event work list */
691 struct list_head work_list;
692 spinlock_t work_lock;
675}; 693};
676 694
677struct ql4_task_data { 695struct ql4_task_data {
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index d0dd4b330206..34cf851978e9 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -181,6 +181,8 @@ int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
181int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, 181int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
182 struct ddb_entry *ddb_entry, uint32_t state); 182 struct ddb_entry *ddb_entry, uint32_t state);
183void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset); 183void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset);
184int qla4xxx_post_aen_work(struct scsi_qla_host *ha, uint32_t aen_code,
185 uint32_t data_size, uint8_t *data);
184 186
185/* BSG Functions */ 187/* BSG Functions */
186int qla4xxx_bsg_request(struct bsg_job *bsg_job); 188int qla4xxx_bsg_request(struct bsg_job *bsg_job);
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 95828862eea0..954fe84be575 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -576,6 +576,9 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
576 set_bit(DPC_LINK_CHANGED, &ha->dpc_flags); 576 set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
577 577
578 ql4_printk(KERN_INFO, ha, "%s: LINK UP\n", __func__); 578 ql4_printk(KERN_INFO, ha, "%s: LINK UP\n", __func__);
579 qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKUP,
580 sizeof(mbox_sts),
581 (uint8_t *) mbox_sts);
579 break; 582 break;
580 583
581 case MBOX_ASTS_LINK_DOWN: 584 case MBOX_ASTS_LINK_DOWN:
@@ -584,6 +587,9 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
584 set_bit(DPC_LINK_CHANGED, &ha->dpc_flags); 587 set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
585 588
586 ql4_printk(KERN_INFO, ha, "%s: LINK DOWN\n", __func__); 589 ql4_printk(KERN_INFO, ha, "%s: LINK DOWN\n", __func__);
590 qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKDOWN,
591 sizeof(mbox_sts),
592 (uint8_t *) mbox_sts);
587 break; 593 break;
588 594
589 case MBOX_ASTS_HEARTBEAT: 595 case MBOX_ASTS_HEARTBEAT:
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 2cd20775836f..d423f7afbbd7 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -2282,6 +2282,10 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
2282 } 2282 }
2283 } 2283 }
2284 2284
2285 /* Process any deferred work. */
2286 if (!list_empty(&ha->work_list))
2287 start_dpc++;
2288
2285 /* Wakeup the dpc routine for this adapter, if needed. */ 2289 /* Wakeup the dpc routine for this adapter, if needed. */
2286 if (start_dpc || 2290 if (start_dpc ||
2287 test_bit(DPC_RESET_HA, &ha->dpc_flags) || 2291 test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
@@ -2847,6 +2851,81 @@ void qla4xxx_wake_dpc(struct scsi_qla_host *ha)
2847 queue_work(ha->dpc_thread, &ha->dpc_work); 2851 queue_work(ha->dpc_thread, &ha->dpc_work);
2848} 2852}
2849 2853
2854static struct qla4_work_evt *
2855qla4xxx_alloc_work(struct scsi_qla_host *ha, uint32_t data_size,
2856 enum qla4_work_type type)
2857{
2858 struct qla4_work_evt *e;
2859 uint32_t size = sizeof(struct qla4_work_evt) + data_size;
2860
2861 e = kzalloc(size, GFP_ATOMIC);
2862 if (!e)
2863 return NULL;
2864
2865 INIT_LIST_HEAD(&e->list);
2866 e->type = type;
2867 return e;
2868}
2869
2870static void qla4xxx_post_work(struct scsi_qla_host *ha,
2871 struct qla4_work_evt *e)
2872{
2873 unsigned long flags;
2874
2875 spin_lock_irqsave(&ha->work_lock, flags);
2876 list_add_tail(&e->list, &ha->work_list);
2877 spin_unlock_irqrestore(&ha->work_lock, flags);
2878 qla4xxx_wake_dpc(ha);
2879}
2880
2881int qla4xxx_post_aen_work(struct scsi_qla_host *ha,
2882 enum iscsi_host_event_code aen_code,
2883 uint32_t data_size, uint8_t *data)
2884{
2885 struct qla4_work_evt *e;
2886
2887 e = qla4xxx_alloc_work(ha, data_size, QLA4_EVENT_AEN);
2888 if (!e)
2889 return QLA_ERROR;
2890
2891 e->u.aen.code = aen_code;
2892 e->u.aen.data_size = data_size;
2893 memcpy(e->u.aen.data, data, data_size);
2894
2895 qla4xxx_post_work(ha, e);
2896
2897 return QLA_SUCCESS;
2898}
2899
2900void qla4xxx_do_work(struct scsi_qla_host *ha)
2901{
2902 struct qla4_work_evt *e, *tmp;
2903 unsigned long flags;
2904 LIST_HEAD(work);
2905
2906 spin_lock_irqsave(&ha->work_lock, flags);
2907 list_splice_init(&ha->work_list, &work);
2908 spin_unlock_irqrestore(&ha->work_lock, flags);
2909
2910 list_for_each_entry_safe(e, tmp, &work, list) {
2911 list_del_init(&e->list);
2912
2913 switch (e->type) {
2914 case QLA4_EVENT_AEN:
2915 iscsi_post_host_event(ha->host_no,
2916 &qla4xxx_iscsi_transport,
2917 e->u.aen.code,
2918 e->u.aen.data_size,
2919 e->u.aen.data);
2920 break;
2921 default:
2922 ql4_printk(KERN_WARNING, ha, "event type: 0x%x not "
2923 "supported", e->type);
2924 }
2925 kfree(e);
2926 }
2927}
2928
2850/** 2929/**
2851 * qla4xxx_do_dpc - dpc routine 2930 * qla4xxx_do_dpc - dpc routine
2852 * @data: in our case pointer to adapter structure 2931 * @data: in our case pointer to adapter structure
@@ -2878,6 +2957,9 @@ static void qla4xxx_do_dpc(struct work_struct *work)
2878 return; 2957 return;
2879 } 2958 }
2880 2959
2960 /* post events to application */
2961 qla4xxx_do_work(ha);
2962
2881 if (is_qla8022(ha)) { 2963 if (is_qla8022(ha)) {
2882 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { 2964 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
2883 qla4_8xxx_idc_lock(ha); 2965 qla4_8xxx_idc_lock(ha);
@@ -4450,6 +4532,9 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
4450 4532
4451 spin_lock_init(&ha->hardware_lock); 4533 spin_lock_init(&ha->hardware_lock);
4452 4534
4535 /* Initialize work list */
4536 INIT_LIST_HEAD(&ha->work_list);
4537
4453 /* Allocate dma buffers */ 4538 /* Allocate dma buffers */
4454 if (qla4xxx_mem_alloc(ha)) { 4539 if (qla4xxx_mem_alloc(ha)) {
4455 ql4_printk(KERN_WARNING, ha, 4540 ql4_printk(KERN_WARNING, ha,