|
Hannes Reinecke |
336646 |
From: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
|
|
Hannes Reinecke |
336646 |
Date: Tue, 29 Jan 2019 01:38:14 -0800
|
|
Hannes Reinecke |
336646 |
Subject: [PATCH] scsi: megaraid_sas: Add support for DEVICE_LIST DCMD in
|
|
Hannes Reinecke |
336646 |
driver
|
|
Hannes Reinecke |
336646 |
References: bsc#1136271
|
|
Hannes Reinecke |
336646 |
Git-commit: f6fe57310811780d55d79e30da51db98677f1a90
|
|
Hannes Reinecke |
336646 |
Patch-mainline: v5.1-rc1
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
This patch adds support for the new DEVICE_LIST DCMD.
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
Driver currently sends two separate DCMDs for getting the list of PDs and
|
|
Hannes Reinecke |
336646 |
LDs that are exposed to host. The new DCMD provides a single interface to
|
|
Hannes Reinecke |
336646 |
get a list of both PDs and LDs that are exposed to the host. Based on the
|
|
Hannes Reinecke |
336646 |
list of target IDs that are returned by this DCMD, driver will add the
|
|
Hannes Reinecke |
336646 |
devices (PD/LD) to SML. Driver will check for FW support for this new DCMD
|
|
Hannes Reinecke |
336646 |
and based on the support will either send the new DCMD or will fall back to
|
|
Hannes Reinecke |
336646 |
the earlier method of sending two separate DCMDs for PD and LD list.
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
|
|
Hannes Reinecke |
336646 |
Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
|
|
Hannes Reinecke |
336646 |
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
Hannes Reinecke |
336646 |
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
|
Hannes Reinecke |
336646 |
---
|
|
Hannes Reinecke |
336646 |
drivers/scsi/megaraid/megaraid_sas.h | 49 +++++-
|
|
Hannes Reinecke |
336646 |
drivers/scsi/megaraid/megaraid_sas_base.c | 222 +++++++++++++++++++++++++---
|
|
Hannes Reinecke |
336646 |
drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 +
|
|
Hannes Reinecke |
336646 |
drivers/scsi/megaraid/megaraid_sas_fusion.h | 1 +
|
|
Hannes Reinecke |
336646 |
4 files changed, 250 insertions(+), 23 deletions(-)
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
|
|
Hannes Reinecke |
336646 |
index 16536c41f0c5..fe1173f02c54 100644
|
|
Hannes Reinecke |
336646 |
--- a/drivers/scsi/megaraid/megaraid_sas.h
|
|
Hannes Reinecke |
336646 |
+++ b/drivers/scsi/megaraid/megaraid_sas.h
|
|
Hannes Reinecke |
336646 |
@@ -790,6 +790,37 @@ struct MR_LD_TARGETID_LIST {
|
|
Hannes Reinecke |
336646 |
u8 targetId[MAX_LOGICAL_DRIVES_EXT];
|
|
Hannes Reinecke |
336646 |
};
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
+struct MR_HOST_DEVICE_LIST_ENTRY {
|
|
Hannes Reinecke |
336646 |
+ struct {
|
|
Hannes Reinecke |
336646 |
+ union {
|
|
Hannes Reinecke |
336646 |
+ struct {
|
|
Hannes Reinecke |
336646 |
+#if defined(__BIG_ENDIAN_BITFIELD)
|
|
Hannes Reinecke |
336646 |
+ u8 reserved:7;
|
|
Hannes Reinecke |
336646 |
+ u8 is_sys_pd:1;
|
|
Hannes Reinecke |
336646 |
+#else
|
|
Hannes Reinecke |
336646 |
+ u8 is_sys_pd:1;
|
|
Hannes Reinecke |
336646 |
+ u8 reserved:7;
|
|
Hannes Reinecke |
336646 |
+#endif
|
|
Hannes Reinecke |
336646 |
+ } bits;
|
|
Hannes Reinecke |
336646 |
+ u8 byte;
|
|
Hannes Reinecke |
336646 |
+ } u;
|
|
Hannes Reinecke |
336646 |
+ } flags;
|
|
Hannes Reinecke |
336646 |
+ u8 scsi_type;
|
|
Hannes Reinecke |
336646 |
+ __le16 target_id;
|
|
Hannes Reinecke |
336646 |
+ u8 reserved[2];
|
|
Hannes Reinecke |
336646 |
+ __le64 sas_addr[2];
|
|
Hannes Reinecke |
336646 |
+} __packed;
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+struct MR_HOST_DEVICE_LIST {
|
|
Hannes Reinecke |
336646 |
+ __le32 size;
|
|
Hannes Reinecke |
336646 |
+ __le32 count;
|
|
Hannes Reinecke |
336646 |
+ struct MR_HOST_DEVICE_LIST_ENTRY host_device_list[1];
|
|
Hannes Reinecke |
336646 |
+} __packed;
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+#define HOST_DEVICE_LIST_SZ (sizeof(struct MR_HOST_DEVICE_LIST) + \
|
|
Hannes Reinecke |
336646 |
+ (sizeof(struct MR_HOST_DEVICE_LIST_ENTRY) * \
|
|
Hannes Reinecke |
336646 |
+ (MEGASAS_MAX_PD + MAX_LOGICAL_DRIVES_EXT - 1)))
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
/*
|
|
Hannes Reinecke |
336646 |
* SAS controller properties
|
|
Hannes Reinecke |
336646 |
@@ -870,13 +901,17 @@ struct megasas_ctrl_prop {
|
|
Hannes Reinecke |
336646 |
u8 viewSpace;
|
|
Hannes Reinecke |
336646 |
struct {
|
|
Hannes Reinecke |
336646 |
#if defined(__BIG_ENDIAN_BITFIELD)
|
|
Hannes Reinecke |
336646 |
- u16 reserved2:11;
|
|
Hannes Reinecke |
336646 |
+ u16 reserved3:9;
|
|
Hannes Reinecke |
336646 |
+ u16 enable_fw_dev_list:1;
|
|
Hannes Reinecke |
336646 |
+ u16 reserved2:1;
|
|
Hannes Reinecke |
336646 |
u16 enable_snap_dump:1;
|
|
Hannes Reinecke |
336646 |
u16 reserved1:4;
|
|
Hannes Reinecke |
336646 |
#else
|
|
Hannes Reinecke |
336646 |
u16 reserved1:4;
|
|
Hannes Reinecke |
336646 |
u16 enable_snap_dump:1;
|
|
Hannes Reinecke |
336646 |
- u16 reserved2:11;
|
|
Hannes Reinecke |
336646 |
+ u16 reserved2:1;
|
|
Hannes Reinecke |
336646 |
+ u16 enable_fw_dev_list:1;
|
|
Hannes Reinecke |
336646 |
+ u16 reserved3:9;
|
|
Hannes Reinecke |
336646 |
#endif
|
|
Hannes Reinecke |
336646 |
} on_off_properties2;
|
|
Hannes Reinecke |
336646 |
};
|
|
Hannes Reinecke |
336646 |
@@ -1685,7 +1720,8 @@ union megasas_sgl_frame {
|
|
Hannes Reinecke |
336646 |
typedef union _MFI_CAPABILITIES {
|
|
Hannes Reinecke |
336646 |
struct {
|
|
Hannes Reinecke |
336646 |
#if defined(__BIG_ENDIAN_BITFIELD)
|
|
Hannes Reinecke |
336646 |
- u32 reserved:17;
|
|
Hannes Reinecke |
336646 |
+ u32 reserved:16;
|
|
Hannes Reinecke |
336646 |
+ u32 support_fw_exposed_dev_list:1;
|
|
Hannes Reinecke |
336646 |
u32 support_nvme_passthru:1;
|
|
Hannes Reinecke |
336646 |
u32 support_64bit_mode:1;
|
|
Hannes Reinecke |
336646 |
u32 support_pd_map_target_id:1;
|
|
Hannes Reinecke |
336646 |
@@ -1717,7 +1753,8 @@ typedef union _MFI_CAPABILITIES {
|
|
Hannes Reinecke |
336646 |
u32 support_pd_map_target_id:1;
|
|
Hannes Reinecke |
336646 |
u32 support_64bit_mode:1;
|
|
Hannes Reinecke |
336646 |
u32 support_nvme_passthru:1;
|
|
Hannes Reinecke |
336646 |
- u32 reserved:17;
|
|
Hannes Reinecke |
336646 |
+ u32 support_fw_exposed_dev_list:1;
|
|
Hannes Reinecke |
336646 |
+ u32 reserved:16;
|
|
Hannes Reinecke |
336646 |
#endif
|
|
Hannes Reinecke |
336646 |
} mfi_capabilities;
|
|
Hannes Reinecke |
336646 |
__le32 reg;
|
|
Hannes Reinecke |
336646 |
@@ -2202,6 +2239,9 @@ struct megasas_instance {
|
|
Hannes Reinecke |
336646 |
struct MR_LD_TARGETID_LIST *ld_targetid_list_buf;
|
|
Hannes Reinecke |
336646 |
dma_addr_t ld_targetid_list_buf_h;
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
+ struct MR_HOST_DEVICE_LIST *host_device_list_buf;
|
|
Hannes Reinecke |
336646 |
+ dma_addr_t host_device_list_buf_h;
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
struct MR_SNAPDUMP_PROPERTIES *snapdump_prop;
|
|
Hannes Reinecke |
336646 |
dma_addr_t snapdump_prop_h;
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
@@ -2337,6 +2377,7 @@ struct megasas_instance {
|
|
Hannes Reinecke |
336646 |
u8 task_abort_tmo;
|
|
Hannes Reinecke |
336646 |
u8 max_reset_tmo;
|
|
Hannes Reinecke |
336646 |
u8 snapdump_wait_time;
|
|
Hannes Reinecke |
336646 |
+ u8 enable_fw_dev_list;
|
|
Hannes Reinecke |
336646 |
};
|
|
Hannes Reinecke |
336646 |
struct MR_LD_VF_MAP {
|
|
Hannes Reinecke |
336646 |
u32 size;
|
|
Hannes Reinecke |
336646 |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
|
|
Hannes Reinecke |
336646 |
index e6dd1aab9931..37e811d9c4c4 100644
|
|
Hannes Reinecke |
336646 |
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
|
|
Hannes Reinecke |
336646 |
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
|
|
Hannes Reinecke |
336646 |
@@ -4640,6 +4640,123 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
|
|
Hannes Reinecke |
336646 |
return ret;
|
|
Hannes Reinecke |
336646 |
}
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
+/**
|
|
Hannes Reinecke |
336646 |
+ * dcmd.opcode - MR_DCMD_CTRL_DEVICE_LIST_GET
|
|
Hannes Reinecke |
336646 |
+ * dcmd.mbox - reserved
|
|
Hannes Reinecke |
336646 |
+ * dcmd.sge IN - ptr to return MR_HOST_DEVICE_LIST structure
|
|
Hannes Reinecke |
336646 |
+ * Desc: This DCMD will return the combined device list
|
|
Hannes Reinecke |
336646 |
+ * Status: MFI_STAT_OK - List returned successfully
|
|
Hannes Reinecke |
336646 |
+ * MFI_STAT_INVALID_CMD - Firmware support for the feature has been
|
|
Hannes Reinecke |
336646 |
+ * disabled
|
|
Hannes Reinecke |
336646 |
+ * @instance: Adapter soft state
|
|
Hannes Reinecke |
336646 |
+ * @is_probe: Driver probe check
|
|
Hannes Reinecke |
336646 |
+ * Return: 0 if DCMD succeeded
|
|
Hannes Reinecke |
336646 |
+ * non-zero if failed
|
|
Hannes Reinecke |
336646 |
+ */
|
|
Hannes Reinecke |
336646 |
+int
|
|
Hannes Reinecke |
336646 |
+megasas_host_device_list_query(struct megasas_instance *instance,
|
|
Hannes Reinecke |
336646 |
+ bool is_probe)
|
|
Hannes Reinecke |
336646 |
+{
|
|
Hannes Reinecke |
336646 |
+ int ret, i, target_id;
|
|
Hannes Reinecke |
336646 |
+ struct megasas_cmd *cmd;
|
|
Hannes Reinecke |
336646 |
+ struct megasas_dcmd_frame *dcmd;
|
|
Hannes Reinecke |
336646 |
+ struct MR_HOST_DEVICE_LIST *ci;
|
|
Hannes Reinecke |
336646 |
+ u32 count;
|
|
Hannes Reinecke |
336646 |
+ dma_addr_t ci_h;
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ ci = instance->host_device_list_buf;
|
|
Hannes Reinecke |
336646 |
+ ci_h = instance->host_device_list_buf_h;
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ cmd = megasas_get_cmd(instance);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ if (!cmd) {
|
|
Hannes Reinecke |
336646 |
+ dev_warn(&instance->pdev->dev,
|
|
Hannes Reinecke |
336646 |
+ "%s: failed to get cmd\n",
|
|
Hannes Reinecke |
336646 |
+ __func__);
|
|
Hannes Reinecke |
336646 |
+ return -ENOMEM;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ dcmd = &cmd->frame->dcmd;
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ memset(ci, 0, sizeof(*ci));
|
|
Hannes Reinecke |
336646 |
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ dcmd->mbox.b[0] = is_probe ? 0 : 1;
|
|
Hannes Reinecke |
336646 |
+ dcmd->cmd = MFI_CMD_DCMD;
|
|
Hannes Reinecke |
336646 |
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
|
|
Hannes Reinecke |
336646 |
+ dcmd->sge_count = 1;
|
|
Hannes Reinecke |
336646 |
+ dcmd->flags = MFI_FRAME_DIR_READ;
|
|
Hannes Reinecke |
336646 |
+ dcmd->timeout = 0;
|
|
Hannes Reinecke |
336646 |
+ dcmd->pad_0 = 0;
|
|
Hannes Reinecke |
336646 |
+ dcmd->data_xfer_len = cpu_to_le32(HOST_DEVICE_LIST_SZ);
|
|
Hannes Reinecke |
336646 |
+ dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_DEVICE_LIST_GET);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ megasas_set_dma_settings(instance, dcmd, ci_h, HOST_DEVICE_LIST_SZ);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ if (!instance->mask_interrupts) {
|
|
Hannes Reinecke |
336646 |
+ ret = megasas_issue_blocked_cmd(instance, cmd,
|
|
Hannes Reinecke |
336646 |
+ MFI_IO_TIMEOUT_SECS);
|
|
Hannes Reinecke |
336646 |
+ } else {
|
|
Hannes Reinecke |
336646 |
+ ret = megasas_issue_polled(instance, cmd);
|
|
Hannes Reinecke |
336646 |
+ cmd->flags |= DRV_DCMD_SKIP_REFIRE;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ switch (ret) {
|
|
Hannes Reinecke |
336646 |
+ case DCMD_SUCCESS:
|
|
Hannes Reinecke |
336646 |
+ /* Fill the internal pd_list and ld_ids array based on
|
|
Hannes Reinecke |
336646 |
+ * targetIds returned by FW
|
|
Hannes Reinecke |
336646 |
+ */
|
|
Hannes Reinecke |
336646 |
+ count = le32_to_cpu(ci->count);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ memset(instance->local_pd_list, 0,
|
|
Hannes Reinecke |
336646 |
+ MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
|
|
Hannes Reinecke |
336646 |
+ memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT);
|
|
Hannes Reinecke |
336646 |
+ for (i = 0; i < count; i++) {
|
|
Hannes Reinecke |
336646 |
+ target_id = le16_to_cpu(ci->host_device_list[i].target_id);
|
|
Hannes Reinecke |
336646 |
+ if (ci->host_device_list[i].flags.u.bits.is_sys_pd) {
|
|
Hannes Reinecke |
336646 |
+ instance->local_pd_list[target_id].tid = target_id;
|
|
Hannes Reinecke |
336646 |
+ instance->local_pd_list[target_id].driveType =
|
|
Hannes Reinecke |
336646 |
+ ci->host_device_list[i].scsi_type;
|
|
Hannes Reinecke |
336646 |
+ instance->local_pd_list[target_id].driveState =
|
|
Hannes Reinecke |
336646 |
+ MR_PD_STATE_SYSTEM;
|
|
Hannes Reinecke |
336646 |
+ } else {
|
|
Hannes Reinecke |
336646 |
+ instance->ld_ids[target_id] = target_id;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ memcpy(instance->pd_list, instance->local_pd_list,
|
|
Hannes Reinecke |
336646 |
+ sizeof(instance->pd_list));
|
|
Hannes Reinecke |
336646 |
+ break;
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ case DCMD_TIMEOUT:
|
|
Hannes Reinecke |
336646 |
+ switch (dcmd_timeout_ocr_possible(instance)) {
|
|
Hannes Reinecke |
336646 |
+ case INITIATE_OCR:
|
|
Hannes Reinecke |
336646 |
+ cmd->flags |= DRV_DCMD_SKIP_REFIRE;
|
|
Hannes Reinecke |
336646 |
+ megasas_reset_fusion(instance->host,
|
|
Hannes Reinecke |
336646 |
+ MFI_IO_TIMEOUT_OCR);
|
|
Hannes Reinecke |
336646 |
+ break;
|
|
Hannes Reinecke |
336646 |
+ case KILL_ADAPTER:
|
|
Hannes Reinecke |
336646 |
+ megaraid_sas_kill_hba(instance);
|
|
Hannes Reinecke |
336646 |
+ break;
|
|
Hannes Reinecke |
336646 |
+ case IGNORE_TIMEOUT:
|
|
Hannes Reinecke |
336646 |
+ dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
|
|
Hannes Reinecke |
336646 |
+ __func__, __LINE__);
|
|
Hannes Reinecke |
336646 |
+ break;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+ break;
|
|
Hannes Reinecke |
336646 |
+ case DCMD_FAILED:
|
|
Hannes Reinecke |
336646 |
+ dev_err(&instance->pdev->dev,
|
|
Hannes Reinecke |
336646 |
+ "%s: MR_DCMD_CTRL_DEVICE_LIST_GET failed\n",
|
|
Hannes Reinecke |
336646 |
+ __func__);
|
|
Hannes Reinecke |
336646 |
+ break;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ if (ret != DCMD_TIMEOUT)
|
|
Hannes Reinecke |
336646 |
+ megasas_return_cmd(instance, cmd);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ return ret;
|
|
Hannes Reinecke |
336646 |
+}
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
/*
|
|
Hannes Reinecke |
336646 |
* megasas_update_ext_vd_details : Update details w.r.t Extended VD
|
|
Hannes Reinecke |
336646 |
* instance : Controller's instance
|
|
Hannes Reinecke |
336646 |
@@ -4867,6 +4984,9 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
|
|
Hannes Reinecke |
336646 |
(ci->properties.on_off_properties2.enable_snap_dump ?
|
|
Hannes Reinecke |
336646 |
MEGASAS_DEFAULT_SNAP_DUMP_WAIT_TIME : 0);
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
+ instance->enable_fw_dev_list =
|
|
Hannes Reinecke |
336646 |
+ ci->properties.on_off_properties2.enable_fw_dev_list;
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
dev_info(&instance->pdev->dev,
|
|
Hannes Reinecke |
336646 |
"controller type\t: %s(%dMB)\n",
|
|
Hannes Reinecke |
336646 |
instance->is_imr ? "iMR" : "MR",
|
|
Hannes Reinecke |
336646 |
@@ -5331,6 +5451,8 @@ static void megasas_setup_reply_map(struct megasas_instance *instance)
|
|
Hannes Reinecke |
336646 |
* @return: Success or failure
|
|
Hannes Reinecke |
336646 |
*
|
|
Hannes Reinecke |
336646 |
* Issue DCMDs to Firmware to get the PD and LD list.
|
|
Hannes Reinecke |
336646 |
+ * Based on the FW support, driver sends the HOST_DEVICE_LIST or combination
|
|
Hannes Reinecke |
336646 |
+ * of PD_LIST/LD_LIST_QUERY DCMDs to get the device list.
|
|
Hannes Reinecke |
336646 |
*/
|
|
Hannes Reinecke |
336646 |
static
|
|
Hannes Reinecke |
336646 |
int megasas_get_device_list(struct megasas_instance *instance)
|
|
Hannes Reinecke |
336646 |
@@ -5339,15 +5461,20 @@ int megasas_get_device_list(struct megasas_instance *instance)
|
|
Hannes Reinecke |
336646 |
(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
|
|
Hannes Reinecke |
336646 |
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
- if (megasas_get_pd_list(instance) < 0) {
|
|
Hannes Reinecke |
336646 |
- dev_err(&instance->pdev->dev, "failed to get PD list\n");
|
|
Hannes Reinecke |
336646 |
- return FAILED;
|
|
Hannes Reinecke |
336646 |
- }
|
|
Hannes Reinecke |
336646 |
+ if (instance->enable_fw_dev_list) {
|
|
Hannes Reinecke |
336646 |
+ if (megasas_host_device_list_query(instance, true))
|
|
Hannes Reinecke |
336646 |
+ return FAILED;
|
|
Hannes Reinecke |
336646 |
+ } else {
|
|
Hannes Reinecke |
336646 |
+ if (megasas_get_pd_list(instance) < 0) {
|
|
Hannes Reinecke |
336646 |
+ dev_err(&instance->pdev->dev, "failed to get PD list\n");
|
|
Hannes Reinecke |
336646 |
+ return FAILED;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
- if (megasas_ld_list_query(instance,
|
|
Hannes Reinecke |
336646 |
- MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) {
|
|
Hannes Reinecke |
336646 |
- dev_err(&instance->pdev->dev, "failed to get LD list\n");
|
|
Hannes Reinecke |
336646 |
- return FAILED;
|
|
Hannes Reinecke |
336646 |
+ if (megasas_ld_list_query(instance,
|
|
Hannes Reinecke |
336646 |
+ MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) {
|
|
Hannes Reinecke |
336646 |
+ dev_err(&instance->pdev->dev, "failed to get LD list\n");
|
|
Hannes Reinecke |
336646 |
+ return FAILED;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
}
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
return SUCCESS;
|
|
Hannes Reinecke |
336646 |
@@ -6449,6 +6576,18 @@ int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance)
|
|
Hannes Reinecke |
336646 |
if (!instance->snapdump_prop)
|
|
Hannes Reinecke |
336646 |
dev_err(&pdev->dev,
|
|
Hannes Reinecke |
336646 |
"Failed to allocate snapdump properties buffer\n");
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ instance->host_device_list_buf = dma_alloc_coherent(&pdev->dev,
|
|
Hannes Reinecke |
336646 |
+ HOST_DEVICE_LIST_SZ,
|
|
Hannes Reinecke |
336646 |
+ &instance->host_device_list_buf_h,
|
|
Hannes Reinecke |
336646 |
+ GFP_KERNEL);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ if (!instance->host_device_list_buf) {
|
|
Hannes Reinecke |
336646 |
+ dev_err(&pdev->dev,
|
|
Hannes Reinecke |
336646 |
+ "Failed to allocate targetid list buffer\n");
|
|
Hannes Reinecke |
336646 |
+ return -ENOMEM;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
}
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
instance->pd_list_buf =
|
|
Hannes Reinecke |
336646 |
@@ -6598,6 +6737,13 @@ void megasas_free_ctrl_dma_buffers(struct megasas_instance *instance)
|
|
Hannes Reinecke |
336646 |
sizeof(struct MR_SNAPDUMP_PROPERTIES),
|
|
Hannes Reinecke |
336646 |
instance->snapdump_prop,
|
|
Hannes Reinecke |
336646 |
instance->snapdump_prop_h);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ if (instance->host_device_list_buf)
|
|
Hannes Reinecke |
336646 |
+ dma_free_coherent(&pdev->dev,
|
|
Hannes Reinecke |
336646 |
+ HOST_DEVICE_LIST_SZ,
|
|
Hannes Reinecke |
336646 |
+ instance->host_device_list_buf,
|
|
Hannes Reinecke |
336646 |
+ instance->host_device_list_buf_h);
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
}
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
/*
|
|
Hannes Reinecke |
336646 |
@@ -6771,7 +6917,9 @@ static int megasas_probe_one(struct pci_dev *pdev,
|
|
Hannes Reinecke |
336646 |
/*
|
|
Hannes Reinecke |
336646 |
* Trigger SCSI to scan our drives
|
|
Hannes Reinecke |
336646 |
*/
|
|
Hannes Reinecke |
336646 |
- scsi_scan_host(host);
|
|
Hannes Reinecke |
336646 |
+ if (!instance->enable_fw_dev_list ||
|
|
Hannes Reinecke |
336646 |
+ (instance->host_device_list_buf->count > 0))
|
|
Hannes Reinecke |
336646 |
+ scsi_scan_host(host);
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
/*
|
|
Hannes Reinecke |
336646 |
* Initiate AEN (Asynchronous Event Notification)
|
|
Hannes Reinecke |
336646 |
@@ -7900,6 +8048,8 @@ static inline void megasas_remove_scsi_device(struct scsi_device *sdev)
|
|
Hannes Reinecke |
336646 |
* @return: Success or failure
|
|
Hannes Reinecke |
336646 |
*
|
|
Hannes Reinecke |
336646 |
* Issue DCMDs to Firmware to update the internal device list in driver.
|
|
Hannes Reinecke |
336646 |
+ * Based on the FW support, driver sends the HOST_DEVICE_LIST or combination
|
|
Hannes Reinecke |
336646 |
+ * of PD_LIST/LD_LIST_QUERY DCMDs to get the device list.
|
|
Hannes Reinecke |
336646 |
*/
|
|
Hannes Reinecke |
336646 |
static
|
|
Hannes Reinecke |
336646 |
int megasas_update_device_list(struct megasas_instance *instance,
|
|
Hannes Reinecke |
336646 |
@@ -7907,22 +8057,28 @@ int megasas_update_device_list(struct megasas_instance *instance,
|
|
Hannes Reinecke |
336646 |
{
|
|
Hannes Reinecke |
336646 |
int dcmd_ret = DCMD_SUCCESS;
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
- if (event_type & SCAN_PD_CHANNEL) {
|
|
Hannes Reinecke |
336646 |
- dcmd_ret = megasas_get_pd_list(instance);
|
|
Hannes Reinecke |
336646 |
-
|
|
Hannes Reinecke |
336646 |
+ if (instance->enable_fw_dev_list) {
|
|
Hannes Reinecke |
336646 |
+ dcmd_ret = megasas_host_device_list_query(instance, false);
|
|
Hannes Reinecke |
336646 |
if (dcmd_ret != DCMD_SUCCESS)
|
|
Hannes Reinecke |
336646 |
goto out;
|
|
Hannes Reinecke |
336646 |
- }
|
|
Hannes Reinecke |
336646 |
+ } else {
|
|
Hannes Reinecke |
336646 |
+ if (event_type & SCAN_PD_CHANNEL) {
|
|
Hannes Reinecke |
336646 |
+ dcmd_ret = megasas_get_pd_list(instance);
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
- if (event_type & SCAN_VD_CHANNEL) {
|
|
Hannes Reinecke |
336646 |
- if (!instance->requestorId ||
|
|
Hannes Reinecke |
336646 |
- (instance->requestorId &&
|
|
Hannes Reinecke |
336646 |
- megasas_get_ld_vf_affiliation(instance, 0))) {
|
|
Hannes Reinecke |
336646 |
- dcmd_ret = megasas_ld_list_query(instance,
|
|
Hannes Reinecke |
336646 |
- MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
|
|
Hannes Reinecke |
336646 |
if (dcmd_ret != DCMD_SUCCESS)
|
|
Hannes Reinecke |
336646 |
goto out;
|
|
Hannes Reinecke |
336646 |
}
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
+ if (event_type & SCAN_VD_CHANNEL) {
|
|
Hannes Reinecke |
336646 |
+ if (!instance->requestorId ||
|
|
Hannes Reinecke |
336646 |
+ (instance->requestorId &&
|
|
Hannes Reinecke |
336646 |
+ megasas_get_ld_vf_affiliation(instance, 0))) {
|
|
Hannes Reinecke |
336646 |
+ dcmd_ret = megasas_ld_list_query(instance,
|
|
Hannes Reinecke |
336646 |
+ MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
|
|
Hannes Reinecke |
336646 |
+ if (dcmd_ret != DCMD_SUCCESS)
|
|
Hannes Reinecke |
336646 |
+ goto out;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
}
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
out:
|
|
Hannes Reinecke |
336646 |
@@ -7943,11 +8099,39 @@ void megasas_add_remove_devices(struct megasas_instance *instance,
|
|
Hannes Reinecke |
336646 |
int i, j;
|
|
Hannes Reinecke |
336646 |
u16 pd_index = 0;
|
|
Hannes Reinecke |
336646 |
u16 ld_index = 0;
|
|
Hannes Reinecke |
336646 |
+ u16 channel = 0, id = 0;
|
|
Hannes Reinecke |
336646 |
struct Scsi_Host *host;
|
|
Hannes Reinecke |
336646 |
struct scsi_device *sdev1;
|
|
Hannes Reinecke |
336646 |
+ struct MR_HOST_DEVICE_LIST *targetid_list = NULL;
|
|
Hannes Reinecke |
336646 |
+ struct MR_HOST_DEVICE_LIST_ENTRY *targetid_entry = NULL;
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
host = instance->host;
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
+ if (instance->enable_fw_dev_list) {
|
|
Hannes Reinecke |
336646 |
+ targetid_list = instance->host_device_list_buf;
|
|
Hannes Reinecke |
336646 |
+ for (i = 0; i < targetid_list->count; i++) {
|
|
Hannes Reinecke |
336646 |
+ targetid_entry = &targetid_list->host_device_list[i];
|
|
Hannes Reinecke |
336646 |
+ if (targetid_entry->flags.u.bits.is_sys_pd) {
|
|
Hannes Reinecke |
336646 |
+ channel = le16_to_cpu(targetid_entry->target_id) /
|
|
Hannes Reinecke |
336646 |
+ MEGASAS_MAX_DEV_PER_CHANNEL;
|
|
Hannes Reinecke |
336646 |
+ id = le16_to_cpu(targetid_entry->target_id) %
|
|
Hannes Reinecke |
336646 |
+ MEGASAS_MAX_DEV_PER_CHANNEL;
|
|
Hannes Reinecke |
336646 |
+ } else {
|
|
Hannes Reinecke |
336646 |
+ channel = MEGASAS_MAX_PD_CHANNELS +
|
|
Hannes Reinecke |
336646 |
+ (le16_to_cpu(targetid_entry->target_id) /
|
|
Hannes Reinecke |
336646 |
+ MEGASAS_MAX_DEV_PER_CHANNEL);
|
|
Hannes Reinecke |
336646 |
+ id = le16_to_cpu(targetid_entry->target_id) %
|
|
Hannes Reinecke |
336646 |
+ MEGASAS_MAX_DEV_PER_CHANNEL;
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+ sdev1 = scsi_device_lookup(host, channel, id, 0);
|
|
Hannes Reinecke |
336646 |
+ if (!sdev1) {
|
|
Hannes Reinecke |
336646 |
+ scsi_add_device(host, channel, id, 0);
|
|
Hannes Reinecke |
336646 |
+ } else {
|
|
Hannes Reinecke |
336646 |
+ scsi_device_put(sdev1);
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+ }
|
|
Hannes Reinecke |
336646 |
+
|
|
Hannes Reinecke |
336646 |
if (scan_type & SCAN_PD_CHANNEL) {
|
|
Hannes Reinecke |
336646 |
for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
|
|
Hannes Reinecke |
336646 |
for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
|
|
Hannes Reinecke |
336646 |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
|
|
Hannes Reinecke |
336646 |
index 3cecee38b192..4e912e01bb89 100644
|
|
Hannes Reinecke |
336646 |
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
|
|
Hannes Reinecke |
336646 |
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
|
|
Hannes Reinecke |
336646 |
@@ -1074,6 +1074,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
|
|
Hannes Reinecke |
336646 |
drv_ops->mfi_capabilities.support_qd_throttling = 1;
|
|
Hannes Reinecke |
336646 |
drv_ops->mfi_capabilities.support_pd_map_target_id = 1;
|
|
Hannes Reinecke |
336646 |
drv_ops->mfi_capabilities.support_nvme_passthru = 1;
|
|
Hannes Reinecke |
336646 |
+ drv_ops->mfi_capabilities.support_fw_exposed_dev_list = 1;
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
if (instance->consistent_mask_64bit)
|
|
Hannes Reinecke |
336646 |
drv_ops->mfi_capabilities.support_64bit_mode = 1;
|
|
Hannes Reinecke |
336646 |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
|
|
Hannes Reinecke |
336646 |
index ca73c50fe723..1481bf029490 100644
|
|
Hannes Reinecke |
336646 |
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
|
|
Hannes Reinecke |
336646 |
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
|
|
Hannes Reinecke |
336646 |
@@ -724,6 +724,7 @@ struct MPI2_IOC_INIT_REQUEST {
|
|
Hannes Reinecke |
336646 |
#define MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111 0x03200200
|
|
Hannes Reinecke |
336646 |
#define MR_DCMD_LD_VF_MAP_GET_ALL_LDS 0x03150200
|
|
Hannes Reinecke |
336646 |
#define MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES 0x01200100
|
|
Hannes Reinecke |
336646 |
+#define MR_DCMD_CTRL_DEVICE_LIST_GET 0x01190600
|
|
Hannes Reinecke |
336646 |
|
|
Hannes Reinecke |
336646 |
struct MR_DEV_HANDLE_INFO {
|
|
Hannes Reinecke |
336646 |
__le16 curDevHdl;
|
|
Hannes Reinecke |
336646 |
--
|
|
Hannes Reinecke |
336646 |
2.16.4
|
|
Hannes Reinecke |
336646 |
|