diff options
author | Kevin Barnett <kevin.barnett@hpe.com> | 2017-05-04 02:52:52 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-06-13 03:48:02 +0300 |
commit | 6a50d6ada03d8d9102a632d0e2db70cd9b6620f5 (patch) | |
tree | ed58dc09192913a6aa144e9a3a72ab9674dbdbdd /drivers/scsi | |
parent | 162d7753fce9a00719c09dfebd9fee3855e27fbe (diff) | |
download | linux-6a50d6ada03d8d9102a632d0e2db70cd9b6620f5.tar.xz |
scsi: smartpqi: add supporting events
Only register for controller events that driver supports
cleanup event handling.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/smartpqi/smartpqi.h | 11 | ||||
-rw-r--r-- | drivers/scsi/smartpqi/smartpqi_init.c | 110 |
2 files changed, 61 insertions, 60 deletions
diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 62045c1990c7..02b31965bf6e 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -860,15 +860,8 @@ struct pqi_io_request { struct list_head request_list_entry; }; -/* for indexing into the pending_events[] field of struct pqi_ctrl_info */ #define PQI_EVENT_HEARTBEAT 0 -#define PQI_EVENT_HOTPLUG 1 -#define PQI_EVENT_HARDWARE 2 -#define PQI_EVENT_PHYSICAL_DEVICE 3 -#define PQI_EVENT_LOGICAL_DEVICE 4 -#define PQI_EVENT_AIO_STATE_CHANGE 5 -#define PQI_EVENT_AIO_CONFIG_CHANGE 6 -#define PQI_NUM_SUPPORTED_EVENTS 7 +#define PQI_NUM_SUPPORTED_EVENTS 6 struct pqi_event { bool pending; @@ -951,7 +944,7 @@ struct pqi_ctrl_info { struct pqi_io_request *io_request_pool; u16 next_io_request_slot; - struct pqi_event pending_events[PQI_NUM_SUPPORTED_EVENTS]; + struct pqi_event events[PQI_NUM_SUPPORTED_EVENTS]; struct work_struct event_work; atomic_t num_interrupts; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 5a5b9abe501f..279dd41796c0 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -81,6 +81,15 @@ static struct scsi_transport_template *pqi_sas_transport_template; static atomic_t pqi_controller_count = ATOMIC_INIT(0); +static unsigned int pqi_supported_event_types[] = { + PQI_EVENT_TYPE_HOTPLUG, + PQI_EVENT_TYPE_HARDWARE, + PQI_EVENT_TYPE_PHYSICAL_DEVICE, + PQI_EVENT_TYPE_LOGICAL_DEVICE, + PQI_EVENT_TYPE_AIO_STATE_CHANGE, + PQI_EVENT_TYPE_AIO_CONFIG_CHANGE, +}; + static int pqi_disable_device_id_wildcards; module_param_named(disable_device_id_wildcards, pqi_disable_device_id_wildcards, int, S_IRUGO | S_IWUSR); @@ -2665,20 +2674,20 @@ static void pqi_event_worker(struct work_struct *work) { unsigned int i; struct pqi_ctrl_info *ctrl_info; - struct pqi_event *pending_event; + struct pqi_event *event; bool got_non_heartbeat_event = false; ctrl_info = container_of(work, struct pqi_ctrl_info, event_work); - pending_event = ctrl_info->pending_events; + event = ctrl_info->events; for (i = 0; i < PQI_NUM_SUPPORTED_EVENTS; i++) { - if (pending_event->pending) { - pending_event->pending = false; - pqi_acknowledge_event(ctrl_info, pending_event); - if (i != PQI_EVENT_HEARTBEAT) + if (event->pending) { + event->pending = false; + pqi_acknowledge_event(ctrl_info, event); + if (i != PQI_EVENT_TYPE_HEARTBEAT) got_non_heartbeat_event = true; } - pending_event++; + event++; } if (got_non_heartbeat_event) @@ -2742,7 +2751,7 @@ static void pqi_heartbeat_timer_handler(unsigned long data) pqi_take_ctrl_offline(ctrl_info); return; } - ctrl_info->pending_events[PQI_EVENT_HEARTBEAT].pending = true; + ctrl_info->events[PQI_EVENT_HEARTBEAT].pending = true; schedule_work(&ctrl_info->event_work); } else { ctrl_info->num_heartbeats_requested = 0; @@ -2773,38 +2782,20 @@ static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info) del_timer_sync(&ctrl_info->heartbeat_timer); } -static int pqi_event_type_to_event_index(unsigned int event_type) +static inline int pqi_event_type_to_event_index(unsigned int event_type) { int index; - switch (event_type) { - case PQI_EVENT_TYPE_HEARTBEAT: - index = PQI_EVENT_HEARTBEAT; - break; - case PQI_EVENT_TYPE_HOTPLUG: - index = PQI_EVENT_HOTPLUG; - break; - case PQI_EVENT_TYPE_HARDWARE: - index = PQI_EVENT_HARDWARE; - break; - case PQI_EVENT_TYPE_PHYSICAL_DEVICE: - index = PQI_EVENT_PHYSICAL_DEVICE; - break; - case PQI_EVENT_TYPE_LOGICAL_DEVICE: - index = PQI_EVENT_LOGICAL_DEVICE; - break; - case PQI_EVENT_TYPE_AIO_STATE_CHANGE: - index = PQI_EVENT_AIO_STATE_CHANGE; - break; - case PQI_EVENT_TYPE_AIO_CONFIG_CHANGE: - index = PQI_EVENT_AIO_CONFIG_CHANGE; - break; - default: - index = -1; - break; - } + for (index = 0; index < ARRAY_SIZE(pqi_supported_event_types); index++) + if (event_type == pqi_supported_event_types[index]) + return index; - return index; + return -1; +} + +static inline bool pqi_is_supported_event(unsigned int event_type) +{ + return pqi_event_type_to_event_index(event_type) != -1; } static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) @@ -2814,7 +2805,7 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) pqi_index_t oq_ci; struct pqi_event_queue *event_queue; struct pqi_event_response *response; - struct pqi_event *pending_event; + struct pqi_event *event; bool need_delayed_work; int event_index; @@ -2837,15 +2828,14 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) if (event_index >= 0) { if (response->request_acknowlege) { - pending_event = - &ctrl_info->pending_events[event_index]; - pending_event->event_type = - response->event_type; - pending_event->event_id = response->event_id; - pending_event->additional_event_id = + event = &ctrl_info->events[event_index]; + event->pending = true; + event->event_type = response->event_type; + event->event_id = response->event_id; + event->additional_event_id = response->additional_event_id; - if (event_index != PQI_EVENT_HEARTBEAT) { - pending_event->pending = true; + if (event_index != PQI_EVENT_TYPE_HEARTBEAT) { + event->pending = true; need_delayed_work = true; } } @@ -3899,11 +3889,13 @@ static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info) (offsetof(struct pqi_event_config, descriptors) + \ (PQI_MAX_EVENT_DESCRIPTORS * sizeof(struct pqi_event_descriptor))) -static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info) +static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info, + bool enable_events) { int rc; unsigned int i; struct pqi_event_config *event_config; + struct pqi_event_descriptor *event_descriptor; struct pqi_general_management_request request; event_config = kmalloc(PQI_REPORT_EVENT_CONFIG_BUFFER_LENGTH, @@ -3937,9 +3929,15 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info) if (rc) goto out; - for (i = 0; i < event_config->num_event_descriptors; i++) - put_unaligned_le16(ctrl_info->event_queue.oq_id, - &event_config->descriptors[i].oq_id); + for (i = 0; i < event_config->num_event_descriptors; i++) { + event_descriptor = &event_config->descriptors[i]; + if (enable_events && + pqi_is_supported_event(event_descriptor->event_type)) + put_unaligned_le16(ctrl_info->event_queue.oq_id, + &event_descriptor->oq_id); + else + put_unaligned_le16(0, &event_descriptor->oq_id); + } memset(&request, 0, sizeof(request)); @@ -3970,6 +3968,16 @@ out: return rc; } +static inline int pqi_enable_events(struct pqi_ctrl_info *ctrl_info) +{ + return pqi_configure_events(ctrl_info, true); +} + +static inline int pqi_disable_events(struct pqi_ctrl_info *ctrl_info) +{ + return pqi_configure_events(ctrl_info, false); +} + static void pqi_free_all_io_requests(struct pqi_ctrl_info *ctrl_info) { unsigned int i; @@ -5413,10 +5421,10 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) sis_enable_msix(ctrl_info); - rc = pqi_configure_events(ctrl_info); + rc = pqi_enable_events(ctrl_info); if (rc) { dev_err(&ctrl_info->pci_dev->dev, - "error configuring events\n"); + "error enabling events\n"); return rc; } |