History

Merge patch series "scsi: ufs: Add support for the aggregated read query opcode"

Hyeoncheol Jeong <hyenc.jeong@samsung.com> says: UFS 5.0 / JEDEC 220H introduces the AGGREGATED READ query opcode (0x9), which retrieves an aggregated data packet bundling multiple Descriptors, Attributes and Flags in a single QUERY RESPONSE UPIU. Such a packet can be far larger than a single descriptor, so the reserved (device management) tag gets a dedicated UCD with an enlarged response area. Patch 1 is a preparatory cleanup that switches the BSG query descriptor length to unsigned types. Patch 2 adds the aggregated read support. v3: https://lore.kernel.org/linux-scsi/20260724030812epcms2p4eb2c77cb4dcd5fd51ca9c3eaa5ea4bfa@epcms2p4/ v2: https://lore.kernel.org/linux-scsi/20260722084819epcms2p49c27fce999e821385f7b5d7ea5a02868@epcms2p4/

Martin K. Petersen (Oracle) committed 3 months ago

Commit f574a022 parents 654fdae 8f5bbff6 files · +143 −48Browse files

Unified · Split

6 files
  1. drivers/ufs/core/ufs-mcq.c +10 −4
  2. drivers/ufs/core/ufs_bsg.c +21 −20
  3. drivers/ufs/core/ufshcd.c +74 −24
  4. include/ufs/ufs.h +6 −0
  5. include/ufs/ufshcd.h +20 −0
  6. include/ufs/ufshci.h +12 −0
drivers/ufs/core/ufs-mcq.c+10−4
@@ -296,14 +296,20 @@ static int ufshcd_mcq_get_tag(struct ufs_hba *hba, struct cq_entry *cqe) · 295 unmodified lines
296 if (hba->ufs_version >= ufshci_version(4, 1))296 if (hba->ufs_version >= ufshci_version(4, 1))
297 return cqe->task_tag;297 return cqe->task_tag;
298 298
299 /* sizeof(struct utp_transfer_cmd_desc) must be a multiple of 128 */299 /* Both UCD types must have a size that is a multiple of 128 bytes */
300 BUILD_BUG_ON(sizeof(struct utp_transfer_cmd_desc) & GENMASK(6, 0));300 BUILD_BUG_ON(sizeof(struct utp_transfer_cmd_desc) & GENMASK(6, 0));
301 BUILD_BUG_ON(sizeof(struct utp_devman_cmd_desc) & GENMASK(6, 0));
301 302
302 /* Bits 63:7 UCD base address, 6:5 are reserved, 4:0 is SQ ID */303 /* Bits 63:7 UCD base address, 6:5 are reserved, 4:0 is SQ ID */
303 addr = (le64_to_cpu(cqe->command_desc_base_addr) & CQE_UCD_BA) -304 addr = le64_to_cpu(cqe->command_desc_base_addr) & CQE_UCD_BA;
304 hba->ucdl_dma_addr;
305 305
306 return div_u64(addr, ufshcd_get_ucd_size(hba));306 /* The devman UCD is outside the pool; return its reserved tag. */
307 if (unlikely(addr == hba->devman_ucd_dma_addr))
308 return hba->dev_cmd.tag;
309
310 /* Pool entries follow the reserved tags. */
311 return div_u64(addr - hba->ucdl_dma_addr, ufshcd_get_ucd_size(hba)) +
312 UFSHCD_NUM_RESERVED;
307}313}
308 314
309static void ufshcd_mcq_process_cqe(struct ufs_hba *hba,315static void ufshcd_mcq_process_cqe(struct ufs_hba *hba,
drivers/ufs/core/ufs_bsg.c+21−20
@@ -13,37 +13,31 @@ · 12 unmodified lines
13#include <ufs/ufshcd.h>13#include <ufs/ufshcd.h>
14#include "ufshcd-priv.h"14#include "ufshcd-priv.h"
15 15
16static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, int *desc_len,
17 struct utp_upiu_query *qr)
18{
19 int desc_size = be16_to_cpu(qr->length);
20
21 if (desc_size <= 0)
22 return -EINVAL;
23
24 *desc_len = min_t(int, QUERY_DESC_MAX_SIZE, desc_size);
25
26 return 0;
27}
28
29static int ufs_bsg_alloc_desc_buffer(struct ufs_hba *hba, struct bsg_job *job,16static int ufs_bsg_alloc_desc_buffer(struct ufs_hba *hba, struct bsg_job *job,
30 uint8_t **desc_buff, int *desc_len,17 u8 **desc_buff, u16 *desc_len,
31 enum query_opcode desc_op)18 enum query_opcode desc_op)
32{19{
33 struct ufs_bsg_request *bsg_request = job->request;20 struct ufs_bsg_request *bsg_request = job->request;
34 struct utp_upiu_query *qr;21 struct utp_upiu_query *qr;
22 u16 max_desc_len;
35 u8 *descp;23 u8 *descp;
36 24
37 if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC &&25 if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC &&
38 desc_op != UPIU_QUERY_OPCODE_READ_DESC)26 desc_op != UPIU_QUERY_OPCODE_READ_DESC &&
27 desc_op != UPIU_QUERY_OPCODE_AGGREGATED_READ)
39 goto out;28 goto out;
40 29
41 qr = &bsg_request->upiu_req.qr;30 qr = &bsg_request->upiu_req.qr;
42 if (ufs_bsg_get_query_desc_size(hba, desc_len, qr)) {31 *desc_len = be16_to_cpu(qr->length);
32 if (*desc_len == 0) {
43 dev_err(hba->dev, "Illegal desc size\n");33 dev_err(hba->dev, "Illegal desc size\n");
44 return -EINVAL;34 return -EINVAL;
45 }35 }
46 36
37 max_desc_len = desc_op == UPIU_QUERY_OPCODE_AGGREGATED_READ ?
38 QUERY_AGGREGATED_MAX_SIZE : QUERY_DESC_MAX_SIZE;
39 *desc_len = min(*desc_len, max_desc_len);
40
47 if (*desc_len > job->request_payload.payload_len) {41 if (*desc_len > job->request_payload.payload_len) {
48 dev_err(hba->dev, "Illegal desc size\n");42 dev_err(hba->dev, "Illegal desc size\n");
49 return -EINVAL;43 return -EINVAL;
@@ -108,6 +102,9 @@ static int ufs_bsg_exec_advanced_rpmb_req(struct ufs_hba *hba, struct bsg_job *j · 58 unmodified lines
108 if (!payload->payload_len || !payload->sg_cnt)102 if (!payload->payload_len || !payload->sg_cnt)
109 return -EINVAL;103 return -EINVAL;
110 104
105 if (payload->sg_cnt > UFSHCD_DEVMAN_SG_ENTRIES)
106 return -EINVAL;
107
111 sg_cnt = dma_map_sg(hba->host->dma_dev, payload->sg_list, payload->sg_cnt, dir);108 sg_cnt = dma_map_sg(hba->host->dma_dev, payload->sg_list, payload->sg_cnt, dir);
112 if (unlikely(!sg_cnt))109 if (unlikely(!sg_cnt))
113 return -ENOMEM;110 return -ENOMEM;
@@ -136,8 +133,9 @@ static int ufs_bsg_request(struct bsg_job *job) · 22 unmodified lines
136 struct ufs_hba *hba = shost_priv(dev_to_shost(job->dev->parent));133 struct ufs_hba *hba = shost_priv(dev_to_shost(job->dev->parent));
137 struct uic_command uc = {};134 struct uic_command uc = {};
138 int msgcode;135 int msgcode;
139 uint8_t *buff = NULL;136 u8 *buff = NULL;
140 int desc_len = 0;137 u16 desc_len = 0;
138 int buff_len;
141 enum query_opcode desc_op = UPIU_QUERY_OPCODE_NOP;139 enum query_opcode desc_op = UPIU_QUERY_OPCODE_NOP;
142 int ret;140 int ret;
143 bool rpmb = false;141 bool rpmb = false;
@@ -156,12 +154,15 @@ static int ufs_bsg_request(struct bsg_job *job) · 12 unmodified lines
156 fallthrough;154 fallthrough;
157 case UPIU_TRANSACTION_NOP_OUT:155 case UPIU_TRANSACTION_NOP_OUT:
158 case UPIU_TRANSACTION_TASK_REQ:156 case UPIU_TRANSACTION_TASK_REQ:
157 buff_len = desc_len;
159 ret = ufshcd_exec_raw_upiu_cmd(hba, &bsg_request->upiu_req,158 ret = ufshcd_exec_raw_upiu_cmd(hba, &bsg_request->upiu_req,
160 &bsg_reply->upiu_rsp, msgcode,159 &bsg_reply->upiu_rsp, msgcode,
161 buff, &desc_len, desc_op);160 buff, &buff_len, desc_op);
161 desc_len = buff_len;
162 if (ret)162 if (ret)
163 dev_err(hba->dev, "exe raw upiu: error code %d\n", ret);163 dev_err(hba->dev, "exe raw upiu: error code %d\n", ret);
164 else if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len) {164 else if ((desc_op == UPIU_QUERY_OPCODE_READ_DESC ||
165 desc_op == UPIU_QUERY_OPCODE_AGGREGATED_READ) && desc_len) {
165 bsg_reply->reply_payload_rcv_len =166 bsg_reply->reply_payload_rcv_len =
166 sg_copy_from_buffer(job->request_payload.sg_list,167 sg_copy_from_buffer(job->request_payload.sg_list,
167 job->request_payload.sg_cnt,168 job->request_payload.sg_cnt,
drivers/ufs/core/ufshcd.c+74−24
@@ -2947,23 +2947,44 @@ static void ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct scsi_cmnd *cmd) · 2946 unmodified lines
2947static void ufshcd_init_lrb(struct ufs_hba *hba, struct scsi_cmnd *cmd)2947static void ufshcd_init_lrb(struct ufs_hba *hba, struct scsi_cmnd *cmd)
2948{2948{
2949 const int i = scsi_cmd_to_rq(cmd)->tag;2949 const int i = scsi_cmd_to_rq(cmd)->tag;
2950 struct utp_transfer_cmd_desc *cmd_descp =
2951 (void *)hba->ucdl_base_addr + i * ufshcd_get_ucd_size(hba);
2952 struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr;2950 struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr;
2953 dma_addr_t cmd_desc_element_addr =
2954 hba->ucdl_dma_addr + i * ufshcd_get_ucd_size(hba);
2955 u16 response_offset = le16_to_cpu(utrdlp[i].response_upiu_offset);2951 u16 response_offset = le16_to_cpu(utrdlp[i].response_upiu_offset);
2956 u16 prdt_offset = le16_to_cpu(utrdlp[i].prd_table_offset);2952 u16 prdt_offset = le16_to_cpu(utrdlp[i].prd_table_offset);
2957 struct ufshcd_lrb *lrb = scsi_cmd_priv(cmd);2953 struct ufshcd_lrb *lrb = scsi_cmd_priv(cmd);
2954 u8 *command_upiu, *response_upiu, *prd_table;
2955 dma_addr_t cmd_desc_element_addr;
2956
2957 /* The reserved tag uses a dedicated UCD outside the pool. */
2958 if (unlikely(blk_mq_is_reserved_rq(scsi_cmd_to_rq(cmd)))) {
2959 struct utp_devman_cmd_desc *cmd_descp = hba->devman_ucd_base_addr;
2960
2961 cmd_desc_element_addr = hba->devman_ucd_dma_addr;
2962 command_upiu = cmd_descp->command_upiu;
2963 response_upiu = cmd_descp->response_upiu;
2964 prd_table = cmd_descp->prd_table;
2965 } else {
2966 int slot = i - UFSHCD_NUM_RESERVED;
2967 struct utp_transfer_cmd_desc *cmd_descp;
2968
2969 /* Non-reserved tags start at UFSHCD_NUM_RESERVED, so slot >= 0. */
2970 WARN_ON_ONCE(slot < 0);
2971 cmd_descp = (void *)hba->ucdl_base_addr + slot * ufshcd_get_ucd_size(hba);
2972
2973 cmd_desc_element_addr =
2974 hba->ucdl_dma_addr + slot * ufshcd_get_ucd_size(hba);
2975 command_upiu = cmd_descp->command_upiu;
2976 response_upiu = cmd_descp->response_upiu;
2977 prd_table = cmd_descp->prd_table;
2978 }
2958 2979
2959 lrb->utr_descriptor_ptr = utrdlp + i;2980 lrb->utr_descriptor_ptr = utrdlp + i;
2960 lrb->utrd_dma_addr =2981 lrb->utrd_dma_addr =
2961 hba->utrdl_dma_addr + i * sizeof(struct utp_transfer_req_desc);2982 hba->utrdl_dma_addr + i * sizeof(struct utp_transfer_req_desc);
2962 lrb->ucd_req_ptr = (struct utp_upiu_req *)cmd_descp->command_upiu;2983 lrb->ucd_req_ptr = (struct utp_upiu_req *)command_upiu;
2963 lrb->ucd_req_dma_addr = cmd_desc_element_addr;2984 lrb->ucd_req_dma_addr = cmd_desc_element_addr;
2964 lrb->ucd_rsp_ptr = (struct utp_upiu_rsp *)cmd_descp->response_upiu;2985 lrb->ucd_rsp_ptr = (struct utp_upiu_rsp *)response_upiu;
2965 lrb->ucd_rsp_dma_addr = cmd_desc_element_addr + response_offset;2986 lrb->ucd_rsp_dma_addr = cmd_desc_element_addr + response_offset;
2966 lrb->ucd_prdt_ptr = (struct ufshcd_sg_entry *)cmd_descp->prd_table;2987 lrb->ucd_prdt_ptr = (struct ufshcd_sg_entry *)prd_table;
2967 lrb->ucd_prdt_dma_addr = cmd_desc_element_addr + prdt_offset;2988 lrb->ucd_prdt_dma_addr = cmd_desc_element_addr + prdt_offset;
2968}2989}
2969 2990
@@ -3160,6 +3181,7 @@ static void ufshcd_setup_dev_cmd(struct ufs_hba *hba, struct scsi_cmnd *cmd, · 190 unmodified lines
3160 __ufshcd_setup_cmd(hba, cmd, lun, tag);3181 __ufshcd_setup_cmd(hba, cmd, lun, tag);
3161 lrbp->intr_cmd = true; /* No interrupt aggregation */3182 lrbp->intr_cmd = true; /* No interrupt aggregation */
3162 hba->dev_cmd.type = cmd_type;3183 hba->dev_cmd.type = cmd_type;
3184 hba->dev_cmd.tag = tag;
3163}3185}
3164 3186
3165/*3187/*
@@ -4015,8 +4037,8 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) · 849 unmodified lines
4015{4037{
4016 size_t utmrdl_size, utrdl_size, ucdl_size;4038 size_t utmrdl_size, utrdl_size, ucdl_size;
4017 4039
4018 /* Allocate memory for UTP command descriptors */4040 /* The reserved tag uses the dedicated UCD below, not this pool. */
4019 ucdl_size = ufshcd_get_ucd_size(hba) * hba->nutrs;4041 ucdl_size = ufshcd_get_ucd_size(hba) * (hba->nutrs - UFSHCD_NUM_RESERVED);
4020 hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev,4042 hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev,
4021 ucdl_size,4043 ucdl_size,
4022 &hba->ucdl_dma_addr,4044 &hba->ucdl_dma_addr,
@@ -4032,6 +4054,21 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) · 9 unmodified lines
4032 goto out;4054 goto out;
4033 }4055 }
4034 4056
4057 /* Dedicated UCD for the reserved tag; allocate once (survives MCQ re-init). */
4058 if (!hba->devman_ucd_base_addr) {
4059 hba->devman_ucd_base_addr =
4060 dmam_alloc_coherent(hba->dev,
4061 ufshcd_get_devman_ucd_size(hba),
4062 &hba->devman_ucd_dma_addr,
4063 GFP_KERNEL);
4064 if (!hba->devman_ucd_base_addr ||
4065 WARN_ON(hba->devman_ucd_dma_addr & (128 - 1))) {
4066 dev_err(hba->dev,
4067 "Devman Command Descriptor Memory allocation failed\n");
4068 goto out;
4069 }
4070 }
4071
4035 /*4072 /*
4036 * Allocate memory for UTP Transfer descriptors4073 * Allocate memory for UTP Transfer descriptors
4037 * UFSHCI requires 1KB alignment of UTRD4074 * UFSHCI requires 1KB alignment of UTRD
@@ -4098,23 +4135,38 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) · 60 unmodified lines
4098 dma_addr_t cmd_desc_element_addr;4135 dma_addr_t cmd_desc_element_addr;
4099 u16 response_offset;4136 u16 response_offset;
4100 u16 prdt_offset;4137 u16 prdt_offset;
4138 u16 response_len;
4101 int cmd_desc_size;4139 int cmd_desc_size;
4102 int i;4140 int i;
4103 4141
4104 utrdlp = hba->utrdl_base_addr;4142 utrdlp = hba->utrdl_base_addr;
4105 4143
4106 response_offset =
4107 offsetof(struct utp_transfer_cmd_desc, response_upiu);
4108 prdt_offset =
4109 offsetof(struct utp_transfer_cmd_desc, prd_table);
4110
4111 cmd_desc_size = ufshcd_get_ucd_size(hba);4144 cmd_desc_size = ufshcd_get_ucd_size(hba);
4112 cmd_desc_dma_addr = hba->ucdl_dma_addr;4145 cmd_desc_dma_addr = hba->ucdl_dma_addr;
4113 4146
4114 for (i = 0; i < hba->nutrs; i++) {4147 for (i = 0; i < hba->nutrs; i++) {
4148 /*
4149 * Reserved tags (low end) use the dedicated devman UCD with a
4150 * larger response area; other tags index the pool at i - RESERVED.
4151 */
4152 if (i < UFSHCD_NUM_RESERVED) {
4153 cmd_desc_element_addr = hba->devman_ucd_dma_addr;
4154 response_offset = offsetof(struct utp_devman_cmd_desc,
4155 response_upiu);
4156 prdt_offset = offsetof(struct utp_devman_cmd_desc,
4157 prd_table);
4158 response_len = ALIGNED_DEVMAN_RSP_SIZE;
4159 } else {
4160 cmd_desc_element_addr = cmd_desc_dma_addr +
4161 cmd_desc_size * (i - UFSHCD_NUM_RESERVED);
4162 response_offset = offsetof(struct utp_transfer_cmd_desc,
4163 response_upiu);
4164 prdt_offset = offsetof(struct utp_transfer_cmd_desc,
4165 prd_table);
4166 response_len = ALIGNED_UPIU_SIZE;
4167 }
4168
4115 /* Configure UTRD with command descriptor base address */4169 /* Configure UTRD with command descriptor base address */
4116 cmd_desc_element_addr =
4117 (cmd_desc_dma_addr + (cmd_desc_size * i));
4118 utrdlp[i].command_desc_base_addr =4170 utrdlp[i].command_desc_base_addr =
4119 cpu_to_le64(cmd_desc_element_addr);4171 cpu_to_le64(cmd_desc_element_addr);
4120 4172
@@ -4125,14 +4177,14 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) · 4 unmodified lines
4125 utrdlp[i].prd_table_offset =4177 utrdlp[i].prd_table_offset =
4126 cpu_to_le16(prdt_offset);4178 cpu_to_le16(prdt_offset);
4127 utrdlp[i].response_upiu_length =4179 utrdlp[i].response_upiu_length =
4128 cpu_to_le16(ALIGNED_UPIU_SIZE);4180 cpu_to_le16(response_len);
4129 } else {4181 } else {
4130 utrdlp[i].response_upiu_offset =4182 utrdlp[i].response_upiu_offset =
4131 cpu_to_le16(response_offset >> 2);4183 cpu_to_le16(response_offset >> 2);
4132 utrdlp[i].prd_table_offset =4184 utrdlp[i].prd_table_offset =
4133 cpu_to_le16(prdt_offset >> 2);4185 cpu_to_le16(prdt_offset >> 2);
4134 utrdlp[i].response_upiu_length =4186 utrdlp[i].response_upiu_length =
4135 cpu_to_le16(ALIGNED_UPIU_SIZE >> 2);4187 cpu_to_le16(response_len >> 2);
4136 }4188 }
4137 }4189 }
4138}4190}
@@ -7657,7 +7709,8 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, · 3518 unmodified lines
7657 7709
7658 /* just copy the upiu response as it is */7710 /* just copy the upiu response as it is */
7659 memcpy(rsp_upiu, lrbp->ucd_rsp_ptr, sizeof(*rsp_upiu));7711 memcpy(rsp_upiu, lrbp->ucd_rsp_ptr, sizeof(*rsp_upiu));
7660 if (desc_buff && desc_op == UPIU_QUERY_OPCODE_READ_DESC) {7712 if (desc_buff && (desc_op == UPIU_QUERY_OPCODE_READ_DESC ||
7713 desc_op == UPIU_QUERY_OPCODE_AGGREGATED_READ)) {
7661 u8 *descp = (u8 *)lrbp->ucd_rsp_ptr + sizeof(*rsp_upiu);7714 u8 *descp = (u8 *)lrbp->ucd_rsp_ptr + sizeof(*rsp_upiu);
7662 u16 resp_len = be16_to_cpu(lrbp->ucd_rsp_ptr->header7715 u16 resp_len = be16_to_cpu(lrbp->ucd_rsp_ptr->header
7663 .data_segment_length);7716 .data_segment_length);
@@ -7829,10 +7882,7 @@ int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *r · 165 unmodified lines
7829 * Message is 02h7882 * Message is 02h
7830 */7883 */
7831 if (ehs_len == 2 && rsp_ehs) {7884 if (ehs_len == 2 && rsp_ehs) {
7832 /*7885 /* EHS data starts from byte32 of the devman UCD response area. */
7833 * ucd_rsp_ptr points to a buffer with a length of 512 bytes
7834 * (ALIGNED_UPIU_SIZE = 512), and the EHS data just starts from byte32
7835 */
7836 ehs_data = (u8 *)lrbp->ucd_rsp_ptr + EHS_OFFSET_IN_RESPONSE;7886 ehs_data = (u8 *)lrbp->ucd_rsp_ptr + EHS_OFFSET_IN_RESPONSE;
7837 memcpy(rsp_ehs, ehs_data, ehs_len * 32);7887 memcpy(rsp_ehs, ehs_data, ehs_len * 32);
7838 }7888 }
@@ -9256,7 +9306,7 @@ static void ufshcd_release_sdb_queue(struct ufs_hba *hba, int nutrs) · 1417 unmodified lines
9256{9306{
9257 size_t ucdl_size, utrdl_size;9307 size_t ucdl_size, utrdl_size;
9258 9308
9259 ucdl_size = ufshcd_get_ucd_size(hba) * nutrs;9309 ucdl_size = ufshcd_get_ucd_size(hba) * (nutrs - UFSHCD_NUM_RESERVED);
9260 dmam_free_coherent(hba->dev, ucdl_size, hba->ucdl_base_addr,9310 dmam_free_coherent(hba->dev, ucdl_size, hba->ucdl_base_addr,
9261 hba->ucdl_dma_addr);9311 hba->ucdl_dma_addr);
9262 9312
include/ufs/ufs.h+6−0
@@ -25,6 +25,11 @@ static_assert(sizeof(struct utp_upiu_query) == 20); · 24 unmodified lines
25 25
26#define GENERAL_UPIU_REQUEST_SIZE (sizeof(struct utp_upiu_req))26#define GENERAL_UPIU_REQUEST_SIZE (sizeof(struct utp_upiu_req))
27#define QUERY_DESC_MAX_SIZE 25527#define QUERY_DESC_MAX_SIZE 255
28/*
29 * Max aggregated read data segment: the devman response area
30 * (ALIGNED_DEVMAN_RSP_SIZE) minus the fixed UPIU header it follows.
31 */
32#define QUERY_AGGREGATED_MAX_SIZE (4096 - GENERAL_UPIU_REQUEST_SIZE)
28#define QUERY_DESC_MIN_SIZE 233#define QUERY_DESC_MIN_SIZE 2
29#define QUERY_DESC_HDR_SIZE 234#define QUERY_DESC_HDR_SIZE 2
30#define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \35#define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \
@@ -464,6 +469,7 @@ enum query_opcode { · 433 unmodified lines
464 UPIU_QUERY_OPCODE_SET_FLAG = 0x6,469 UPIU_QUERY_OPCODE_SET_FLAG = 0x6,
465 UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7,470 UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7,
466 UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8,471 UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8,
472 UPIU_QUERY_OPCODE_AGGREGATED_READ = 0x9,
467};473};
468 474
469/* bRefClkFreq attribute values */475/* bRefClkFreq attribute values */
include/ufs/ufshcd.h+20−0
@@ -235,11 +235,13 @@ struct ufs_query { · 234 unmodified lines
235 * @type: device management command type - Query, NOP OUT235 * @type: device management command type - Query, NOP OUT
236 * @lock: lock to allow one command at a time236 * @lock: lock to allow one command at a time
237 * @query: Device management query information237 * @query: Device management query information
238 * @tag: tag of the reserved request in use
238 */239 */
239struct ufs_dev_cmd {240struct ufs_dev_cmd {
240 enum dev_cmd_type type;241 enum dev_cmd_type type;
241 struct mutex lock;242 struct mutex lock;
242 struct ufs_query query;243 struct ufs_query query;
244 u8 tag;
243};245};
244 246
245/**247/**
@@ -954,9 +956,13 @@ enum ufshcd_mcq_opr { · 708 unmodified lines
954 * @ucdl_base_addr: UFS Command Descriptor base address956 * @ucdl_base_addr: UFS Command Descriptor base address
955 * @utrdl_base_addr: UTP Transfer Request Descriptor base address957 * @utrdl_base_addr: UTP Transfer Request Descriptor base address
956 * @utmrdl_base_addr: UTP Task Management Descriptor base address958 * @utmrdl_base_addr: UTP Task Management Descriptor base address
959 * @devman_ucd_base_addr: UFS Command Descriptor base address for the reserved
960 * device management tag (has a larger response area)
957 * @ucdl_dma_addr: UFS Command Descriptor DMA address961 * @ucdl_dma_addr: UFS Command Descriptor DMA address
958 * @utrdl_dma_addr: UTRDL DMA address962 * @utrdl_dma_addr: UTRDL DMA address
959 * @utmrdl_dma_addr: UTMRDL DMA address963 * @utmrdl_dma_addr: UTMRDL DMA address
964 * @devman_ucd_dma_addr: UFS Command Descriptor DMA address for the reserved
965 * device management tag
960 * @host: Scsi_Host instance of the driver966 * @host: Scsi_Host instance of the driver
961 * @dev: device handle967 * @dev: device handle
962 * @ufs_device_wlun: WLUN that controls the entire UFS device.968 * @ufs_device_wlun: WLUN that controls the entire UFS device.
@@ -1098,11 +1104,13 @@ struct ufs_hba { · 135 unmodified lines
1098 struct utp_transfer_cmd_desc *ucdl_base_addr;1104 struct utp_transfer_cmd_desc *ucdl_base_addr;
1099 struct utp_transfer_req_desc *utrdl_base_addr;1105 struct utp_transfer_req_desc *utrdl_base_addr;
1100 struct utp_task_req_desc *utmrdl_base_addr;1106 struct utp_task_req_desc *utmrdl_base_addr;
1107 struct utp_devman_cmd_desc *devman_ucd_base_addr;
1101 1108
1102 /* DMA memory reference */1109 /* DMA memory reference */
1103 dma_addr_t ucdl_dma_addr;1110 dma_addr_t ucdl_dma_addr;
1104 dma_addr_t utrdl_dma_addr;1111 dma_addr_t utrdl_dma_addr;
1105 dma_addr_t utmrdl_dma_addr;1112 dma_addr_t utmrdl_dma_addr;
1113 dma_addr_t devman_ucd_dma_addr;
1106 1114
1107 struct Scsi_Host *host;1115 struct Scsi_Host *host;
1108 struct device *dev;1116 struct device *dev;
@@ -1361,6 +1369,18 @@ static inline size_t ufshcd_get_ucd_size(const struct ufs_hba *hba) · 252 unmodified lines
1361 return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba);1369 return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba);
1362}1370}
1363 1371
1372/*
1373 * Two entries should be enough for the largest devman PRDT transfer (4 KiB),
1374 * like advanced RPMB.
1375 */
1376#define UFSHCD_DEVMAN_SG_ENTRIES 2
1377
1378static inline size_t ufshcd_get_devman_ucd_size(const struct ufs_hba *hba)
1379{
1380 return sizeof(struct utp_devman_cmd_desc) +
1381 UFSHCD_DEVMAN_SG_ENTRIES * ufshcd_sg_entry_size(hba);
1382}
1383
1364/* Returns true if clocks can be gated. Otherwise false */1384/* Returns true if clocks can be gated. Otherwise false */
1365static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba)1385static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba)
1366{1386{
include/ufs/ufshci.h+12−0
@@ -18,6 +18,8 @@ enum { · 17 unmodified lines
18 TASK_REQ_UPIU_SIZE_DWORDS = 8,18 TASK_REQ_UPIU_SIZE_DWORDS = 8,
19 TASK_RSP_UPIU_SIZE_DWORDS = 8,19 TASK_RSP_UPIU_SIZE_DWORDS = 8,
20 ALIGNED_UPIU_SIZE = 512,20 ALIGNED_UPIU_SIZE = 512,
21 /* Larger response area, only for the devman UCD */
22 ALIGNED_DEVMAN_RSP_SIZE = 4096,
21};23};
22 24
23/* UFSHCI Registers */25/* UFSHCI Registers */
@@ -501,6 +503,16 @@ struct utp_transfer_cmd_desc { · 477 unmodified lines
501 u8 prd_table[];503 u8 prd_table[];
502};504};
503 505
506/* Dedicated UCD for the devman/reserved slot */
507struct utp_devman_cmd_desc {
508 u8 command_upiu[ALIGNED_UPIU_SIZE];
509 u8 response_upiu[ALIGNED_DEVMAN_RSP_SIZE];
510 u8 prd_table[];
511};
512
513static_assert(sizeof(struct utp_upiu_req) + QUERY_AGGREGATED_MAX_SIZE <=
514 ALIGNED_DEVMAN_RSP_SIZE);
515
504/**516/**
505 * struct request_desc_header - Descriptor Header common to both UTRD and UTMRD517 * struct request_desc_header - Descriptor Header common to both UTRD and UTMRD
506 */518 */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t