Hi Jared On 8/28/2025 12:20 AM, Jared McArthur wrote: > Some UFS attributes must be set before a UFS device is initialized. > Add ufshcd_query_attr and ufshcd_query_attr_retry to send UFS > attribute requests. > > Taken from Linux Kernel v6.17 (drivers/ufs/core/ufshcd.c) and ported > to U-Boot. > > Signed-off-by: Jared McArthur <[email protected]> > --- > drivers/ufs/ufs.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 95 insertions(+) > > diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c > index 91f6ad3bfef..9e67dd86232 100644 > --- a/drivers/ufs/ufs.c > +++ b/drivers/ufs/ufs.c > @@ -1107,6 +1107,101 @@ static int ufshcd_query_flag_retry(struct ufs_hba > *hba, > return ret; > } > > +/** > + * ufshcd_query_attr - API function for sending attribute requests > + * @hba: per-adapter instance > + * @opcode: attribute opcode > + * @idn: attribute idn to access > + * @index: index field > + * @selector: selector field > + * @attr_val: the attribute value after the query request completes > + * > + * Return: 0 for success, non-zero in case of failure. > + */ > +int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, > + enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) > +{ > + struct ufs_query_req *request = NULL; > + struct ufs_query_res *response = NULL; > + int err; > + > + if (!attr_val) { > + dev_err(hba->dev, > + "%s: attribute value required for opcode 0x%x\n", > + __func__, opcode); > + return -EINVAL; > + } > + > + ufshcd_init_query(hba, &request, &response, opcode, idn, index, > selector); > + > + switch (opcode) { > + case UPIU_QUERY_OPCODE_WRITE_ATTR: > + request->query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST; > + request->upiu_req.value = cpu_to_be32(*attr_val); > + break; > + case UPIU_QUERY_OPCODE_READ_ATTR: > + request->query_func = UPIU_QUERY_FUNC_STANDARD_READ_REQUEST; > + break; > + default: > + dev_err(hba->dev, > + "%s: Expected query attr opcode but got = 0x%.2x\n", > + __func__, opcode); > + err = -EINVAL; > + goto out; > + } > + > + err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, QUERY_REQ_TIMEOUT); > + > + if (err) { > + dev_err(hba->dev, > + "%s: opcode 0x%.2x for idn %d failed, index %d, err = > %d\n", > + __func__, opcode, idn, index, err); > + goto out; > + } > + > + *attr_val = be32_to_cpu(response->upiu_res.value); > + > +out: > + return err; > +} > + > +/** > + * ufshcd_query_attr_retry() - API function for sending query > + * attribute with retries > + * @hba: per-adapter instance > + * @opcode: attribute opcode > + * @idn: attribute idn to access > + * @index: index field > + * @selector: selector field > + * @attr_val: the attribute value after the query request > + * completes > + * > + * Return: 0 for success, non-zero in case of failure. > + */ > +int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode, > + enum attr_idn idn, u8 index, u8 selector, > + u32 *attr_val) > +{ > + int ret = 0; > + u32 retries; > + > + for (retries = QUERY_REQ_RETRIES; retries > 0; retries--) { > + ret = ufshcd_query_attr(hba, opcode, idn, index, selector, > attr_val); > + if (ret) > + dev_dbg(hba->dev, > + "%s: failed with error %d, retries %d\n", > + __func__, ret, retries); > + else > + break; > + } > + > + if (ret) > + dev_err(hba->dev, > + "%s: query attribute, idn %d, failed with error %d > after %d retries\n", > + __func__, idn, ret, QUERY_REQ_RETRIES); > + return ret; > +} > + > static int __ufshcd_query_descriptor(struct ufs_hba *hba, > enum query_opcode opcode, > enum desc_idn idn, u8 index, u8 selector,
Reviewed-by: Neha Malcom Francis <[email protected]> -- Thanking You Neha Malcom Francis

