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/
Showing the changes to include (3 of 6 files). Show all
Unified · Split
| @@ -25,6 +25,11 @@ static_assert(sizeof(struct utp_upiu_query) == 20); · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #define GENERAL_UPIU_REQUEST_SIZE (sizeof(struct utp_upiu_req)) |
| 27 | 27 | #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 | 33 | #define QUERY_DESC_MIN_SIZE 2 |
| 29 | 34 | #define QUERY_DESC_HDR_SIZE 2 |
| 30 | 35 | #define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \ |
| @@ -464,6 +469,7 @@ enum query_opcode { · 433 unmodified lines | ||
| 464 | 469 | UPIU_QUERY_OPCODE_SET_FLAG = 0x6, |
| 465 | 470 | UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7, |
| 466 | 471 | UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8, |
| 472 | + UPIU_QUERY_OPCODE_AGGREGATED_READ = 0x9, | |
| 467 | 473 | }; |
| 468 | 474 | |
| 469 | 475 | /* bRefClkFreq attribute values */ |
| @@ -235,11 +235,13 @@ struct ufs_query { · 234 unmodified lines | ||
| 235 | 235 | * @type: device management command type - Query, NOP OUT |
| 236 | 236 | * @lock: lock to allow one command at a time |
| 237 | 237 | * @query: Device management query information |
| 238 | + * @tag: tag of the reserved request in use | |
| 238 | 239 | */ |
| 239 | 240 | struct ufs_dev_cmd { |
| 240 | 241 | enum dev_cmd_type type; |
| 241 | 242 | struct mutex lock; |
| 242 | 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 | 956 | * @ucdl_base_addr: UFS Command Descriptor base address |
| 955 | 957 | * @utrdl_base_addr: UTP Transfer Request Descriptor base address |
| 956 | 958 | * @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 | 961 | * @ucdl_dma_addr: UFS Command Descriptor DMA address |
| 958 | 962 | * @utrdl_dma_addr: UTRDL DMA address |
| 959 | 963 | * @utmrdl_dma_addr: UTMRDL DMA address |
| 964 | + * @devman_ucd_dma_addr: UFS Command Descriptor DMA address for the reserved | |
| 965 | + * device management tag | |
| 960 | 966 | * @host: Scsi_Host instance of the driver |
| 961 | 967 | * @dev: device handle |
| 962 | 968 | * @ufs_device_wlun: WLUN that controls the entire UFS device. |
| @@ -1098,11 +1104,13 @@ struct ufs_hba { · 135 unmodified lines | ||
| 1098 | 1104 | struct utp_transfer_cmd_desc *ucdl_base_addr; |
| 1099 | 1105 | struct utp_transfer_req_desc *utrdl_base_addr; |
| 1100 | 1106 | struct utp_task_req_desc *utmrdl_base_addr; |
| 1107 | + struct utp_devman_cmd_desc *devman_ucd_base_addr; | |
| 1101 | 1108 | |
| 1102 | 1109 | /* DMA memory reference */ |
| 1103 | 1110 | dma_addr_t ucdl_dma_addr; |
| 1104 | 1111 | dma_addr_t utrdl_dma_addr; |
| 1105 | 1112 | dma_addr_t utmrdl_dma_addr; |
| 1113 | + dma_addr_t devman_ucd_dma_addr; | |
| 1106 | 1114 | |
| 1107 | 1115 | struct Scsi_Host *host; |
| 1108 | 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 | 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 | + | |
| 1378 | +static 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 | 1384 | /* Returns true if clocks can be gated. Otherwise false */ |
| 1365 | 1385 | static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba) |
| 1366 | 1386 | { |
| @@ -18,6 +18,8 @@ enum { · 17 unmodified lines | ||
| 18 | 18 | TASK_REQ_UPIU_SIZE_DWORDS = 8, |
| 19 | 19 | TASK_RSP_UPIU_SIZE_DWORDS = 8, |
| 20 | 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 | 25 | /* UFSHCI Registers */ |
| @@ -501,6 +503,16 @@ struct utp_transfer_cmd_desc { · 477 unmodified lines | ||
| 501 | 503 | u8 prd_table[]; |
| 502 | 504 | }; |
| 503 | 505 | |
| 506 | +/* Dedicated UCD for the devman/reserved slot */ | |
| 507 | +struct 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 | + | |
| 513 | +static_assert(sizeof(struct utp_upiu_req) + QUERY_AGGREGATED_MAX_SIZE <= | |
| 514 | + ALIGNED_DEVMAN_RSP_SIZE); | |
| 515 | + | |
| 504 | 516 | /** |
| 505 | 517 | * struct request_desc_header - Descriptor Header common to both UTRD and UTMRD |
| 506 | 518 | */ |