summaryrefslogtreecommitdiff
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c112
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c29
3 files changed, 106 insertions, 36 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index a14e8344822b..a6e788c02ff4 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2429,6 +2429,7 @@ struct megasas_instance {
u8 adapter_type;
bool consistent_mask_64bit;
bool support_nvme_passthru;
+ bool enable_sdev_max_qd;
u8 task_abort_tmo;
u8 max_reset_tmo;
u8 snapdump_wait_time;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index f9f07935556e..42cf38c1ea99 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -109,6 +109,10 @@ int event_log_level = MFI_EVT_CLASS_CRITICAL;
module_param(event_log_level, int, 0644);
MODULE_PARM_DESC(event_log_level, "Asynchronous event logging level- range is: -2(CLASS_DEBUG) to 4(CLASS_DEAD), Default: 2(CLASS_CRITICAL)");
+unsigned int enable_sdev_max_qd;
+module_param(enable_sdev_max_qd, int, 0444);
+MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0");
+
MODULE_LICENSE("GPL");
MODULE_VERSION(MEGASAS_VERSION);
MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com");
@@ -1941,25 +1945,19 @@ megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size)
blk_queue_virt_boundary(sdev->request_queue, mr_nvme_pg_size - 1);
}
-
/*
- * megasas_set_static_target_properties -
- * Device property set by driver are static and it is not required to be
- * updated after OCR.
- *
- * set io timeout
- * set device queue depth
- * set nvme device properties. see - megasas_set_nvme_device_properties
+ * megasas_set_fw_assisted_qd -
+ * set device queue depth to can_queue
+ * set device queue depth to fw assisted qd
*
* @sdev: scsi device
* @is_target_prop true, if fw provided target properties.
*/
-static void megasas_set_static_target_properties(struct scsi_device *sdev,
+static void megasas_set_fw_assisted_qd(struct scsi_device *sdev,
bool is_target_prop)
{
u8 interface_type;
u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN;
- u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB;
u32 tgt_device_qd;
struct megasas_instance *instance;
struct MR_PRIV_DEVICE *mr_device_priv_data;
@@ -1968,11 +1966,6 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev,
mr_device_priv_data = sdev->hostdata;
interface_type = mr_device_priv_data->interface_type;
- /*
- * The RAID firmware may require extended timeouts.
- */
- blk_queue_rq_timeout(sdev->request_queue, scmd_timeout * HZ);
-
switch (interface_type) {
case SAS_PD:
device_qd = MEGASAS_SAS_QD;
@@ -1990,18 +1983,49 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev,
if (tgt_device_qd &&
(tgt_device_qd <= instance->host->can_queue))
device_qd = tgt_device_qd;
+ }
- /* max_io_size_kb will be set to non zero for
- * nvme based vd and syspd.
- */
+ if (instance->enable_sdev_max_qd && interface_type != UNKNOWN_DRIVE)
+ device_qd = instance->host->can_queue;
+
+ scsi_change_queue_depth(sdev, device_qd);
+}
+
+/*
+ * megasas_set_static_target_properties -
+ * Device property set by driver are static and it is not required to be
+ * updated after OCR.
+ *
+ * set io timeout
+ * set device queue depth
+ * set nvme device properties. see - megasas_set_nvme_device_properties
+ *
+ * @sdev: scsi device
+ * @is_target_prop true, if fw provided target properties.
+ */
+static void megasas_set_static_target_properties(struct scsi_device *sdev,
+ bool is_target_prop)
+{
+ u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB;
+ struct megasas_instance *instance;
+
+ instance = megasas_lookup_instance(sdev->host->host_no);
+
+ /*
+ * The RAID firmware may require extended timeouts.
+ */
+ blk_queue_rq_timeout(sdev->request_queue, scmd_timeout * HZ);
+
+ /* max_io_size_kb will be set to non zero for
+ * nvme based vd and syspd.
+ */
+ if (is_target_prop)
max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb);
- }
if (instance->nvme_page_size && max_io_size_kb)
megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10));
- scsi_change_queue_depth(sdev, device_qd);
-
+ megasas_set_fw_assisted_qd(sdev, is_target_prop);
}
@@ -3285,6 +3309,48 @@ fw_cmds_outstanding_show(struct device *cdev,
}
static ssize_t
+enable_sdev_max_qd_show(struct device *cdev,
+ struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", instance->enable_sdev_max_qd);
+}
+
+static ssize_t
+enable_sdev_max_qd_store(struct device *cdev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
+ u32 val = 0;
+ bool is_target_prop;
+ int ret_target_prop = DCMD_FAILED;
+ struct scsi_device *sdev;
+
+ if (kstrtou32(buf, 0, &val) != 0) {
+ pr_err("megasas: could not set enable_sdev_max_qd\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&instance->reset_mutex);
+ if (val)
+ instance->enable_sdev_max_qd = true;
+ else
+ instance->enable_sdev_max_qd = false;
+
+ shost_for_each_device(sdev, shost) {
+ ret_target_prop = megasas_get_target_prop(instance, sdev);
+ is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false;
+ megasas_set_fw_assisted_qd(sdev, is_target_prop);
+ }
+ mutex_unlock(&instance->reset_mutex);
+
+ return strlen(buf);
+}
+
+static ssize_t
dump_system_regs_show(struct device *cdev,
struct device_attribute *attr, char *buf)
{
@@ -3313,6 +3379,7 @@ static DEVICE_ATTR_RW(fw_crash_state);
static DEVICE_ATTR_RO(page_size);
static DEVICE_ATTR_RO(ldio_outstanding);
static DEVICE_ATTR_RO(fw_cmds_outstanding);
+static DEVICE_ATTR_RW(enable_sdev_max_qd);
static DEVICE_ATTR_RO(dump_system_regs);
static DEVICE_ATTR_RO(raid_map_id);
@@ -3323,6 +3390,7 @@ static struct device_attribute *megaraid_host_attrs[] = {
&dev_attr_page_size,
&dev_attr_ldio_outstanding,
&dev_attr_fw_cmds_outstanding,
+ &dev_attr_enable_sdev_max_qd,
&dev_attr_dump_system_regs,
&dev_attr_raid_map_id,
NULL,
@@ -5894,6 +5962,8 @@ static int megasas_init_fw(struct megasas_instance *instance)
MR_MAX_RAID_MAP_SIZE_MASK);
}
+ instance->enable_sdev_max_qd = enable_sdev_max_qd;
+
switch (instance->adapter_type) {
case VENTURA_SERIES:
fusion->pcie_bw_limitation = true;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 120e3c4de8c2..e301458bcbae 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -323,9 +323,6 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c
{
u16 cur_max_fw_cmds = 0;
u16 ldio_threshold = 0;
- struct megasas_register_set __iomem *reg_set;
-
- reg_set = instance->reg_set;
/* ventura FW does not fill outbound_scratch_pad_2 with queue depth */
if (instance->adapter_type < VENTURA_SERIES)
@@ -3511,7 +3508,7 @@ megasas_complete_r1_command(struct megasas_instance *instance,
* @instance: Adapter soft state
* Completes all commands that is in reply descriptor queue
*/
-int
+static int
complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex,
struct megasas_irq_context *irq_context)
{
@@ -3702,7 +3699,7 @@ static void megasas_enable_irq_poll(struct megasas_instance *instance)
* megasas_sync_irqs - Synchronizes all IRQs owned by adapter
* @instance: Adapter soft state
*/
-void megasas_sync_irqs(unsigned long instance_addr)
+static void megasas_sync_irqs(unsigned long instance_addr)
{
u32 count, i;
struct megasas_instance *instance =
@@ -3760,7 +3757,7 @@ int megasas_irqpoll(struct irq_poll *irqpoll, int budget)
*
* Tasklet to complete cmds
*/
-void
+static void
megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
{
struct megasas_instance *instance =
@@ -3780,7 +3777,7 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
/**
* megasas_isr_fusion - isr entry point
*/
-irqreturn_t megasas_isr_fusion(int irq, void *devp)
+static irqreturn_t megasas_isr_fusion(int irq, void *devp)
{
struct megasas_irq_context *irq_context = devp;
struct megasas_instance *instance = irq_context->instance;
@@ -3816,7 +3813,7 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp)
* mfi_cmd: megasas_cmd pointer
*
*/
-void
+static void
build_mpt_mfi_pass_thru(struct megasas_instance *instance,
struct megasas_cmd *mfi_cmd)
{
@@ -3874,7 +3871,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
* @cmd: mfi cmd to build
*
*/
-union MEGASAS_REQUEST_DESCRIPTOR_UNION *
+static union MEGASAS_REQUEST_DESCRIPTOR_UNION *
build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
{
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL;
@@ -3900,7 +3897,7 @@ build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
* @cmd: mfi cmd pointer
*
*/
-void
+static void
megasas_issue_dcmd_fusion(struct megasas_instance *instance,
struct megasas_cmd *cmd)
{
@@ -4096,8 +4093,9 @@ static inline void megasas_trigger_snap_dump(struct megasas_instance *instance)
}
/* This function waits for outstanding commands on fusion to complete */
-int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
- int reason, int *convert)
+static int
+megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
+ int reason, int *convert)
{
int i, outstanding, retval = 0, hb_seconds_missed = 0;
u32 fw_state, abs_state;
@@ -4221,7 +4219,7 @@ void megasas_reset_reply_desc(struct megasas_instance *instance)
* megasas_refire_mgmt_cmd : Re-fire management commands
* @instance: Controller's soft instance
*/
-void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
+static void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
{
int j;
struct megasas_cmd_fusion *cmd_fusion;
@@ -4747,7 +4745,8 @@ out:
}
/*SRIOV get other instance in cluster if any*/
-struct megasas_instance *megasas_get_peer_instance(struct megasas_instance *instance)
+static struct
+megasas_instance *megasas_get_peer_instance(struct megasas_instance *instance)
{
int i;
@@ -5053,7 +5052,7 @@ out:
}
/* Fusion Crash dump collection */
-void megasas_fusion_crash_dump(struct megasas_instance *instance)
+static void megasas_fusion_crash_dump(struct megasas_instance *instance)
{
u32 status_reg;
u8 partial_copy = 0;