Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit c30d8d0

Browse files
Asutosh Dasmartinkpetersen
authored andcommitted
scsi: ufs: core: Prepare for completion in MCQ
Modify completion path APIs and add completion queue entry. Co-developed-by: Can Guo <[email protected]> Signed-off-by: Can Guo <[email protected]> Signed-off-by: Asutosh Das <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Stanley Chu <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 854f84e commit c30d8d0

File tree

2 files changed

+51
-31
lines changed

2 files changed

+51
-31
lines changed

drivers/ufs/core/ufshcd-priv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
6161
int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
6262
enum flag_idn idn, u8 index, bool *flag_res);
6363
void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit);
64+
void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
65+
struct cq_entry *cqe);
6466
int ufshcd_mcq_init(struct ufs_hba *hba);
6567
int ufshcd_mcq_decide_queue_depth(struct ufs_hba *hba);
6668
int ufshcd_mcq_memory_alloc(struct ufs_hba *hba);

drivers/ufs/core/ufshcd.c

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -776,12 +776,17 @@ static inline bool ufshcd_is_device_present(struct ufs_hba *hba)
776776
/**
777777
* ufshcd_get_tr_ocs - Get the UTRD Overall Command Status
778778
* @lrbp: pointer to local command reference block
779+
* @cqe: pointer to the completion queue entry
779780
*
780781
* This function is used to get the OCS field from UTRD
781782
* Returns the OCS field in the UTRD
782783
*/
783-
static enum utp_ocs ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp)
784+
static enum utp_ocs ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp,
785+
struct cq_entry *cqe)
784786
{
787+
if (cqe)
788+
return le32_to_cpu(cqe->status) & MASK_OCS;
789+
785790
return le32_to_cpu(lrbp->utr_descriptor_ptr->header.dword_2) & MASK_OCS;
786791
}
787792

@@ -3068,7 +3073,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
30683073
* not trigger any race conditions.
30693074
*/
30703075
hba->dev_cmd.complete = NULL;
3071-
err = ufshcd_get_tr_ocs(lrbp);
3076+
err = ufshcd_get_tr_ocs(lrbp, hba->dev_cmd.cqe);
30723077
if (!err)
30733078
err = ufshcd_dev_cmd_completion(hba, lrbp);
30743079
} else {
@@ -5202,18 +5207,20 @@ ufshcd_scsi_cmd_status(struct ufshcd_lrb *lrbp, int scsi_status)
52025207
* ufshcd_transfer_rsp_status - Get overall status of the response
52035208
* @hba: per adapter instance
52045209
* @lrbp: pointer to local reference block of completed command
5210+
* @cqe: pointer to the completion queue entry
52055211
*
52065212
* Returns result of the command to notify SCSI midlayer
52075213
*/
52085214
static inline int
5209-
ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
5215+
ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
5216+
struct cq_entry *cqe)
52105217
{
52115218
int result = 0;
52125219
int scsi_status;
52135220
enum utp_ocs ocs;
52145221

52155222
/* overall command status of utrd */
5216-
ocs = ufshcd_get_tr_ocs(lrbp);
5223+
ocs = ufshcd_get_tr_ocs(lrbp, cqe);
52175224

52185225
if (hba->quirks & UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR) {
52195226
if (be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_1) &
@@ -5378,42 +5385,53 @@ static void ufshcd_release_scsi_cmd(struct ufs_hba *hba,
53785385
}
53795386

53805387
/**
5381-
* __ufshcd_transfer_req_compl - handle SCSI and query command completion
5388+
* ufshcd_compl_one_cqe - handle a completion queue entry
53825389
* @hba: per adapter instance
5383-
* @completed_reqs: bitmask that indicates which requests to complete
5390+
* @task_tag: the task tag of the request to be completed
5391+
* @cqe: pointer to the completion queue entry
53845392
*/
5385-
static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
5386-
unsigned long completed_reqs)
5393+
void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
5394+
struct cq_entry *cqe)
53875395
{
53885396
struct ufshcd_lrb *lrbp;
53895397
struct scsi_cmnd *cmd;
5390-
int index;
5391-
5392-
for_each_set_bit(index, &completed_reqs, hba->nutrs) {
5393-
lrbp = &hba->lrb[index];
5394-
lrbp->compl_time_stamp = ktime_get();
5395-
lrbp->compl_time_stamp_local_clock = local_clock();
5396-
cmd = lrbp->cmd;
5397-
if (cmd) {
5398-
if (unlikely(ufshcd_should_inform_monitor(hba, lrbp)))
5399-
ufshcd_update_monitor(hba, lrbp);
5400-
ufshcd_add_command_trace(hba, index, UFS_CMD_COMP);
5401-
cmd->result = ufshcd_transfer_rsp_status(hba, lrbp);
5402-
ufshcd_release_scsi_cmd(hba, lrbp);
5403-
/* Do not touch lrbp after scsi done */
5404-
scsi_done(cmd);
5405-
} else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE ||
5406-
lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) {
5407-
if (hba->dev_cmd.complete) {
5408-
ufshcd_add_command_trace(hba, index,
5409-
UFS_DEV_COMP);
5410-
complete(hba->dev_cmd.complete);
5411-
ufshcd_clk_scaling_update_busy(hba);
5412-
}
5398+
5399+
lrbp = &hba->lrb[task_tag];
5400+
lrbp->compl_time_stamp = ktime_get();
5401+
cmd = lrbp->cmd;
5402+
if (cmd) {
5403+
if (unlikely(ufshcd_should_inform_monitor(hba, lrbp)))
5404+
ufshcd_update_monitor(hba, lrbp);
5405+
ufshcd_add_command_trace(hba, task_tag, UFS_CMD_COMP);
5406+
cmd->result = ufshcd_transfer_rsp_status(hba, lrbp, cqe);
5407+
ufshcd_release_scsi_cmd(hba, lrbp);
5408+
/* Do not touch lrbp after scsi done */
5409+
scsi_done(cmd);
5410+
} else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE ||
5411+
lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) {
5412+
if (hba->dev_cmd.complete) {
5413+
hba->dev_cmd.cqe = cqe;
5414+
ufshcd_add_command_trace(hba, task_tag, UFS_DEV_COMP);
5415+
complete(hba->dev_cmd.complete);
5416+
ufshcd_clk_scaling_update_busy(hba);
54135417
}
54145418
}
54155419
}
54165420

5421+
/**
5422+
* __ufshcd_transfer_req_compl - handle SCSI and query command completion
5423+
* @hba: per adapter instance
5424+
* @completed_reqs: bitmask that indicates which requests to complete
5425+
*/
5426+
static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
5427+
unsigned long completed_reqs)
5428+
{
5429+
int tag;
5430+
5431+
for_each_set_bit(tag, &completed_reqs, hba->nutrs)
5432+
ufshcd_compl_one_cqe(hba, tag, NULL);
5433+
}
5434+
54175435
/* Any value that is not an existing queue number is fine for this constant. */
54185436
enum {
54195437
UFSHCD_POLL_FROM_INTERRUPT_CONTEXT = -1

0 commit comments

Comments
 (0)