Message ID | 1502798740-69337-1-git-send-email-hare@suse.de (mailing list archive) |
---|---|
State | Changes Requested, archived |
Headers | show |
>-----Original Message----- >From: Hannes Reinecke [mailto:hare@suse.de] >Sent: Tuesday, August 15, 2017 5:36 PM >To: Martin K. Petersen >Cc: Christoph Hellwig; James Bottomley; Sumit Saxena; Kashyap Desai; >megaraidlinux.pdl@broadcom.com; linux-scsi@vger.kernel.org; Hannes >Reinecke >Subject: [PATCH] megaraid_sas: Fallback to older scanning if no disks are >found > >commit 21c9e160a51383d4cb0b882398534b0c95c0cc3b implemented a new >driver lookup using the MR_DCMD_LD_LIST_QUERY firmware command. >However, this command might not work properly on older firmware, causing >the command to return no drives instead of an error. >This causes a regression on older firmware as the driver will no longer detect >any drives. >This patch checks if MR_DCMD_LD_LIST_QUERY return no drives, and falls >back to the original method if so. > >Signed-off-by: Hannes Reinecke <hare@suse.de> >--- > drivers/scsi/megaraid/megaraid_sas_base.c | 29 >+++++++++++++++++++++++------ > 1 file changed, 23 insertions(+), 6 deletions(-) > >diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c >b/drivers/scsi/megaraid/megaraid_sas_base.c >index 39b08fc..a1cf2c3 100644 >--- a/drivers/scsi/megaraid/megaraid_sas_base.c >+++ b/drivers/scsi/megaraid/megaraid_sas_base.c >@@ -4502,7 +4502,6 @@ int megasas_alloc_cmds(struct megasas_instance >*instance) > dev_info(&instance->pdev->dev, > "DCMD not supported by firmware - %s %d\n", > __func__, __LINE__); >- ret = megasas_get_ld_list(instance); > break; > case DCMD_TIMEOUT: > switch (dcmd_timeout_ocr_possible(instance)) { @@ -4530,6 >+4529,14 @@ int megasas_alloc_cmds(struct megasas_instance *instance) > break; > case DCMD_SUCCESS: > tgtid_count = le32_to_cpu(ci->count); >+ /* >+ * Some older firmware return '0' if the LD LIST QUERY >+ * command is not supported. >+ */ >+ if (tgtid_count == 0) { >+ ret = DCMD_FAILED; >+ break; >+ } If firmware does not support LD_LIST_QUERY, "DCMD_FAILED" should be returned by megasas_issue_blocked_cmd (function which fires command to firmware) instead of DCMD_SCCESS. Can you please help with older firmware version which returns DCMD_SUCCESS(0) if LD_LIST_QUERY is not supported ? "tgtid_count" may be zero(in case of no logical disks configured) even when firmware supports LD LIST QUERY and in that case also driver will fire old command by calling megasas_get_ld_list() but that's not a problem. Thanks, Sumit > > if ((tgtid_count > (instance->fw_supported_vd_count))) > break; >@@ -5146,7 +5153,7 @@ static int megasas_init_fw(struct megasas_instance >*instance) > struct megasas_register_set __iomem *reg_set; > struct megasas_ctrl_info *ctrl_info = NULL; > unsigned long bar_list; >- int i, j, loop, fw_msix_count = 0; >+ int i, j, loop, fw_msix_count = 0, ret; > struct IOV_111 *iovPtr; > struct fusion_context *fusion; > >@@ -5384,8 +5391,11 @@ static int megasas_init_fw(struct megasas_instance >*instance) > } > } > >- if (megasas_ld_list_query(instance, >- MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) >+ ret = megasas_ld_list_query(instance, >+ MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); >+ if (ret == DCMD_FAILED) >+ ret = megasas_get_ld_list(instance); >+ if (ret) > goto fail_get_ld_pd_list; > > /* >@@ -7426,8 +7436,12 @@ static inline void >megasas_remove_scsi_device(struct scsi_device *sdev) > case MR_EVT_LD_DELETED: > case MR_EVT_LD_CREATED: > if (!instance->requestorId || >- (instance->requestorId && >megasas_get_ld_vf_affiliation(instance, 0))) >+ (instance->requestorId && >+ megasas_get_ld_vf_affiliation(instance, 0))) { > dcmd_ret = megasas_ld_list_query(instance, >MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); >+ if (dcmd_ret == DCMD_FAILED) >+ dcmd_ret = >megasas_get_ld_list(instance); >+ } > > if (dcmd_ret == DCMD_SUCCESS) > doscan = SCAN_VD_CHANNEL; >@@ -7443,8 +7457,11 @@ static inline void >megasas_remove_scsi_device(struct scsi_device *sdev) > break; > > if (!instance->requestorId || >- (instance->requestorId && >megasas_get_ld_vf_affiliation(instance, 0))) >+ (instance->requestorId && >+megasas_get_ld_vf_affiliation(instance, 0))) { > dcmd_ret = megasas_ld_list_query(instance, >MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); >+ if (dcmd_ret == DCMD_FAILED) >+ dcmd_ret = >megasas_get_ld_list(instance); >+ } > > if (dcmd_ret != DCMD_SUCCESS) > break; >-- >1.8.5.6
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 39b08fc..a1cf2c3 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4502,7 +4502,6 @@ int megasas_alloc_cmds(struct megasas_instance *instance) dev_info(&instance->pdev->dev, "DCMD not supported by firmware - %s %d\n", __func__, __LINE__); - ret = megasas_get_ld_list(instance); break; case DCMD_TIMEOUT: switch (dcmd_timeout_ocr_possible(instance)) { @@ -4530,6 +4529,14 @@ int megasas_alloc_cmds(struct megasas_instance *instance) break; case DCMD_SUCCESS: tgtid_count = le32_to_cpu(ci->count); + /* + * Some older firmware return '0' if the LD LIST QUERY + * command is not supported. + */ + if (tgtid_count == 0) { + ret = DCMD_FAILED; + break; + } if ((tgtid_count > (instance->fw_supported_vd_count))) break; @@ -5146,7 +5153,7 @@ static int megasas_init_fw(struct megasas_instance *instance) struct megasas_register_set __iomem *reg_set; struct megasas_ctrl_info *ctrl_info = NULL; unsigned long bar_list; - int i, j, loop, fw_msix_count = 0; + int i, j, loop, fw_msix_count = 0, ret; struct IOV_111 *iovPtr; struct fusion_context *fusion; @@ -5384,8 +5391,11 @@ static int megasas_init_fw(struct megasas_instance *instance) } } - if (megasas_ld_list_query(instance, - MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) + ret = megasas_ld_list_query(instance, + MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); + if (ret == DCMD_FAILED) + ret = megasas_get_ld_list(instance); + if (ret) goto fail_get_ld_pd_list; /* @@ -7426,8 +7436,12 @@ static inline void megasas_remove_scsi_device(struct scsi_device *sdev) case MR_EVT_LD_DELETED: case MR_EVT_LD_CREATED: if (!instance->requestorId || - (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0))) + (instance->requestorId && + megasas_get_ld_vf_affiliation(instance, 0))) { dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); + if (dcmd_ret == DCMD_FAILED) + dcmd_ret = megasas_get_ld_list(instance); + } if (dcmd_ret == DCMD_SUCCESS) doscan = SCAN_VD_CHANNEL; @@ -7443,8 +7457,11 @@ static inline void megasas_remove_scsi_device(struct scsi_device *sdev) break; if (!instance->requestorId || - (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0))) + (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0))) { dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); + if (dcmd_ret == DCMD_FAILED) + dcmd_ret = megasas_get_ld_list(instance); + } if (dcmd_ret != DCMD_SUCCESS) break;
commit 21c9e160a51383d4cb0b882398534b0c95c0cc3b implemented a new driver lookup using the MR_DCMD_LD_LIST_QUERY firmware command. However, this command might not work properly on older firmware, causing the command to return no drives instead of an error. This causes a regression on older firmware as the driver will no longer detect any drives. This patch checks if MR_DCMD_LD_LIST_QUERY return no drives, and falls back to the original method if so. Signed-off-by: Hannes Reinecke <hare@suse.de> --- drivers/scsi/megaraid/megaraid_sas_base.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)