Skip to content

Commit 67a2a89

Browse files
bvanasschemartinkpetersen
authored andcommitted
scsi: ufs: Simplify transfer request header initialization
Make the code that initializes UTP transfer request headers easier to read by using bitfields instead of __le32 where appropriate. Cc: "Bao D. Nguyen" <[email protected]> Cc: Eric Biggers <[email protected]> Cc: Avri Altman <[email protected]> Cc: Bean Huo <[email protected]> Cc: Adrian Hunter <[email protected]> Signed-off-by: Bart Van Assche <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Avri Altman <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent e2566e0 commit 67a2a89

File tree

5 files changed

+99
-58
lines changed

5 files changed

+99
-58
lines changed

drivers/ufs/core/ufs-mcq.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -558,12 +558,7 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag)
558558
*/
559559
static void ufshcd_mcq_nullify_sqe(struct utp_transfer_req_desc *utrd)
560560
{
561-
u32 dword_0;
562-
563-
dword_0 = le32_to_cpu(utrd->header.dword_0);
564-
dword_0 &= ~UPIU_COMMAND_TYPE_MASK;
565-
dword_0 |= FIELD_PREP(UPIU_COMMAND_TYPE_MASK, 0xF);
566-
utrd->header.dword_0 = cpu_to_le32(dword_0);
561+
utrd->header.command_type = 0xf;
567562
}
568563

569564
/**

drivers/ufs/core/ufshcd-crypto.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ static inline void ufshcd_prepare_lrbp_crypto(struct request *rq,
2626
}
2727

2828
static inline void
29-
ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, u32 *dword_0,
30-
u32 *dword_1, u32 *dword_3)
29+
ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp,
30+
struct request_desc_header *h)
3131
{
32-
if (lrbp->crypto_key_slot >= 0) {
33-
*dword_0 |= UTP_REQ_DESC_CRYPTO_ENABLE_CMD;
34-
*dword_0 |= lrbp->crypto_key_slot;
35-
*dword_1 = lower_32_bits(lrbp->data_unit_num);
36-
*dword_3 = upper_32_bits(lrbp->data_unit_num);
37-
}
32+
if (lrbp->crypto_key_slot < 0)
33+
return;
34+
h->enable_crypto = 1;
35+
h->cci = lrbp->crypto_key_slot;
36+
h->dunl = cpu_to_le32(lower_32_bits(lrbp->data_unit_num));
37+
h->dunu = cpu_to_le32(upper_32_bits(lrbp->data_unit_num));
3838
}
3939

4040
bool ufshcd_crypto_enable(struct ufs_hba *hba);
@@ -51,8 +51,8 @@ static inline void ufshcd_prepare_lrbp_crypto(struct request *rq,
5151
struct ufshcd_lrb *lrbp) { }
5252

5353
static inline void
54-
ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, u32 *dword_0,
55-
u32 *dword_1, u32 *dword_3) { }
54+
ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp,
55+
struct request_desc_header *h) { }
5656

5757
static inline bool ufshcd_crypto_enable(struct ufs_hba *hba)
5858
{

drivers/ufs/core/ufshcd.c

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ static enum utp_ocs ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp,
794794
if (cqe)
795795
return le32_to_cpu(cqe->status) & MASK_OCS;
796796

797-
return le32_to_cpu(lrbp->utr_descriptor_ptr->header.dword_2) & MASK_OCS;
797+
return lrbp->utr_descriptor_ptr->header.ocs & MASK_OCS;
798798
}
799799

800800
/**
@@ -2587,10 +2587,10 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, u8 *upiu_flags,
25872587
enum dma_data_direction cmd_dir, int ehs_length)
25882588
{
25892589
struct utp_transfer_req_desc *req_desc = lrbp->utr_descriptor_ptr;
2590-
u32 data_direction;
2591-
u32 dword_0;
2592-
u32 dword_1 = 0;
2593-
u32 dword_3 = 0;
2590+
struct request_desc_header *h = &req_desc->header;
2591+
enum utp_data_direction data_direction;
2592+
2593+
*h = (typeof(*h)){ };
25942594

25952595
if (cmd_dir == DMA_FROM_DEVICE) {
25962596
data_direction = UTP_DEVICE_TO_HOST;
@@ -2603,25 +2603,22 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, u8 *upiu_flags,
26032603
*upiu_flags = UPIU_CMD_FLAGS_NONE;
26042604
}
26052605

2606-
dword_0 = data_direction | (lrbp->command_type << UPIU_COMMAND_TYPE_OFFSET) |
2607-
ehs_length << 8;
2606+
h->command_type = lrbp->command_type;
2607+
h->data_direction = data_direction;
2608+
h->ehs_length = ehs_length;
2609+
26082610
if (lrbp->intr_cmd)
2609-
dword_0 |= UTP_REQ_DESC_INT_CMD;
2611+
h->interrupt = 1;
26102612

26112613
/* Prepare crypto related dwords */
2612-
ufshcd_prepare_req_desc_hdr_crypto(lrbp, &dword_0, &dword_1, &dword_3);
2614+
ufshcd_prepare_req_desc_hdr_crypto(lrbp, h);
26132615

2614-
/* Transfer request descriptor header fields */
2615-
req_desc->header.dword_0 = cpu_to_le32(dword_0);
2616-
req_desc->header.dword_1 = cpu_to_le32(dword_1);
26172616
/*
26182617
* assigning invalid value for command status. Controller
26192618
* updates OCS on command completion, with the command
26202619
* status
26212620
*/
2622-
req_desc->header.dword_2 =
2623-
cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
2624-
req_desc->header.dword_3 = cpu_to_le32(dword_3);
2621+
h->ocs = OCS_INVALID_COMMAND_STATUS;
26252622

26262623
req_desc->prd_table_length = 0;
26272624
}
@@ -5445,8 +5442,7 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
54455442
if (hba->dev_cmd.complete) {
54465443
if (cqe) {
54475444
ocs = le32_to_cpu(cqe->status) & MASK_OCS;
5448-
lrbp->utr_descriptor_ptr->header.dword_2 =
5449-
cpu_to_le32(ocs);
5445+
lrbp->utr_descriptor_ptr->header.ocs = ocs;
54505446
}
54515447
complete(hba->dev_cmd.complete);
54525448
ufshcd_clk_scaling_update_busy(hba);
@@ -7034,8 +7030,8 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
70347030
int err;
70357031

70367032
/* Configure task request descriptor */
7037-
treq.header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
7038-
treq.header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
7033+
treq.header.interrupt = 1;
7034+
treq.header.ocs = OCS_INVALID_COMMAND_STATUS;
70397035

70407036
/* Configure task request UPIU */
70417037
treq.upiu_req.req_header.dword_0 = cpu_to_be32(lun_id << 8) |
@@ -7053,7 +7049,7 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
70537049
if (err == -ETIMEDOUT)
70547050
return err;
70557051

7056-
ocs_value = le32_to_cpu(treq.header.dword_2) & MASK_OCS;
7052+
ocs_value = treq.header.ocs & MASK_OCS;
70577053
if (ocs_value != OCS_SUCCESS)
70587054
dev_err(hba->dev, "%s: failed, ocs = 0x%x\n",
70597055
__func__, ocs_value);
@@ -7213,16 +7209,16 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
72137209

72147210
break;
72157211
case UPIU_TRANSACTION_TASK_REQ:
7216-
treq.header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
7217-
treq.header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
7212+
treq.header.interrupt = 1;
7213+
treq.header.ocs = OCS_INVALID_COMMAND_STATUS;
72187214

72197215
memcpy(&treq.upiu_req, req_upiu, sizeof(*req_upiu));
72207216

72217217
err = __ufshcd_issue_tm_cmd(hba, &treq, tm_f);
72227218
if (err == -ETIMEDOUT)
72237219
break;
72247220

7225-
ocs_value = le32_to_cpu(treq.header.dword_2) & MASK_OCS;
7221+
ocs_value = treq.header.ocs & MASK_OCS;
72267222
if (ocs_value != OCS_SUCCESS) {
72277223
dev_err(hba->dev, "%s: failed, ocs = 0x%x\n", __func__,
72287224
ocs_value);
@@ -10567,6 +10563,39 @@ static const struct dev_pm_ops ufshcd_wl_pm_ops = {
1056710563
SET_RUNTIME_PM_OPS(ufshcd_wl_runtime_suspend, ufshcd_wl_runtime_resume, NULL)
1056810564
};
1056910565

10566+
static void ufshcd_check_header_layout(void)
10567+
{
10568+
BUILD_BUG_ON(((u8 *)&(struct request_desc_header){
10569+
.cci = 3})[0] != 3);
10570+
10571+
BUILD_BUG_ON(((u8 *)&(struct request_desc_header){
10572+
.ehs_length = 2})[1] != 2);
10573+
10574+
BUILD_BUG_ON(((u8 *)&(struct request_desc_header){
10575+
.enable_crypto = 1})[2]
10576+
!= 0x80);
10577+
10578+
BUILD_BUG_ON((((u8 *)&(struct request_desc_header){
10579+
.command_type = 5,
10580+
.data_direction = 3,
10581+
.interrupt = 1,
10582+
})[3]) != ((5 << 4) | (3 << 1) | 1));
10583+
10584+
BUILD_BUG_ON(((__le32 *)&(struct request_desc_header){
10585+
.dunl = cpu_to_le32(0xdeadbeef)})[1] !=
10586+
cpu_to_le32(0xdeadbeef));
10587+
10588+
BUILD_BUG_ON(((u8 *)&(struct request_desc_header){
10589+
.ocs = 4})[8] != 4);
10590+
10591+
BUILD_BUG_ON(((u8 *)&(struct request_desc_header){
10592+
.cds = 5})[9] != 5);
10593+
10594+
BUILD_BUG_ON(((__le32 *)&(struct request_desc_header){
10595+
.dunu = cpu_to_le32(0xbadcafe)})[3] !=
10596+
cpu_to_le32(0xbadcafe));
10597+
}
10598+
1057010599
/*
1057110600
* ufs_dev_wlun_template - describes ufs device wlun
1057210601
* ufs-device wlun - used to send pm commands
@@ -10592,6 +10621,8 @@ static int __init ufshcd_core_init(void)
1059210621
{
1059310622
int ret;
1059410623

10624+
ufshcd_check_header_layout();
10625+
1059510626
ufs_debugfs_init();
1059610627

1059710628
ret = scsi_register_driver(&ufs_dev_wlun_template.gendrv);

include/ufs/ufs.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,6 @@ enum {
473473
UPIU_COMMAND_SET_TYPE_QUERY = 0x2,
474474
};
475475

476-
/* UTP Transfer Request Command Offset */
477-
#define UPIU_COMMAND_TYPE_OFFSET 28
478-
479476
/* Offset of the response code in the UPIU header */
480477
#define UPIU_RSP_CODE_OFFSET 8
481478

include/ufs/ufshci.h

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ enum {
127127
};
128128

129129
#define SQ_ICU_ERR_CODE_MASK GENMASK(7, 4)
130-
#define UPIU_COMMAND_TYPE_MASK GENMASK(31, 28)
131130
#define UFS_MASK(mask, offset) ((mask) << (offset))
132131

133132
/* UFS Version 08h */
@@ -439,15 +438,13 @@ enum {
439438
UTP_SCSI_COMMAND = 0x00000000,
440439
UTP_NATIVE_UFS_COMMAND = 0x10000000,
441440
UTP_DEVICE_MANAGEMENT_FUNCTION = 0x20000000,
442-
UTP_REQ_DESC_INT_CMD = 0x01000000,
443-
UTP_REQ_DESC_CRYPTO_ENABLE_CMD = 0x00800000,
444441
};
445442

446443
/* UTP Transfer Request Data Direction (DD) */
447-
enum {
448-
UTP_NO_DATA_TRANSFER = 0x00000000,
449-
UTP_HOST_TO_DEVICE = 0x02000000,
450-
UTP_DEVICE_TO_HOST = 0x04000000,
444+
enum utp_data_direction {
445+
UTP_NO_DATA_TRANSFER = 0,
446+
UTP_HOST_TO_DEVICE = 1,
447+
UTP_DEVICE_TO_HOST = 2,
451448
};
452449

453450
/* Overall command status values */
@@ -506,17 +503,38 @@ struct utp_transfer_cmd_desc {
506503

507504
/**
508505
* struct request_desc_header - Descriptor Header common to both UTRD and UTMRD
509-
* @dword0: Descriptor Header DW0
510-
* @dword1: Descriptor Header DW1
511-
* @dword2: Descriptor Header DW2
512-
* @dword3: Descriptor Header DW3
513506
*/
514507
struct request_desc_header {
515-
__le32 dword_0;
516-
__le32 dword_1;
517-
__le32 dword_2;
518-
__le32 dword_3;
519-
};
508+
u8 cci;
509+
u8 ehs_length;
510+
#if defined(__BIG_ENDIAN)
511+
u8 enable_crypto:1;
512+
u8 reserved2:7;
513+
514+
u8 command_type:4;
515+
u8 reserved1:1;
516+
u8 data_direction:2;
517+
u8 interrupt:1;
518+
#elif defined(__LITTLE_ENDIAN)
519+
u8 reserved2:7;
520+
u8 enable_crypto:1;
521+
522+
u8 interrupt:1;
523+
u8 data_direction:2;
524+
u8 reserved1:1;
525+
u8 command_type:4;
526+
#else
527+
#error
528+
#endif
529+
530+
__le32 dunl;
531+
u8 ocs;
532+
u8 cds;
533+
__le16 ldbc;
534+
__le32 dunu;
535+
};
536+
537+
static_assert(sizeof(struct request_desc_header) == 16);
520538

521539
/**
522540
* struct utp_transfer_req_desc - UTP Transfer Request Descriptor (UTRD)

0 commit comments

Comments
 (0)