mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
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: 09d9e4d041
("scsi: ufs: ufshpb: Remove HPB2.0 flows")
Link: https://lore.kernel.org/r/20211031123654.17719-1-avri.altman@wdc.com
Reviewed-by: Daejun Park <daejun7.park@samsung.com>
Signed-off-by: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
6266f7df38
commit
9ec5128a8b
@ -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
|
||||
@ -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 ?
|
||||
@ -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];
|
||||
|
||||
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user