Skip to content

Commit

Permalink
scsi: ufs: ufshpb: Properly handle max-single-cmd
Browse files Browse the repository at this point in the history
The spec recommends that for transfer length larger than the max-single-cmd
attribute (bMAX_DATA_SIZE_FOR_HPB_SINGLE_CMD) it is possible to couple
pre-requests with the HPB-READ command.  Being a recommendation, using
pre-requests can be perceived merely as a means of optimization.  A common
practice was to send pre-requests for chunks within some interval, and
leave the READ10 untouched if larger.

Now that the pre-request flows have been removed, all the commands are
single commands.  Properly handle this attribute and do not send HPB-READ
for transfer lengths larger than max-single-cmd.

[mkp: resolve conflict]

Fixes: 09d9e4d ("scsi: ufs: ufshpb: Remove HPB2.0 flows")
Link: https://lore.kernel.org/r/[email protected]
Reviewed-by: Daejun Park <[email protected]>
Signed-off-by: Avri Altman <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
  • Loading branch information
avri-altman-wdc authored and martinkpetersen committed Nov 4, 2021
1 parent 6266f7d commit 9ec5128
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 12 deletions.
24 changes: 13 additions & 11 deletions drivers/scsi/ufs/ufshpb.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,6 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
if (!ufshpb_is_supported_chunk(hpb, transfer_len))
return 0;

WARN_ON_ONCE(transfer_len > HPB_MULTI_CHUNK_HIGH);

if (hpb->is_hcm) {
/*
* in host control mode, reads are the main source for
Expand Down Expand Up @@ -1572,7 +1570,7 @@ static void ufshpb_lu_parameter_init(struct ufs_hba *hba,
if (ufshpb_is_legacy(hba))
hpb->pre_req_max_tr_len = HPB_LEGACY_CHUNK_HIGH;
else
hpb->pre_req_max_tr_len = HPB_MULTI_CHUNK_HIGH;
hpb->pre_req_max_tr_len = hpb_dev_info->max_hpb_single_cmd;

hpb->lu_pinned_start = hpb_lu_info->pinned_start;
hpb->lu_pinned_end = hpb_lu_info->num_pinned ?
Expand Down Expand Up @@ -2582,7 +2580,7 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf)
{
struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev;
int version, ret;
u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW;
int max_single_cmd;

hpb_dev_info->control_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL];

Expand All @@ -2598,18 +2596,22 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf)
if (version == HPB_SUPPORT_LEGACY_VERSION)
hpb_dev_info->is_legacy = true;

ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd);
if (ret)
dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed",
__func__);
hpb_dev_info->max_hpb_single_cmd = max_hpb_single_cmd;

/*
* Get the number of user logical unit to check whether all
* scsi_device finish initialization
*/
hpb_dev_info->num_lu = desc_buf[DEVICE_DESC_PARAM_NUM_LU];

if (hpb_dev_info->is_legacy)
return;

ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_single_cmd);

if (ret)
hpb_dev_info->max_hpb_single_cmd = HPB_LEGACY_CHUNK_HIGH;
else
hpb_dev_info->max_hpb_single_cmd = min(max_single_cmd + 1, HPB_MULTI_CHUNK_HIGH);
}

void ufshpb_init(struct ufs_hba *hba)
Expand Down
1 change: 0 additions & 1 deletion drivers/scsi/ufs/ufshpb.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

/* hpb support chunk size */
#define HPB_LEGACY_CHUNK_HIGH 1
#define HPB_MULTI_CHUNK_LOW 7
#define HPB_MULTI_CHUNK_HIGH 255

/* hpb vender defined opcode */
Expand Down

0 comments on commit 9ec5128

Please sign in to comment.