From: Kevin Barnett
add support for ACPI S3 (suspend) and S4 (hibernate) system power states.
Reviewed-by: Scott Benesh
Signed-off-by: Kevin Barnett
Signed-off-by: Don Brace
---
drivers/scsi/smartpqi/smartpqi.h | 12 +
drivers/scsi/smartpqi/smartpqi_init.c | 424 +++--
drivers/scsi/smartpqi/smartpqi_sis.c | 75 ++
drivers/scsi/smartpqi/smartpqi_sis.h |3
4 files changed, 485 insertions(+), 29 deletions(-)
diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 5b0c6fb..06e2b71 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -61,7 +61,7 @@ struct pqi_device_registers {
/*
* controller registers
*
- * These are defined by the PMC implementation.
+ * These are defined by the Microsemi implementation.
*
* Some registers (those named sis_*) are only used when in
* legacy SIS mode before we transition the controller into
@@ -102,6 +102,12 @@ enum pqi_io_path {
AIO_PATH = 1
};
+enum pqi_irq_mode {
+ IRQ_MODE_NONE,
+ IRQ_MODE_INTX,
+ IRQ_MODE_MSIX
+};
+
struct pqi_sg_descriptor {
__le64 address;
__le32 length;
@@ -908,7 +914,7 @@ struct pqi_ctrl_info {
dma_addr_t error_buffer_dma_handle;
size_t sg_chain_buffer_length;
unsigned intnum_queue_groups;
- unsigned intnum_active_queue_groups;
+ u16 max_hw_queue_index;
u16 num_elements_per_iq;
u16 num_elements_per_oq;
u16 max_inbound_iu_length_per_firmware;
@@ -923,6 +929,7 @@ struct pqi_ctrl_info {
struct pqi_admin_queues admin_queues;
struct pqi_queue_group queue_groups[PQI_MAX_QUEUE_GROUPS];
struct pqi_event_queue event_queue;
+ enum pqi_irq_mode irq_mode;
int max_msix_vectors;
int num_msix_vectors_enabled;
int num_msix_vectors_initialized;
@@ -937,6 +944,7 @@ struct pqi_ctrl_info {
u8 outbound_spanning_supported : 1;
u8 pqi_mode_enabled : 1;
u8 heartbeat_timer_started : 1;
+ u8 update_time_worker_scheduled : 1;
struct list_head scsi_device_list;
spinlock_t scsi_device_list_lock;
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c
b/drivers/scsi/smartpqi/smartpqi_init.c
index 96bf318..ca9d010 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -262,6 +262,11 @@ static inline void pqi_schedule_rescan_worker(struct
pqi_ctrl_info *ctrl_info)
PQI_RESCAN_WORK_INTERVAL);
}
+static inline void pqi_cancel_rescan_worker(struct pqi_ctrl_info *ctrl_info)
+{
+ cancel_delayed_work_sync(_info->rescan_work);
+}
+
static int pqi_map_single(struct pci_dev *pci_dev,
struct pqi_sg_descriptor *sg_descriptor, void *buffer,
size_t buffer_length, int data_direction)
@@ -588,7 +593,7 @@ static int pqi_write_driver_version_to_host_wellness(
buffer->driver_version_tag[1] = 'V';
put_unaligned_le16(sizeof(buffer->driver_version),
>driver_version_length);
- strncpy(buffer->driver_version, DRIVER_VERSION,
+ strncpy(buffer->driver_version, "Linux " DRIVER_VERSION,
sizeof(buffer->driver_version) - 1);
buffer->driver_version[sizeof(buffer->driver_version) - 1] = '\0';
buffer->end_tag[0] = 'Z';
@@ -686,7 +691,21 @@ static void pqi_update_time_worker(struct work_struct
*work)
static inline void pqi_schedule_update_time_worker(
struct pqi_ctrl_info *ctrl_info)
{
+ if (ctrl_info->update_time_worker_scheduled)
+ return;
+
schedule_delayed_work(_info->update_time_work, 0);
+ ctrl_info->update_time_worker_scheduled = true;
+}
+
+static inline void pqi_cancel_update_time_worker(
+ struct pqi_ctrl_info *ctrl_info)
+{
+ if (!ctrl_info->update_time_worker_scheduled)
+ return;
+
+ cancel_delayed_work_sync(_info->update_time_work);
+ ctrl_info->update_time_worker_scheduled = false;
}
static int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd,
@@ -1967,6 +1986,18 @@ static int pqi_scan_finished(struct Scsi_Host *shost,
return !mutex_is_locked(_info->scan_mutex);
}
+static void pqi_wait_until_scan_finished(struct pqi_ctrl_info *ctrl_info)
+{
+ mutex_lock(_info->scan_mutex);
+ mutex_unlock(_info->scan_mutex);
+}
+
+static void pqi_wait_until_lun_reset_finished(struct pqi_ctrl_info *ctrl_info)
+{
+ mutex_lock(_info->lun_reset_mutex);
+ mutex_unlock(_info->lun_reset_mutex);
+}
+
static inline void pqi_set_encryption_info(
struct pqi_encryption_info *encryption_info, struct raid_map *raid_map,
u64