Skip to content

Commit 9ec5128

Browse files
avri-altman-sndkmartinkpetersen
authored andcommitted
scsi: ufs: ufshpb: Properly handle max-single-cmd
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]>
1 parent 6266f7d commit 9ec5128

File tree

2 files changed

+13
-12
lines changed

2 files changed

+13
-12
lines changed

drivers/scsi/ufs/ufshpb.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,6 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
394394
if (!ufshpb_is_supported_chunk(hpb, transfer_len))
395395
return 0;
396396

397-
WARN_ON_ONCE(transfer_len > HPB_MULTI_CHUNK_HIGH);
398-
399397
if (hpb->is_hcm) {
400398
/*
401399
* in host control mode, reads are the main source for
@@ -1572,7 +1570,7 @@ static void ufshpb_lu_parameter_init(struct ufs_hba *hba,
15721570
if (ufshpb_is_legacy(hba))
15731571
hpb->pre_req_max_tr_len = HPB_LEGACY_CHUNK_HIGH;
15741572
else
1575-
hpb->pre_req_max_tr_len = HPB_MULTI_CHUNK_HIGH;
1573+
hpb->pre_req_max_tr_len = hpb_dev_info->max_hpb_single_cmd;
15761574

15771575
hpb->lu_pinned_start = hpb_lu_info->pinned_start;
15781576
hpb->lu_pinned_end = hpb_lu_info->num_pinned ?
@@ -2582,7 +2580,7 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf)
25822580
{
25832581
struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev;
25842582
int version, ret;
2585-
u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW;
2583+
int max_single_cmd;
25862584

25872585
hpb_dev_info->control_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL];
25882586

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

2601-
ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
2602-
QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd);
2603-
if (ret)
2604-
dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed",
2605-
__func__);
2606-
hpb_dev_info->max_hpb_single_cmd = max_hpb_single_cmd;
2607-
26082599
/*
26092600
* Get the number of user logical unit to check whether all
26102601
* scsi_device finish initialization
26112602
*/
26122603
hpb_dev_info->num_lu = desc_buf[DEVICE_DESC_PARAM_NUM_LU];
2604+
2605+
if (hpb_dev_info->is_legacy)
2606+
return;
2607+
2608+
ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
2609+
QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_single_cmd);
2610+
2611+
if (ret)
2612+
hpb_dev_info->max_hpb_single_cmd = HPB_LEGACY_CHUNK_HIGH;
2613+
else
2614+
hpb_dev_info->max_hpb_single_cmd = min(max_single_cmd + 1, HPB_MULTI_CHUNK_HIGH);
26132615
}
26142616

26152617
void ufshpb_init(struct ufs_hba *hba)

drivers/scsi/ufs/ufshpb.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131

3232
/* hpb support chunk size */
3333
#define HPB_LEGACY_CHUNK_HIGH 1
34-
#define HPB_MULTI_CHUNK_LOW 7
3534
#define HPB_MULTI_CHUNK_HIGH 255
3635

3736
/* hpb vender defined opcode */

0 commit comments

Comments
 (0)