@@ -5598,6 +5598,7 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag)
}
static void ufshcd_fill_tm_req(struct utp_task_req_desc *task_req_descp,
+ struct utp_upiu_task_req *raw_task_req_upiup,
int lun_id, int task_id, u8 tm_function,
int task_tag)
{
@@ -5608,6 +5609,13 @@ static void ufshcd_fill_tm_req(struct utp_task_req_desc *task_req_descp,
task_req_descp->header.dword_2 =
cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
+ if (raw_task_req_upiup) {
+ raw_task_req_upiup->header.dword_0 |= cpu_to_be32(task_tag);
+ memcpy(task_req_descp->task_req_upiu, raw_task_req_upiup,
+ GENERAL_UPIU_REQUEST_SIZE);
+ return;
+ }
+
task_req_upiup =
(struct utp_upiu_task_req *)task_req_descp->task_req_upiu;
task_req_upiup->header.dword_0 =
@@ -5633,8 +5641,11 @@ static void ufshcd_fill_tm_req(struct utp_task_req_desc *task_req_descp,
*
* Returns non-zero value on error, zero on success.
*/
-static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
- u8 tm_function, u8 *tm_response)
+static int ufshcd_issue_tm_cmd(struct ufs_hba *hba,
+ struct utp_upiu_task_req *raw_task_req_upiup,
+ struct utp_upiu_task_req *raw_task_rsp_upiup,
+ int lun_id, int task_id, u8 tm_function,
+ u8 *tm_response)
{
struct utp_task_req_desc *task_req_descp;
struct Scsi_Host *host;
@@ -5658,8 +5669,8 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
task_req_descp += free_slot;
task_tag = hba->nutrs + free_slot;
- ufshcd_fill_tm_req(task_req_descp, lun_id, task_id, tm_function,
- task_tag);
+ ufshcd_fill_tm_req(task_req_descp, raw_task_req_upiup, lun_id, task_id,
+ tm_function, task_tag);
ufshcd_vops_setup_task_mgmt(hba, free_slot, tm_function);
@@ -5691,6 +5702,10 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
err = -ETIMEDOUT;
} else {
err = ufshcd_task_req_compl(hba, free_slot, tm_response);
+ if (raw_task_rsp_upiup)
+ memcpy(raw_task_rsp_upiup,
+ task_req_descp->task_rsp_upiu,
+ GENERAL_UPIU_REQUEST_SIZE);
ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete");
}
@@ -5725,7 +5740,8 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
tag = cmd->request->tag;
lrbp = &hba->lrb[tag];
- err = ufshcd_issue_tm_cmd(hba, lrbp->lun, 0, UFS_LOGICAL_RESET, &resp);
+ err = ufshcd_issue_tm_cmd(hba, NULL, NULL, lrbp->lun, 0,
+ UFS_LOGICAL_RESET, &resp);
if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
if (!err)
err = resp;
@@ -5855,8 +5871,9 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
}
for (poll_cnt = 100; poll_cnt; poll_cnt--) {
- err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag,
- UFS_QUERY_TASK, &resp);
+ err = ufshcd_issue_tm_cmd(hba, NULL, NULL, lrbp->lun,
+ lrbp->task_tag, UFS_QUERY_TASK,
+ &resp);
if (!err && resp == UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED) {
/* cmd pending in the device */
dev_err(hba->dev, "%s: cmd pending in the device. tag = %d\n",
@@ -5894,8 +5911,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
goto out;
}
- err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag,
- UFS_ABORT_TASK, &resp);
+ err = ufshcd_issue_tm_cmd(hba, NULL, NULL, lrbp->lun, lrbp->task_tag,
+ UFS_ABORT_TASK, &resp);
if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
if (!err) {
err = resp; /* service response error */
Do that in order to re-use its code if the task request and response UPIUs are given externally. Signed-off-by: Avri Altman <avri.altman@wdc.com> --- drivers/scsi/ufs/ufshcd.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-)