Commit 6a50d6ad authored by Kevin Barnett's avatar Kevin Barnett Committed by Martin K. Petersen

scsi: smartpqi: add supporting events

Only register for controller events that driver supports
cleanup event handling.
Reviewed-by: default avatarScott Benesh <scott.benesh@microsemi.com>
Signed-off-by: default avatarKevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: default avatarDon Brace <don.brace@microsemi.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 162d7753
...@@ -860,15 +860,8 @@ struct pqi_io_request { ...@@ -860,15 +860,8 @@ struct pqi_io_request {
struct list_head request_list_entry; 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_HEARTBEAT 0
#define PQI_EVENT_HOTPLUG 1 #define PQI_NUM_SUPPORTED_EVENTS 6
#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
struct pqi_event { struct pqi_event {
bool pending; bool pending;
...@@ -951,7 +944,7 @@ struct pqi_ctrl_info { ...@@ -951,7 +944,7 @@ struct pqi_ctrl_info {
struct pqi_io_request *io_request_pool; struct pqi_io_request *io_request_pool;
u16 next_io_request_slot; 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; struct work_struct event_work;
atomic_t num_interrupts; atomic_t num_interrupts;
......
...@@ -81,6 +81,15 @@ static struct scsi_transport_template *pqi_sas_transport_template; ...@@ -81,6 +81,15 @@ static struct scsi_transport_template *pqi_sas_transport_template;
static atomic_t pqi_controller_count = ATOMIC_INIT(0); 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; static int pqi_disable_device_id_wildcards;
module_param_named(disable_device_id_wildcards, module_param_named(disable_device_id_wildcards,
pqi_disable_device_id_wildcards, int, S_IRUGO | S_IWUSR); pqi_disable_device_id_wildcards, int, S_IRUGO | S_IWUSR);
...@@ -2665,20 +2674,20 @@ static void pqi_event_worker(struct work_struct *work) ...@@ -2665,20 +2674,20 @@ static void pqi_event_worker(struct work_struct *work)
{ {
unsigned int i; unsigned int i;
struct pqi_ctrl_info *ctrl_info; struct pqi_ctrl_info *ctrl_info;
struct pqi_event *pending_event; struct pqi_event *event;
bool got_non_heartbeat_event = false; bool got_non_heartbeat_event = false;
ctrl_info = container_of(work, struct pqi_ctrl_info, event_work); 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++) { for (i = 0; i < PQI_NUM_SUPPORTED_EVENTS; i++) {
if (pending_event->pending) { if (event->pending) {
pending_event->pending = false; event->pending = false;
pqi_acknowledge_event(ctrl_info, pending_event); pqi_acknowledge_event(ctrl_info, event);
if (i != PQI_EVENT_HEARTBEAT) if (i != PQI_EVENT_TYPE_HEARTBEAT)
got_non_heartbeat_event = true; got_non_heartbeat_event = true;
} }
pending_event++; event++;
} }
if (got_non_heartbeat_event) if (got_non_heartbeat_event)
...@@ -2742,7 +2751,7 @@ static void pqi_heartbeat_timer_handler(unsigned long data) ...@@ -2742,7 +2751,7 @@ static void pqi_heartbeat_timer_handler(unsigned long data)
pqi_take_ctrl_offline(ctrl_info); pqi_take_ctrl_offline(ctrl_info);
return; return;
} }
ctrl_info->pending_events[PQI_EVENT_HEARTBEAT].pending = true; ctrl_info->events[PQI_EVENT_HEARTBEAT].pending = true;
schedule_work(&ctrl_info->event_work); schedule_work(&ctrl_info->event_work);
} else { } else {
ctrl_info->num_heartbeats_requested = 0; ctrl_info->num_heartbeats_requested = 0;
...@@ -2773,38 +2782,20 @@ static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info) ...@@ -2773,38 +2782,20 @@ static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info)
del_timer_sync(&ctrl_info->heartbeat_timer); 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; int index;
switch (event_type) { for (index = 0; index < ARRAY_SIZE(pqi_supported_event_types); index++)
case PQI_EVENT_TYPE_HEARTBEAT: if (event_type == pqi_supported_event_types[index])
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;
}
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) 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) ...@@ -2814,7 +2805,7 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
pqi_index_t oq_ci; pqi_index_t oq_ci;
struct pqi_event_queue *event_queue; struct pqi_event_queue *event_queue;
struct pqi_event_response *response; struct pqi_event_response *response;
struct pqi_event *pending_event; struct pqi_event *event;
bool need_delayed_work; bool need_delayed_work;
int event_index; int event_index;
...@@ -2837,15 +2828,14 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) ...@@ -2837,15 +2828,14 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
if (event_index >= 0) { if (event_index >= 0) {
if (response->request_acknowlege) { if (response->request_acknowlege) {
pending_event = event = &ctrl_info->events[event_index];
&ctrl_info->pending_events[event_index]; event->pending = true;
pending_event->event_type = event->event_type = response->event_type;
response->event_type; event->event_id = response->event_id;
pending_event->event_id = response->event_id; event->additional_event_id =
pending_event->additional_event_id =
response->additional_event_id; response->additional_event_id;
if (event_index != PQI_EVENT_HEARTBEAT) { if (event_index != PQI_EVENT_TYPE_HEARTBEAT) {
pending_event->pending = true; event->pending = true;
need_delayed_work = true; need_delayed_work = true;
} }
} }
...@@ -3899,11 +3889,13 @@ static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info) ...@@ -3899,11 +3889,13 @@ static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info)
(offsetof(struct pqi_event_config, descriptors) + \ (offsetof(struct pqi_event_config, descriptors) + \
(PQI_MAX_EVENT_DESCRIPTORS * sizeof(struct pqi_event_descriptor))) (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; int rc;
unsigned int i; unsigned int i;
struct pqi_event_config *event_config; struct pqi_event_config *event_config;
struct pqi_event_descriptor *event_descriptor;
struct pqi_general_management_request request; struct pqi_general_management_request request;
event_config = kmalloc(PQI_REPORT_EVENT_CONFIG_BUFFER_LENGTH, event_config = kmalloc(PQI_REPORT_EVENT_CONFIG_BUFFER_LENGTH,
...@@ -3937,9 +3929,15 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info) ...@@ -3937,9 +3929,15 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info)
if (rc) if (rc)
goto out; goto out;
for (i = 0; i < event_config->num_event_descriptors; i++) 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, put_unaligned_le16(ctrl_info->event_queue.oq_id,
&event_config->descriptors[i].oq_id); &event_descriptor->oq_id);
else
put_unaligned_le16(0, &event_descriptor->oq_id);
}
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
...@@ -3970,6 +3968,16 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info) ...@@ -3970,6 +3968,16 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info)
return rc; 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) static void pqi_free_all_io_requests(struct pqi_ctrl_info *ctrl_info)
{ {
unsigned int i; unsigned int i;
...@@ -5413,10 +5421,10 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) ...@@ -5413,10 +5421,10 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
sis_enable_msix(ctrl_info); sis_enable_msix(ctrl_info);
rc = pqi_configure_events(ctrl_info); rc = pqi_enable_events(ctrl_info);
if (rc) { if (rc) {
dev_err(&ctrl_info->pci_dev->dev, dev_err(&ctrl_info->pci_dev->dev,
"error configuring events\n"); "error enabling events\n");
return rc; return rc;
} }
......
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