summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorKevin Barnett <kevin.barnett@hpe.com>2017-05-04 02:52:52 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2017-06-13 03:48:02 +0300
commit6a50d6ada03d8d9102a632d0e2db70cd9b6620f5 (patch)
treeed58dc09192913a6aa144e9a3a72ab9674dbdbdd /drivers/scsi
parent162d7753fce9a00719c09dfebd9fee3855e27fbe (diff)
downloadlinux-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.h11
-rw-r--r--drivers/scsi/smartpqi/smartpqi_init.c110
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;
}