Skip to content

Commit 60b4dd1

Browse files
quic-ziqichenmartinkpetersen
authored andcommitted
scsi: ufs: core: Add ufshcd_send_bsg_uic_cmd() for UFS BSG
User layer applications can send UIC GET/SET commands via the BSG framework, and if the user layer application sends a UIC SET command to the PA_PWRMODE attribute, a power mode change shall be initiated in UniPro and two interrupts shall be triggered if the power mode is successfully changed, i.e., UIC Command Completion interrupt and UIC Power Mode interrupt. The current UFS BSG code calls ufshcd_send_uic_cmd() directly, with which the second interrupt, i.e., UIC Power Mode interrupt, shall be treated as unhandled interrupt. In addition, after the UIC command is completed, user layer application has to poll UniPro and/or M-PHY state machine to confirm the power mode change is finished. Add a new wrapper function ufshcd_send_bsg_uic_cmd() and call it from ufs_bsg_request() so that if a UIC SET command is targeting the PA_PWRMODE attribute it can be redirected to ufshcd_uic_pwr_ctrl(). Fixes: e77044c ("scsi: ufs-bsg: Add support for uic commands in ufs_bsg_request()") Co-developed-by: Can Guo <[email protected]> Signed-off-by: Can Guo <[email protected]> Signed-off-by: Ziqi Chen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Bean Huo <[email protected]> Reviewed-by: Avri Altman <[email protected]> Reviewed-by: Peter Wang <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 5cd3167 commit 60b4dd1

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

drivers/ufs/core/ufs_bsg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ static int ufs_bsg_request(struct bsg_job *job)
170170
break;
171171
case UPIU_TRANSACTION_UIC_CMD:
172172
memcpy(&uc, &bsg_request->upiu_req.uc, UIC_CMD_SIZE);
173-
ret = ufshcd_send_uic_cmd(hba, &uc);
173+
ret = ufshcd_send_bsg_uic_cmd(hba, &uc);
174174
if (ret)
175175
dev_err(hba->dev, "send uic cmd: error code %d\n", ret);
176176

drivers/ufs/core/ufshcd-priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
8484
u8 **buf, bool ascii);
8585

8686
int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
87+
int ufshcd_send_bsg_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
8788

8889
int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
8990
struct utp_upiu_req *req_upiu,

drivers/ufs/core/ufshcd.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4319,6 +4319,42 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
43194319
return ret;
43204320
}
43214321

4322+
/**
4323+
* ufshcd_send_bsg_uic_cmd - Send UIC commands requested via BSG layer and retrieve the result
4324+
* @hba: per adapter instance
4325+
* @uic_cmd: UIC command
4326+
*
4327+
* Return: 0 only if success.
4328+
*/
4329+
int ufshcd_send_bsg_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
4330+
{
4331+
int ret;
4332+
4333+
if (hba->quirks & UFSHCD_QUIRK_BROKEN_UIC_CMD)
4334+
return 0;
4335+
4336+
ufshcd_hold(hba);
4337+
4338+
if (uic_cmd->argument1 == UIC_ARG_MIB(PA_PWRMODE) &&
4339+
uic_cmd->command == UIC_CMD_DME_SET) {
4340+
ret = ufshcd_uic_pwr_ctrl(hba, uic_cmd);
4341+
goto out;
4342+
}
4343+
4344+
mutex_lock(&hba->uic_cmd_mutex);
4345+
ufshcd_add_delay_before_dme_cmd(hba);
4346+
4347+
ret = __ufshcd_send_uic_cmd(hba, uic_cmd);
4348+
if (!ret)
4349+
ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd);
4350+
4351+
mutex_unlock(&hba->uic_cmd_mutex);
4352+
4353+
out:
4354+
ufshcd_release(hba);
4355+
return ret;
4356+
}
4357+
43224358
/**
43234359
* ufshcd_uic_change_pwr_mode - Perform the UIC power mode chage
43244360
* using DME_SET primitives.

0 commit comments

Comments
 (0)