summaryrefslogtreecommitdiff
path: root/drivers/scsi/smartpqi/smartpqi_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/smartpqi/smartpqi_init.c')
-rw-r--r--drivers/scsi/smartpqi/smartpqi_init.c559
1 files changed, 418 insertions, 141 deletions
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index f0897d587454..7c0d069a3158 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -33,11 +33,11 @@
#define BUILD_TIMESTAMP
#endif
-#define DRIVER_VERSION "2.1.12-055"
+#define DRIVER_VERSION "2.1.14-035"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 1
-#define DRIVER_RELEASE 12
-#define DRIVER_REVISION 55
+#define DRIVER_RELEASE 14
+#define DRIVER_REVISION 35
#define DRIVER_NAME "Microchip SmartPQI Driver (v" \
DRIVER_VERSION BUILD_TIMESTAMP ")"
@@ -54,6 +54,16 @@ MODULE_DESCRIPTION("Driver for Microchip Smart Family Controller version "
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
+struct pqi_cmd_priv {
+ int this_residual;
+};
+
+static struct pqi_cmd_priv *pqi_cmd_priv(struct scsi_cmnd *cmd)
+{
+ return scsi_cmd_priv(cmd);
+}
+
+static void pqi_verify_structures(void);
static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info,
enum pqi_ctrl_shutdown_reason ctrl_shutdown_reason);
static void pqi_ctrl_offline_worker(struct work_struct *work);
@@ -68,7 +78,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info,
static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb,
unsigned int cdb_length, struct pqi_queue_group *queue_group,
- struct pqi_encryption_info *encryption_info, bool raid_bypass);
+ struct pqi_encryption_info *encryption_info, bool raid_bypass, bool io_high_prio);
static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info,
struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device,
@@ -376,7 +386,7 @@ static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info)
displayed_warning = false;
start_jiffies = jiffies;
- warning_timeout = (PQI_QUIESCE_WARNING_TIMEOUT_SECS * PQI_HZ) + start_jiffies;
+ warning_timeout = (PQI_QUIESCE_WARNING_TIMEOUT_SECS * HZ) + start_jiffies;
while (atomic_read(&ctrl_info->num_busy_threads) >
atomic_read(&ctrl_info->num_blocked_threads)) {
@@ -385,7 +395,7 @@ static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info)
"waiting %u seconds for driver activity to quiesce\n",
jiffies_to_msecs(jiffies - start_jiffies) / 1000);
displayed_warning = true;
- warning_timeout = (PQI_QUIESCE_WARNING_TIMEOUT_SECS * PQI_HZ) + jiffies;
+ warning_timeout = (PQI_QUIESCE_WARNING_TIMEOUT_SECS * HZ) + jiffies;
}
usleep_range(1000, 2000);
}
@@ -462,7 +472,7 @@ static inline void pqi_schedule_rescan_worker(struct pqi_ctrl_info *ctrl_info)
pqi_schedule_rescan_worker_with_delay(ctrl_info, 0);
}
-#define PQI_RESCAN_WORK_DELAY (10 * PQI_HZ)
+#define PQI_RESCAN_WORK_DELAY (10 * HZ)
static inline void pqi_schedule_rescan_worker_delayed(struct pqi_ctrl_info *ctrl_info)
{
@@ -1038,7 +1048,7 @@ static int pqi_write_current_time_to_host_wellness(
return rc;
}
-#define PQI_UPDATE_TIME_WORK_INTERVAL (24UL * 60 * 60 * PQI_HZ)
+#define PQI_UPDATE_TIME_WORK_INTERVAL (24UL * 60 * 60 * HZ)
static void pqi_update_time_worker(struct work_struct *work)
{
@@ -1181,8 +1191,8 @@ static inline int pqi_report_phys_luns(struct pqi_ctrl_info *ctrl_info, void **b
for (i = 0; i < num_physicals; i++) {
memcpy(&rpl_16byte_wwid_list->lun_entries[i].lunid, &rpl_8byte_wwid_list->lun_entries[i].lunid, sizeof(rpl_8byte_wwid_list->lun_entries[i].lunid));
- memset(&rpl_16byte_wwid_list->lun_entries[i].wwid, 0, 8);
- memcpy(&rpl_16byte_wwid_list->lun_entries[i].wwid[8], &rpl_8byte_wwid_list->lun_entries[i].wwid, sizeof(rpl_8byte_wwid_list->lun_entries[i].wwid));
+ memcpy(&rpl_16byte_wwid_list->lun_entries[i].wwid[0], &rpl_8byte_wwid_list->lun_entries[i].wwid, sizeof(rpl_8byte_wwid_list->lun_entries[i].wwid));
+ memset(&rpl_16byte_wwid_list->lun_entries[i].wwid[8], 0, 8);
rpl_16byte_wwid_list->lun_entries[i].device_type = rpl_8byte_wwid_list->lun_entries[i].device_type;
rpl_16byte_wwid_list->lun_entries[i].device_flags = rpl_8byte_wwid_list->lun_entries[i].device_flags;
rpl_16byte_wwid_list->lun_entries[i].lun_count = rpl_8byte_wwid_list->lun_entries[i].lun_count;
@@ -1549,6 +1559,7 @@ no_buffer:
device->volume_offline = volume_offline;
}
+#define PQI_DEVICE_NCQ_PRIO_SUPPORTED 0x01
#define PQI_DEVICE_PHY_MAP_SUPPORTED 0x10
static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info,
@@ -1587,9 +1598,6 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info,
sizeof(device->phys_connector));
device->bay = id_phys->phys_bay_in_box;
- memcpy(&device->page_83_identifier, &id_phys->page_83_identifier,
- sizeof(device->page_83_identifier));
-
if ((id_phys->even_more_flags & PQI_DEVICE_PHY_MAP_SUPPORTED) &&
id_phys->phy_count)
device->phy_id =
@@ -1597,6 +1605,10 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info,
else
device->phy_id = 0xFF;
+ device->ncq_prio_support =
+ ((get_unaligned_le32(&id_phys->misc_drive_flags) >> 16) &
+ PQI_DEVICE_NCQ_PRIO_SUPPORTED);
+
return 0;
}
@@ -2010,8 +2022,8 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info,
/* Assumes the SCSI device list lock is held. */
-static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
- struct pqi_scsi_dev *new_device)
+static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *existing_device, struct pqi_scsi_dev *new_device)
{
existing_device->device_type = new_device->device_type;
existing_device->bus = new_device->bus;
@@ -2021,9 +2033,8 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
existing_device->target_lun_valid = true;
}
- if ((existing_device->volume_status == CISS_LV_QUEUED_FOR_EXPANSION ||
- existing_device->volume_status == CISS_LV_UNDERGOING_EXPANSION) &&
- new_device->volume_status == CISS_LV_OK)
+ if (pqi_is_logical_device(existing_device) &&
+ ctrl_info->logical_volume_rescan_needed)
existing_device->rescan = true;
/* By definition, the scsi3addr and wwid fields are already the same. */
@@ -2054,7 +2065,7 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
sizeof(existing_device->box));
memcpy(existing_device->phys_connector, new_device->phys_connector,
sizeof(existing_device->phys_connector));
- existing_device->next_bypass_group = 0;
+ memset(existing_device->next_bypass_group, 0, sizeof(existing_device->next_bypass_group));
kfree(existing_device->raid_map);
existing_device->raid_map = new_device->raid_map;
existing_device->raid_bypass_configured =
@@ -2141,7 +2152,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
*/
device->new_device = false;
matching_device->device_gone = false;
- pqi_scsi_update_device(matching_device, device);
+ pqi_scsi_update_device(ctrl_info, matching_device, device);
break;
case DEVICE_NOT_FOUND:
/*
@@ -2213,8 +2224,8 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
}
/*
- * Notify the SCSI ML if the queue depth of any existing device has
- * changed.
+ * Notify the SML of any existing device changes such as;
+ * queue depth, device size.
*/
list_for_each_entry(device, &ctrl_info->scsi_device_list, scsi_device_list_entry) {
if (device->sdev && device->queue_depth != device->advertised_queue_depth) {
@@ -2243,6 +2254,9 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
}
}
}
+
+ ctrl_info->logical_volume_rescan_needed = false;
+
}
static inline bool pqi_is_supported_device(struct pqi_scsi_dev *device)
@@ -2274,16 +2288,12 @@ static inline void pqi_mask_device(u8 *scsi3addr)
scsi3addr[3] |= 0xc0;
}
-static inline bool pqi_is_device_with_sas_address(struct pqi_scsi_dev *device)
+static inline bool pqi_is_multipath_device(struct pqi_scsi_dev *device)
{
- switch (device->device_type) {
- case SA_DEVICE_TYPE_SAS:
- case SA_DEVICE_TYPE_EXPANDER_SMP:
- case SA_DEVICE_TYPE_SES:
- return true;
- }
+ if (pqi_is_logical_device(device))
+ return false;
- return false;
+ return (device->path_map & (device->path_map - 1)) != 0;
}
static inline bool pqi_expose_device(struct pqi_scsi_dev *device)
@@ -2291,17 +2301,6 @@ static inline bool pqi_expose_device(struct pqi_scsi_dev *device)
return !device->is_physical_device || !pqi_skip_device(device->scsi3addr);
}
-static inline void pqi_set_physical_device_wwid(struct pqi_ctrl_info *ctrl_info,
- struct pqi_scsi_dev *device, struct report_phys_lun_16byte_wwid *phys_lun)
-{
- if (ctrl_info->unique_wwid_in_report_phys_lun_supported ||
- ctrl_info->rpl_extended_format_4_5_supported ||
- pqi_is_device_with_sas_address(device))
- memcpy(device->wwid, phys_lun->wwid, sizeof(device->wwid));
- else
- memcpy(&device->wwid[8], device->page_83_identifier, 8);
-}
-
static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
{
int i;
@@ -2469,7 +2468,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
pqi_assign_bus_target_lun(device);
if (device->is_physical_device) {
- pqi_set_physical_device_wwid(ctrl_info, device, phys_lun);
+ memcpy(device->wwid, phys_lun->wwid, sizeof(device->wwid));
if ((phys_lun->device_flags &
CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED) &&
phys_lun->aio_handle) {
@@ -2482,8 +2481,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
sizeof(device->volume_id));
}
- if (pqi_is_device_with_sas_address(device))
- device->sas_address = get_unaligned_be64(&device->wwid[8]);
+ device->sas_address = get_unaligned_be64(&device->wwid[0]);
new_device_list[num_valid_devices++] = device;
}
@@ -2513,17 +2511,15 @@ static void pqi_remove_all_scsi_devices(struct pqi_ctrl_info *ctrl_info)
struct pqi_scsi_dev *device;
struct pqi_scsi_dev *next;
- spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
-
list_for_each_entry_safe(device, next, &ctrl_info->scsi_device_list,
scsi_device_list_entry) {
if (pqi_is_device_added(device))
pqi_remove_device(ctrl_info, device);
+ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
list_del(&device->scsi_device_list_entry);
pqi_free_device(device);
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
}
-
- spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
}
static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info)
@@ -2950,11 +2946,11 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
if (rmd.is_write) {
pqi_calc_aio_r1_nexus(raid_map, &rmd);
} else {
- group = device->next_bypass_group;
+ group = device->next_bypass_group[rmd.map_index];
next_bypass_group = group + 1;
if (next_bypass_group >= rmd.layout_map_count)
next_bypass_group = 0;
- device->next_bypass_group = next_bypass_group;
+ device->next_bypass_group[rmd.map_index] = next_bypass_group;
rmd.map_index += group * rmd.data_disks_per_row;
}
} else if ((device->raid_level == SA_RAID_5 ||
@@ -3009,7 +3005,7 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle,
rmd.cdb, rmd.cdb_length, queue_group,
- encryption_info_ptr, true);
+ encryption_info_ptr, true, false);
}
#define PQI_STATUS_IDLE 0x0
@@ -3034,7 +3030,7 @@ static int pqi_wait_for_pqi_mode_ready(struct pqi_ctrl_info *ctrl_info)
u8 status;
pqi_registers = ctrl_info->pqi_registers;
- timeout = (PQI_MODE_READY_TIMEOUT_SECS * PQI_HZ) + jiffies;
+ timeout = (PQI_MODE_READY_TIMEOUT_SECS * HZ) + jiffies;
while (1) {
signature = readq(&pqi_registers->signature);
@@ -3213,12 +3209,14 @@ static void pqi_process_aio_io_error(struct pqi_io_request *io_request)
int residual_count;
int xfer_count;
bool device_offline;
+ struct pqi_scsi_dev *device;
scmd = io_request->scmd;
error_info = io_request->error_info;
host_byte = DID_OK;
sense_data_length = 0;
device_offline = false;
+ device = scmd->device->hostdata;
switch (error_info->service_response) {
case PQI_AIO_SERV_RESPONSE_COMPLETE:
@@ -3243,8 +3241,14 @@ static void pqi_process_aio_io_error(struct pqi_io_request *io_request)
break;
case PQI_AIO_STATUS_AIO_PATH_DISABLED:
pqi_aio_path_disabled(io_request);
- scsi_status = SAM_STAT_GOOD;
- io_request->status = -EAGAIN;
+ if (pqi_is_multipath_device(device)) {
+ pqi_device_remove_start(device);
+ host_byte = DID_NO_CONNECT;
+ scsi_status = SAM_STAT_CHECK_CONDITION;
+ } else {
+ scsi_status = SAM_STAT_GOOD;
+ io_request->status = -EAGAIN;
+ }
break;
case PQI_AIO_STATUS_NO_PATH_TO_DEVICE:
case PQI_AIO_STATUS_INVALID_DEVICE:
@@ -3520,7 +3524,7 @@ static enum pqi_soft_reset_status pqi_poll_for_soft_reset_status(
u8 status;
unsigned long timeout;
- timeout = (PQI_SOFT_RESET_STATUS_TIMEOUT_SECS * PQI_HZ) + jiffies;
+ timeout = (PQI_SOFT_RESET_STATUS_TIMEOUT_SECS * HZ) + jiffies;
while (1) {
status = pqi_read_soft_reset_status(ctrl_info);
@@ -3684,6 +3688,8 @@ static void pqi_event_worker(struct work_struct *work)
} else {
ack_event = true;
rescan_needed = true;
+ if (event->event_type == PQI_EVENT_TYPE_LOGICAL_DEVICE)
+ ctrl_info->logical_volume_rescan_needed = true;
}
if (ack_event)
pqi_acknowledge_event(ctrl_info, event);
@@ -3698,7 +3704,7 @@ out:
pqi_ctrl_unbusy(ctrl_info);
}
-#define PQI_HEARTBEAT_TIMER_INTERVAL (10 * PQI_HZ)
+#define PQI_HEARTBEAT_TIMER_INTERVAL (10 * HZ)
static void pqi_heartbeat_timer_handler(struct timer_list *t)
{
@@ -4245,7 +4251,7 @@ static int pqi_alloc_admin_queues(struct pqi_ctrl_info *ctrl_info)
return 0;
}
-#define PQI_ADMIN_QUEUE_CREATE_TIMEOUT_JIFFIES PQI_HZ
+#define PQI_ADMIN_QUEUE_CREATE_TIMEOUT_JIFFIES HZ
#define PQI_ADMIN_QUEUE_CREATE_POLL_INTERVAL_MSECS 1
static int pqi_create_admin_queues(struct pqi_ctrl_info *ctrl_info)
@@ -4339,7 +4345,7 @@ static int pqi_poll_for_admin_response(struct pqi_ctrl_info *ctrl_info,
admin_queues = &ctrl_info->admin_queues;
oq_ci = admin_queues->oq_ci_copy;
- timeout = (PQI_ADMIN_REQUEST_TIMEOUT_SECS * PQI_HZ) + jiffies;
+ timeout = (PQI_ADMIN_REQUEST_TIMEOUT_SECS * HZ) + jiffies;
while (1) {
oq_pi = readl(admin_queues->oq_pi);
@@ -4454,7 +4460,7 @@ static int pqi_wait_for_completion_io(struct pqi_ctrl_info *ctrl_info,
while (1) {
if (wait_for_completion_io_timeout(wait,
- PQI_WAIT_FOR_COMPLETION_IO_TIMEOUT_SECS * PQI_HZ)) {
+ PQI_WAIT_FOR_COMPLETION_IO_TIMEOUT_SECS * HZ)) {
rc = 0;
break;
}
@@ -5555,25 +5561,62 @@ static void pqi_aio_io_complete(struct pqi_io_request *io_request,
scsi_dma_unmap(scmd);
if (io_request->status == -EAGAIN || pqi_raid_bypass_retry_needed(io_request)) {
set_host_byte(scmd, DID_IMM_RETRY);
- scmd->SCp.this_residual++;
+ pqi_cmd_priv(scmd)->this_residual++;
}
pqi_free_io_request(io_request);
pqi_scsi_done(scmd);
}
+static inline bool pqi_is_io_high_priority(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device, struct scsi_cmnd *scmd)
+{
+ bool io_high_prio;
+ int priority_class;
+
+ io_high_prio = false;
+
+ if (device->ncq_prio_enable) {
+ priority_class =
+ IOPRIO_PRIO_CLASS(req_get_ioprio(scsi_cmd_to_rq(scmd)));
+ if (priority_class == IOPRIO_CLASS_RT) {
+ /* Set NCQ priority for read/write commands. */
+ switch (scmd->cmnd[0]) {
+ case WRITE_16:
+ case READ_16:
+ case WRITE_12:
+ case READ_12:
+ case WRITE_10:
+ case READ_10:
+ case WRITE_6:
+ case READ_6:
+ io_high_prio = true;
+ break;
+ }
+ }
+ }
+
+ return io_high_prio;
+}
+
static inline int pqi_aio_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
struct pqi_scsi_dev *device, struct scsi_cmnd *scmd,
struct pqi_queue_group *queue_group)
{
+ bool io_high_prio;
+
+ io_high_prio = pqi_is_io_high_priority(ctrl_info, device, scmd);
+
return pqi_aio_submit_io(ctrl_info, scmd, device->aio_handle,
- scmd->cmnd, scmd->cmd_len, queue_group, NULL, false);
+ scmd->cmnd, scmd->cmd_len, queue_group, NULL,
+ false, io_high_prio);
}
static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb,
unsigned int cdb_length, struct pqi_queue_group *queue_group,
- struct pqi_encryption_info *encryption_info, bool raid_bypass)
+ struct pqi_encryption_info *encryption_info, bool raid_bypass,
+ bool io_high_prio)
{
int rc;
struct pqi_io_request *io_request;
@@ -5585,12 +5628,13 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
io_request->raid_bypass = raid_bypass;
request = io_request->iu;
- memset(request, 0, offsetof(struct pqi_raid_path_request, sg_descriptors));
+ memset(request, 0, offsetof(struct pqi_aio_path_request, sg_descriptors));
request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_IO;
put_unaligned_le32(aio_handle, &request->nexus_id);
put_unaligned_le32(scsi_bufflen(scmd), &request->buffer_length);
request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE;
+ request->command_priority = io_high_prio;
put_unaligned_le16(io_request->index, &request->request_id);
request->error_index = request->request_id;
if (cdb_length > sizeof(request->cdb))
@@ -5779,7 +5823,7 @@ static inline bool pqi_is_bypass_eligible_request(struct scsi_cmnd *scmd)
if (blk_rq_is_passthrough(scsi_cmd_to_rq(scmd)))
return false;
- return scmd->SCp.this_residual == 0;
+ return pqi_cmd_priv(scmd)->this_residual == 0;
}
/*
@@ -6008,7 +6052,7 @@ static int pqi_wait_until_inbound_queues_empty(struct pqi_ctrl_info *ctrl_info)
displayed_warning = false;
start_jiffies = jiffies;
- warning_timeout = (PQI_INBOUND_QUEUES_NONEMPTY_WARNING_TIMEOUT_SECS * PQI_HZ) + start_jiffies;
+ warning_timeout = (PQI_INBOUND_QUEUES_NONEMPTY_WARNING_TIMEOUT_SECS * HZ) + start_jiffies;
while (1) {
queued_io_count = pqi_queued_io_count(ctrl_info);
@@ -6023,7 +6067,7 @@ static int pqi_wait_until_inbound_queues_empty(struct pqi_ctrl_info *ctrl_info)
"waiting %u seconds for queued I/O to drain (queued I/O count: %u; non-empty inbound queue count: %u)\n",
jiffies_to_msecs(jiffies - start_jiffies) / 1000, queued_io_count, nonempty_inbound_queue_count);
displayed_warning = true;
- warning_timeout = (PQI_INBOUND_QUEUES_NONEMPTY_WARNING_TIMEOUT_SECS * PQI_HZ) + jiffies;
+ warning_timeout = (PQI_INBOUND_QUEUES_NONEMPTY_WARNING_TIMEOUT_SECS * HZ) + jiffies;
}
usleep_range(1000, 2000);
}
@@ -6091,7 +6135,7 @@ static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
unsigned long msecs_waiting;
start_jiffies = jiffies;
- warning_timeout = (PQI_PENDING_IO_WARNING_TIMEOUT_SECS * PQI_HZ) + start_jiffies;
+ warning_timeout = (PQI_PENDING_IO_WARNING_TIMEOUT_SECS * HZ) + start_jiffies;
while ((cmds_outstanding = atomic_read(&device->scsi_cmds_outstanding)) > 0) {
pqi_check_ctrl_health(ctrl_info);
@@ -6110,7 +6154,7 @@ static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
"scsi %d:%d:%d:%d: waiting %lu seconds for %d outstanding command(s)\n",
ctrl_info->scsi_host->host_no, device->bus, device->target,
device->lun, msecs_waiting / 1000, cmds_outstanding);
- warning_timeout = (PQI_PENDING_IO_WARNING_TIMEOUT_SECS * PQI_HZ) + jiffies;
+ warning_timeout = (PQI_PENDING_IO_WARNING_TIMEOUT_SECS * HZ) + jiffies;
}
usleep_range(1000, 2000);
}
@@ -6139,7 +6183,7 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info,
while (1) {
if (wait_for_completion_io_timeout(wait,
- PQI_LUN_RESET_POLL_COMPLETION_SECS * PQI_HZ)) {
+ PQI_LUN_RESET_POLL_COMPLETION_SECS * HZ)) {
rc = 0;
break;
}
@@ -7026,7 +7070,7 @@ static ssize_t pqi_sas_address_show(struct device *dev,
spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
device = sdev->hostdata;
- if (!device || !pqi_is_device_with_sas_address(device)) {
+ if (!device) {
spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
return -ENODEV;
}
@@ -7123,6 +7167,71 @@ static ssize_t pqi_raid_bypass_cnt_show(struct device *dev,
return scnprintf(buffer, PAGE_SIZE, "0x%x\n", raid_bypass_cnt);
}
+static ssize_t pqi_sas_ncq_prio_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pqi_ctrl_info *ctrl_info;
+ struct scsi_device *sdev;
+ struct pqi_scsi_dev *device;
+ unsigned long flags;
+ int output_len = 0;
+
+ sdev = to_scsi_device(dev);
+ ctrl_info = shost_to_hba(sdev->host);
+
+ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+
+ device = sdev->hostdata;
+ if (!device) {
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+ return -ENODEV;
+ }
+
+ output_len = snprintf(buf, PAGE_SIZE, "%d\n",
+ device->ncq_prio_enable);
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+
+ return output_len;
+}
+
+static ssize_t pqi_sas_ncq_prio_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct pqi_ctrl_info *ctrl_info;
+ struct scsi_device *sdev;
+ struct pqi_scsi_dev *device;
+ unsigned long flags;
+ u8 ncq_prio_enable = 0;
+
+ if (kstrtou8(buf, 0, &ncq_prio_enable))
+ return -EINVAL;
+
+ sdev = to_scsi_device(dev);
+ ctrl_info = shost_to_hba(sdev->host);
+
+ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+
+ device = sdev->hostdata;
+
+ if (!device) {
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+ return -ENODEV;
+ }
+
+ if (!device->ncq_prio_support ||
+ !device->is_physical_device) {
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+ return -EINVAL;
+ }
+
+ device->ncq_prio_enable = ncq_prio_enable;
+
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+
+ return strlen(buf);
+}
+
static DEVICE_ATTR(lunid, 0444, pqi_lunid_show, NULL);
static DEVICE_ATTR(unique_id, 0444, pqi_unique_id_show, NULL);
static DEVICE_ATTR(path_info, 0444, pqi_path_info_show, NULL);
@@ -7130,6 +7239,8 @@ static DEVICE_ATTR(sas_address, 0444, pqi_sas_address_show, NULL);
static DEVICE_ATTR(ssd_smart_path_enabled, 0444, pqi_ssd_smart_path_enabled_show, NULL);
static DEVICE_ATTR(raid_level, 0444, pqi_raid_level_show, NULL);
static DEVICE_ATTR(raid_bypass_cnt, 0444, pqi_raid_bypass_cnt_show, NULL);
+static DEVICE_ATTR(sas_ncq_prio_enable, 0644,
+ pqi_sas_ncq_prio_enable_show, pqi_sas_ncq_prio_enable_store);
static struct attribute *pqi_sdev_attrs[] = {
&dev_attr_lunid.attr,
@@ -7139,6 +7250,7 @@ static struct attribute *pqi_sdev_attrs[] = {
&dev_attr_ssd_smart_path_enabled.attr,
&dev_attr_raid_level.attr,
&dev_attr_raid_bypass_cnt.attr,
+ &dev_attr_sas_ncq_prio_enable.attr,
NULL
};
@@ -7159,6 +7271,7 @@ static struct scsi_host_template pqi_driver_template = {
.map_queues = pqi_map_queues,
.sdev_groups = pqi_sdev_groups,
.shost_groups = pqi_shost_groups,
+ .cmd_size = sizeof(struct pqi_cmd_priv),
};
static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info)
@@ -7514,10 +7627,6 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info,
case PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT:
ctrl_info->tmf_iu_timeout_supported = firmware_feature->enabled;
break;
- case PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN:
- ctrl_info->unique_wwid_in_report_phys_lun_supported =
- firmware_feature->enabled;
- break;
case PQI_FIRMWARE_FEATURE_FW_TRIAGE:
ctrl_info->firmware_triage_supported = firmware_feature->enabled;
pqi_save_fw_triage_setting(ctrl_info, firmware_feature->enabled);
@@ -7616,11 +7725,6 @@ static struct pqi_firmware_feature pqi_firmware_features[] = {
.feature_status = pqi_firmware_feature_status,
},
{
- .feature_name = "Unique WWID in Report Physical LUN",
- .feature_bit = PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN,
- .feature_status = pqi_ctrl_update_feature_flags,
- },
- {
.feature_name = "Firmware Triage",
.feature_bit = PQI_FIRMWARE_FEATURE_FW_TRIAGE,
.feature_status = pqi_ctrl_update_feature_flags,
@@ -7729,7 +7833,6 @@ static void pqi_ctrl_reset_config(struct pqi_ctrl_info *ctrl_info)
ctrl_info->enable_r6_writes = false;
ctrl_info->raid_iu_timeout_supported = false;
ctrl_info->tmf_iu_timeout_supported = false;
- ctrl_info->unique_wwid_in_report_phys_lun_supported = false;
ctrl_info->firmware_triage_supported = false;
ctrl_info->rpl_extended_format_4_5_supported = false;
}
@@ -7857,6 +7960,21 @@ static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info)
return pqi_revert_to_sis_mode(ctrl_info);
}
+static void pqi_perform_lockup_action(void)
+{
+ switch (pqi_lockup_action) {
+ case PANIC:
+ panic("FATAL: Smart Family Controller lockup detected");
+ break;
+ case REBOOT:
+ emergency_restart();
+ break;
+ case NONE:
+ default:
+ break;
+ }
+}
+
static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
{
int rc;
@@ -7869,7 +7987,7 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
return rc;
}
sis_soft_reset(ctrl_info);
- msleep(PQI_POST_RESET_DELAY_SECS * PQI_HZ);
+ ssleep(PQI_POST_RESET_DELAY_SECS);
} else {
rc = pqi_force_sis_mode(ctrl_info);
if (rc)
@@ -7881,8 +7999,15 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
* commands.
*/
rc = sis_wait_for_ctrl_ready(ctrl_info);
- if (rc)
+ if (rc) {
+ if (reset_devices) {
+ dev_err(&ctrl_info->pci_dev->dev,
+ "kdump init failed with error %d\n", rc);
+ pqi_lockup_action = REBOOT;
+ pqi_perform_lockup_action();
+ }
return rc;
+ }
/*
* Get the controller properties. This allows us to determine
@@ -8607,21 +8732,6 @@ static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info, unsigned int de
return pqi_ctrl_init_resume(ctrl_info);
}
-static void pqi_perform_lockup_action(void)
-{
- switch (pqi_lockup_action) {
- case PANIC:
- panic("FATAL: Smart Family Controller lockup detected");
- break;
- case REBOOT:
- emergency_restart();
- break;
- case NONE:
- default:
- break;
- }
-}
-
static struct pqi_raid_error_info pqi_ctrl_offline_raid_error_info = {
.data_out_result = PQI_DATA_IN_OUT_HARDWARE_ERROR,
.status = SAM_STAT_CHECK_CONDITION,
@@ -8712,7 +8822,7 @@ static int pqi_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
int rc;
- int node, cp_node;
+ int node;
struct pqi_ctrl_info *ctrl_info;
pqi_print_ctrl_info(pci_dev, id);
@@ -8731,10 +8841,10 @@ static int pqi_pci_probe(struct pci_dev *pci_dev,
node = dev_to_node(&pci_dev->dev);
if (node == NUMA_NO_NODE) {
- cp_node = cpu_to_node(0);
- if (cp_node == NUMA_NO_NODE)
- cp_node = 0;
- set_dev_node(&pci_dev->dev, cp_node);
+ node = cpu_to_node(0);
+ if (node == NUMA_NO_NODE)
+ node = 0;
+ set_dev_node(&pci_dev->dev, node);
}
ctrl_info = pqi_alloc_ctrl_info(node);
@@ -8793,6 +8903,7 @@ static void pqi_shutdown(struct pci_dev *pci_dev)
{
int rc;
struct pqi_ctrl_info *ctrl_info;
+ enum bmic_flush_cache_shutdown_event shutdown_event;
ctrl_info = pci_get_drvdata(pci_dev);
if (!ctrl_info) {
@@ -8808,11 +8919,16 @@ static void pqi_shutdown(struct pci_dev *pci_dev)
pqi_ctrl_block_requests(ctrl_info);
pqi_ctrl_wait_until_quiesced(ctrl_info);
+ if (system_state == SYSTEM_RESTART)
+ shutdown_event = RESTART;
+ else
+ shutdown_event = SHUTDOWN;
+
/*
* Write all data in the controller's battery-backed cache to
* storage.
*/
- rc = pqi_flush_cache(ctrl_info, SHUTDOWN);
+ rc = pqi_flush_cache(ctrl_info, shutdown_event);
if (rc)
dev_err(&pci_dev->dev,
"unable to flush controller cache\n");
@@ -8845,10 +8961,22 @@ static void pqi_process_module_params(void)
pqi_process_lockup_action_param();
}
-static __maybe_unused int pqi_suspend(struct pci_dev *pci_dev, pm_message_t state)
+#if defined(CONFIG_PM)
+
+static inline enum bmic_flush_cache_shutdown_event pqi_get_flush_cache_shutdown_event(struct pci_dev *pci_dev)
+{
+ if (pci_dev->subsystem_vendor == PCI_VENDOR_ID_ADAPTEC2 && pci_dev->subsystem_device == 0x1304)
+ return RESTART;
+
+ return SUSPEND;
+}
+
+static int pqi_suspend_or_freeze(struct device *dev, bool suspend)
{
+ struct pci_dev *pci_dev;
struct pqi_ctrl_info *ctrl_info;
+ pci_dev = to_pci_dev(dev);
ctrl_info = pci_get_drvdata(pci_dev);
pqi_wait_until_ofa_finished(ctrl_info);
@@ -8858,16 +8986,17 @@ static __maybe_unused int pqi_suspend(struct pci_dev *pci_dev, pm_message_t stat
pqi_ctrl_block_device_reset(ctrl_info);
pqi_ctrl_block_requests(ctrl_info);
pqi_ctrl_wait_until_quiesced(ctrl_info);
- pqi_flush_cache(ctrl_info, SUSPEND);
- pqi_stop_heartbeat_timer(ctrl_info);
- pqi_crash_if_pending_command(ctrl_info);
+ if (suspend) {
+ enum bmic_flush_cache_shutdown_event shutdown_event;
- if (state.event == PM_EVENT_FREEZE)
- return 0;
+ shutdown_event = pqi_get_flush_cache_shutdown_event(pci_dev);
+ pqi_flush_cache(ctrl_info, shutdown_event);
+ }
- pci_save_state(pci_dev);
- pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+ pqi_stop_heartbeat_timer(ctrl_info);
+ pqi_crash_if_pending_command(ctrl_info);
+ pqi_free_irqs(ctrl_info);
ctrl_info->controller_online = false;
ctrl_info->pqi_mode_enabled = false;
@@ -8875,44 +9004,89 @@ static __maybe_unused int pqi_suspend(struct pci_dev *pci_dev, pm_message_t stat
return 0;
}
-static __maybe_unused int pqi_resume(struct pci_dev *pci_dev)
+static __maybe_unused int pqi_suspend(struct device *dev)
+{
+ return pqi_suspend_or_freeze(dev, true);
+}
+
+static int pqi_resume_or_restore(struct device *dev)
{
int rc;
+ struct pci_dev *pci_dev;
struct pqi_ctrl_info *ctrl_info;
+ pci_dev = to_pci_dev(dev);
ctrl_info = pci_get_drvdata(pci_dev);
- if (pci_dev->current_state != PCI_D0) {
- ctrl_info->max_hw_queue_index = 0;
- pqi_free_interrupts(ctrl_info);
- pqi_change_irq_mode(ctrl_info, IRQ_MODE_INTX);
- rc = request_irq(pci_irq_vector(pci_dev, 0), pqi_irq_handler,
- IRQF_SHARED, DRIVER_NAME_SHORT,
- &ctrl_info->queue_groups[0]);
- if (rc) {
- dev_err(&ctrl_info->pci_dev->dev,
- "irq %u init failed with error %d\n",
- pci_dev->irq, rc);
- return rc;
- }
- pqi_ctrl_unblock_device_reset(ctrl_info);
- pqi_ctrl_unblock_requests(ctrl_info);
- pqi_scsi_unblock_requests(ctrl_info);
- pqi_ctrl_unblock_scan(ctrl_info);
- return 0;
- }
-
- pci_set_power_state(pci_dev, PCI_D0);
- pci_restore_state(pci_dev);
+ rc = pqi_request_irqs(ctrl_info);
+ if (rc)
+ return rc;
pqi_ctrl_unblock_device_reset(ctrl_info);
pqi_ctrl_unblock_requests(ctrl_info);
pqi_scsi_unblock_requests(ctrl_info);
pqi_ctrl_unblock_scan(ctrl_info);
+ ssleep(PQI_POST_RESET_DELAY_SECS);
+
return pqi_ctrl_init_resume(ctrl_info);
}
+static int pqi_freeze(struct device *dev)
+{
+ return pqi_suspend_or_freeze(dev, false);
+}
+
+static int pqi_thaw(struct device *dev)
+{
+ int rc;
+ struct pci_dev *pci_dev;
+ struct pqi_ctrl_info *ctrl_info;
+
+ pci_dev = to_pci_dev(dev);
+ ctrl_info = pci_get_drvdata(pci_dev);
+
+ rc = pqi_request_irqs(ctrl_info);
+ if (rc)
+ return rc;
+
+ ctrl_info->controller_online = true;
+ ctrl_info->pqi_mode_enabled = true;
+
+ pqi_ctrl_unblock_device_reset(ctrl_info);
+ pqi_ctrl_unblock_requests(ctrl_info);
+ pqi_scsi_unblock_requests(ctrl_info);
+ pqi_ctrl_unblock_scan(ctrl_info);
+
+ return 0;
+}
+
+static int pqi_poweroff(struct device *dev)
+{
+ struct pci_dev *pci_dev;
+ struct pqi_ctrl_info *ctrl_info;
+ enum bmic_flush_cache_shutdown_event shutdown_event;
+
+ pci_dev = to_pci_dev(dev);
+ ctrl_info = pci_get_drvdata(pci_dev);
+
+ shutdown_event = pqi_get_flush_cache_shutdown_event(pci_dev);
+ pqi_flush_cache(ctrl_info, shutdown_event);
+
+ return 0;
+}
+
+static const struct dev_pm_ops pqi_pm_ops = {
+ .suspend = pqi_suspend,
+ .resume = pqi_resume_or_restore,
+ .freeze = pqi_freeze,
+ .thaw = pqi_thaw,
+ .poweroff = pqi_poweroff,
+ .restore = pqi_resume_or_restore,
+};
+
+#endif /* CONFIG_PM */
+
/* Define the PCI IDs for the controllers that we support. */
static const struct pci_device_id pqi_pci_id_table[] = {
{
@@ -8945,10 +9119,6 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
- 0x193d, 0x8460)
- },
- {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
0x193d, 0x1104)
},
{
@@ -9045,6 +9215,34 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x006b)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x006c)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x006d)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x006f)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x0070)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x0071)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x0072)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
0x19e5, 0xd227)
},
{
@@ -9201,6 +9399,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x1304)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
PCI_VENDOR_ID_ADAPTEC2, 0x1380)
},
{
@@ -9261,6 +9463,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x1463)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
PCI_VENDOR_ID_ADAPTEC2, 0x1470)
},
{
@@ -9273,6 +9479,14 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x1473)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x1474)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
PCI_VENDOR_ID_ADAPTEC2, 0x1480)
},
{
@@ -9297,6 +9511,18 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x14a4)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x14a5)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x14a6)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
PCI_VENDOR_ID_ADAPTEC2, 0x14b0)
},
{
@@ -9313,6 +9539,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x14c2)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
PCI_VENDOR_ID_ADAPTEC2, 0x14d0)
},
{
@@ -9417,6 +9647,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1590, 0x036f)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1590, 0x0381)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1590, 0x0382)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1590, 0x0383)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
0x1d8d, 0x0800)
},
{
@@ -9441,6 +9687,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1f0c, 0x3161)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
0x1cf2, 0x5445)
},
{
@@ -9453,6 +9703,30 @@ static const struct pci_device_id pqi_pci_id_table[] = {
},
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1cf2, 0x5449)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1cf2, 0x544a)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1cf2, 0x544b)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1cf2, 0x544d)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1cf2, 0x544e)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1cf2, 0x544f)
+ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
0x1cf2, 0x0b27)
},
{
@@ -9479,8 +9753,9 @@ static struct pci_driver pqi_pci_driver = {
.remove = pqi_pci_remove,
.shutdown = pqi_shutdown,
#if defined(CONFIG_PM)
- .suspend = pqi_suspend,
- .resume = pqi_resume,
+ .driver = {
+ .pm = &pqi_pm_ops
+ },
#endif
};
@@ -9489,6 +9764,8 @@ static int __init pqi_init(void)
int rc;
pr_info(DRIVER_NAME "\n");
+ pqi_verify_structures();
+ sis_verify_structures();
pqi_sas_transport_template = sas_attach_transport(&pqi_sas_transport_functions);
if (!pqi_sas_transport_template)
@@ -9512,7 +9789,7 @@ static void __exit pqi_cleanup(void)
module_init(pqi_init);
module_exit(pqi_cleanup);
-static void __attribute__((unused)) verify_structures(void)
+static void pqi_verify_structures(void)
{
BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers,
sis_host_to_ctrl_doorbell) != 0x20);