diff options
| author | Martin K. Petersen (Oracle) <mkp@kernel.org> | 2026-08-07 11:34:35 -0400 |
|---|---|---|
| committer | Martin K. Petersen (Oracle) <mkp@kernel.org> | 2026-08-07 11:34:35 -0400 |
| commit | f574a022ee5d1f23e9dd6f6a4e4c8a8af7bbb477 (patch) | |
| tree | 9b93a3d4188bb943015860336a7c5d03c57d40a6 /include | |
| parent | 654fdae895253ef4ce5bf0cfa261d0e1547347c2 (diff) | |
| parent | 8f5bbff8749ab886557cc27dc09729c911c122fa (diff) | |
| download | linux-stable-f574a022ee5d1f23e9dd6f6a4e4c8a8af7bbb477.tar.gz linux-stable-f574a022ee5d1f23e9dd6f6a4e4c8a8af7bbb477.zip | |
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/
Link: https://patch.msgid.link/20260728092208epcms2p881b17276fb41c006a4229c1d073b4ad0@epcms2p8
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/ufs/ufs.h | 6 | ||||
| -rw-r--r-- | include/ufs/ufshcd.h | 20 | ||||
| -rw-r--r-- | include/ufs/ufshci.h | 12 |
3 files changed, 38 insertions, 0 deletions
diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index 0d48e137d66d..afbb32654fab 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -25,6 +25,11 @@ static_assert(sizeof(struct utp_upiu_query) == 20); #define GENERAL_UPIU_REQUEST_SIZE (sizeof(struct utp_upiu_req)) #define QUERY_DESC_MAX_SIZE 255 +/* + * Max aggregated read data segment: the devman response area + * (ALIGNED_DEVMAN_RSP_SIZE) minus the fixed UPIU header it follows. + */ +#define QUERY_AGGREGATED_MAX_SIZE (4096 - GENERAL_UPIU_REQUEST_SIZE) #define QUERY_DESC_MIN_SIZE 2 #define QUERY_DESC_HDR_SIZE 2 #define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \ @@ -464,6 +469,7 @@ enum query_opcode { UPIU_QUERY_OPCODE_SET_FLAG = 0x6, UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7, UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8, + UPIU_QUERY_OPCODE_AGGREGATED_READ = 0x9, }; /* bRefClkFreq attribute values */ diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 26118b28b2dc..dfd302f2dc7c 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -235,11 +235,13 @@ struct ufs_query { * @type: device management command type - Query, NOP OUT * @lock: lock to allow one command at a time * @query: Device management query information + * @tag: tag of the reserved request in use */ struct ufs_dev_cmd { enum dev_cmd_type type; struct mutex lock; struct ufs_query query; + u8 tag; }; /** @@ -954,9 +956,13 @@ enum ufshcd_mcq_opr { * @ucdl_base_addr: UFS Command Descriptor base address * @utrdl_base_addr: UTP Transfer Request Descriptor base address * @utmrdl_base_addr: UTP Task Management Descriptor base address + * @devman_ucd_base_addr: UFS Command Descriptor base address for the reserved + * device management tag (has a larger response area) * @ucdl_dma_addr: UFS Command Descriptor DMA address * @utrdl_dma_addr: UTRDL DMA address * @utmrdl_dma_addr: UTMRDL DMA address + * @devman_ucd_dma_addr: UFS Command Descriptor DMA address for the reserved + * device management tag * @host: Scsi_Host instance of the driver * @dev: device handle * @ufs_device_wlun: WLUN that controls the entire UFS device. @@ -1098,11 +1104,13 @@ struct ufs_hba { struct utp_transfer_cmd_desc *ucdl_base_addr; struct utp_transfer_req_desc *utrdl_base_addr; struct utp_task_req_desc *utmrdl_base_addr; + struct utp_devman_cmd_desc *devman_ucd_base_addr; /* DMA memory reference */ dma_addr_t ucdl_dma_addr; dma_addr_t utrdl_dma_addr; dma_addr_t utmrdl_dma_addr; + dma_addr_t devman_ucd_dma_addr; struct Scsi_Host *host; struct device *dev; @@ -1361,6 +1369,18 @@ static inline size_t ufshcd_get_ucd_size(const struct ufs_hba *hba) return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba); } +/* + * Two entries should be enough for the largest devman PRDT transfer (4 KiB), + * like advanced RPMB. + */ +#define UFSHCD_DEVMAN_SG_ENTRIES 2 + +static inline size_t ufshcd_get_devman_ucd_size(const struct ufs_hba *hba) +{ + return sizeof(struct utp_devman_cmd_desc) + + UFSHCD_DEVMAN_SG_ENTRIES * ufshcd_sg_entry_size(hba); +} + /* Returns true if clocks can be gated. Otherwise false */ static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba) { diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h index 9f0fdd850e54..c3537bb544ae 100644 --- a/include/ufs/ufshci.h +++ b/include/ufs/ufshci.h @@ -18,6 +18,8 @@ enum { TASK_REQ_UPIU_SIZE_DWORDS = 8, TASK_RSP_UPIU_SIZE_DWORDS = 8, ALIGNED_UPIU_SIZE = 512, + /* Larger response area, only for the devman UCD */ + ALIGNED_DEVMAN_RSP_SIZE = 4096, }; /* UFSHCI Registers */ @@ -501,6 +503,16 @@ struct utp_transfer_cmd_desc { u8 prd_table[]; }; +/* Dedicated UCD for the devman/reserved slot */ +struct utp_devman_cmd_desc { + u8 command_upiu[ALIGNED_UPIU_SIZE]; + u8 response_upiu[ALIGNED_DEVMAN_RSP_SIZE]; + u8 prd_table[]; +}; + +static_assert(sizeof(struct utp_upiu_req) + QUERY_AGGREGATED_MAX_SIZE <= + ALIGNED_DEVMAN_RSP_SIZE); + /** * struct request_desc_header - Descriptor Header common to both UTRD and UTMRD */ |
