Changeset View
Standalone View
sys/dev/ufshci/ufshci.h
- This file was added.
| /*- | |||||
| * SPDX-License-Identifier: BSD-2-Clause | |||||
| * | |||||
| * Copyright (c) 2025, Samsung Electronics Co., Ltd. | |||||
| * All rights reserved. | |||||
| * | |||||
imp: We have new, streamlined rules. Of course you're allowed to use the long form, but since you… | |||||
Done Inline ActionsWould it be okay if I update it like this? /*- * Copyright (c) 2025, Samsung Electronics Co., Ltd. * Written by Jaeyoon Choi * * SPDX-License-Identifier: BSD-2-Clause */ jaeyoon: Would it be okay if I update it like this?
```
/*-
* Copyright (c) 2025, Samsung Electronics… | |||||
Done Inline ActionsThis is perfect. Thank you.. imp: This is perfect. Thank you.. | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| */ | |||||
| #ifndef __UFSHCI_H__ | |||||
| #define __UFSHCI_H__ | |||||
| #ifdef _KERNEL | |||||
Done Inline ActionsI don't think this #ifdef is needed... param.h includes types.h I thought. imp: I don't think this #ifdef is needed... param.h includes types.h I thought. | |||||
| #include <sys/types.h> | |||||
| #endif | |||||
| #include <sys/param.h> | |||||
| #include <sys/endian.h> | |||||
| /* MIPI UniPro spec 2.0, section 5.8.1 "PHY Adapter Common Attributes" */ | |||||
| #define PA_AvailTxDataLanes 0x1520 | |||||
| #define PA_AvailRxDataLanes 0x1540 | |||||
| /* | |||||
| * MIPI UniPro spec 2.0, section 5.8.2 "PHY Adapter M-PHY-Specific | |||||
| * Attributes" | |||||
| */ | |||||
| #define PA_ConnectedTxDataLanes 0x1561 | |||||
| #define PA_ConnectedRxDataLanes 0x1581 | |||||
| #define PA_MaxRxHSGear 0x1587 | |||||
| #define PA_Granularity 0x15AA | |||||
| #define PA_TActivate 0x15A8 | |||||
| #define PA_RemoteVerInfo 0x15A0 | |||||
| #define PA_LocalVerInfo 0x15A9 | |||||
| /* UFSHCI spec 4.0, section 7.4 "UIC Power Mode Change". */ | |||||
| #define PA_ActiveTxDataLanes 0x1560 | |||||
| #define PA_ActiveRxDataLanes 0x1580 | |||||
| #define PA_TxGear 0x1568 | |||||
| #define PA_RxGear 0x1583 | |||||
| #define PA_TxTermination 0x1569 | |||||
| #define PA_RxTermination 0x1584 | |||||
| #define PA_HSSeries 0x156A | |||||
| #define PA_PWRModeUserData0 0x15B0 | |||||
| #define PA_PWRModeUserData1 0x15B1 | |||||
| #define PA_PWRModeUserData2 0x15B2 | |||||
| #define PA_PWRModeUserData3 0x15B3 | |||||
| #define PA_PWRModeUserData4 0x15B4 | |||||
| #define PA_PWRModeUserData5 0x15B5 | |||||
| #define PA_TxHsAdaptType 0x15D4 | |||||
| #define PA_PWRMode 0x1571 | |||||
| #define DME_LocalFC0ProtectionTimeOutVal 0xD041 | |||||
| #define DME_LocalTC0ReplayTimeOutVal 0xD042 | |||||
| #define DME_LocalAFC0ReqTimeOutVal 0xD043 | |||||
| /* Currently, UFS uses TC0 only. */ | |||||
| #define DL_FC0ProtectionTimeOutVal_Default 8191 | |||||
| #define DL_TC0ReplayTimeOutVal_Default 65535 | |||||
| #define DL_AFC0ReqTimeOutVal_Default 32767 | |||||
Done Inline ActionsThe above are all nicely aligned, but these aren't. Maybe you should align them? Just a thought, it would make it it look a little better, but frankly is minor thing. And I think clang-format might undo it all (it doesn't like the alignment like this and removes it), so if you do that, then never mind. imp: The above are all nicely aligned, but these aren't. Maybe you should align them? Just a thought… | |||||
Done Inline ActionsI'm a little confused, if I apply clang-format it breaks all the aligns for variable declarations, is it okay to apply clang-format? Is it okay if I don't follow the align for variable declarations? jaeyoon: I'm a little confused, if I apply clang-format it breaks all the aligns for variable… | |||||
Done Inline ActionsYes. My comment was about consistency, not the need to follow something absolutely. clangformat will produce consistent results. imp: Yes. My comment was about consistency, not the need to follow something absolutely. clangformat… | |||||
Done Inline ActionsThank you, I'll use clang-format. jaeyoon: Thank you, I'll use clang-format. | |||||
| /* UFS Spec 4.0, section 6.4 "Reference Clock". */ | |||||
| enum ufshci_attribute_reference_clock { | |||||
| UFSHCI_ATTR_REF_CLOCK_19_2MHz = 0x0, | |||||
| UFSHCI_ATTR_REF_CLOCK_26MHz = 0x1, | |||||
| UFSHCI_ATTR_REF_CLOCK_38_4MHz = 0x2, | |||||
| UFSHCI_ATTR_REF_CLOCK_OBSOLETE = 0x3, | |||||
| }; | |||||
| /* UFS spec 4.0, section 9 "UFS UIC Layer: MIPI Unipro" */ | |||||
| enum ufshci_uic_cmd_opcode { | |||||
| /* Configuration */ | |||||
| UFSHCI_DME_GET = 0x01, | |||||
| UFSHCI_DME_SET = 0x02, | |||||
| UFSHCI_DME_PEER_GET = 0x03, | |||||
| UFSHCI_DME_PEER_SET = 0x04, | |||||
| /* Controll */ | |||||
| UFSHCI_DME_POWER_ON = 0x10, | |||||
| UFSHCI_DME_POWER_OFF = 0x11, | |||||
| UFSHCI_DME_ENABLE = 0x12, | |||||
| UFSHCI_DME_RESET = 0x14, | |||||
| UFSHCI_DME_ENDPOINT_RESET = 0x15, | |||||
| UFSHCI_DME_LINK_STARTUP = 0x16, | |||||
| UFSHCI_DME_HIBERNATE_ENTER = 0x17, | |||||
| UFSHCI_DME_HIBERNATE_EXIT = 0x18, | |||||
| UFSHCI_DME_TEST_MODE = 0x1a, | |||||
| }; | |||||
| /* UFSHCI spec 4.1, section 5.6.3 "Offset 98h: UICCMDARG2 – UIC Command Argument" */ | |||||
| enum ufshci_uic_cmd_attr_set_type { | |||||
| UFSHCI_ATTR_SET_TYPE_NORMAL = 0, /* volatile value */ | |||||
| UFSHCI_ATTR_SET_TYPE_STATIC = 1, /* non-volatile reset value */ | |||||
| }; | |||||
| struct ufshci_uic_cmd { | |||||
| uint8_t opcode; | |||||
| uint32_t argument1; | |||||
Done Inline Actionsthis will have alignment issues. Is this used external interface? imp: this will have alignment issues. Is this used external interface? | |||||
Done Inline ActionsThis structure is not used in any external interface, so alignment should not be an issue in this case. jaeyoon: This structure is not used in any external interface, so alignment should not be an issue in… | |||||
| uint32_t argument2; | |||||
| uint32_t argument3; | |||||
| }; | |||||
| /* UFS spec 4.0, section 10.5 "UPIU Transactions" */ | |||||
| enum transaction_code { | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_NOP_OUT = 0x00, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_COMMAND = 0x01, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_DATA_OUT = 0x02, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_TASK_MANAGEMENT_REQUEST = 0x04, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_QUERY_REQUEST = 0x16, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_NOP_IN = 0x20, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_RESPONSE = 0x21, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_DATA_IN = 0x22, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_TASK_MANAGEMENT_RESPONSE = 0x24, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_READY_TO_TRANSFER = 0x31, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_QUERY_RESPONSE = 0x36, | |||||
| UFSHCI_UPIU_TRANSACTION_CODE_REJECT_UPIU = 0x3f, | |||||
| }; | |||||
| enum overall_command_status { | |||||
| UFSHCI_DESC_SUCCESS = 0x0, | |||||
| UFSHCI_DESC_INVALID_COMMAND_TABLE_ATTRIBUTES = 0x01, | |||||
| UFSHCI_DESC_INVALID_PRDT_ATTRIBUTES = 0x02, | |||||
| UFSHCI_DESC_MISMATCH_DATA_BUFFER_SIZE = 0x03, | |||||
| UFSHCI_DESC_MISMATCH_RESPONSE_UPIU_SIZE = 0x04, | |||||
| UFSHCI_DESC_COMMUNICATION_FAILURE_WITHIN_UIC_LAYERS = 0x05, | |||||
| UFSHCI_DESC_ABORTED = 0x06, | |||||
| UFSHCI_DESC_HOST_CONTROLLER_FATAL_ERROR = 0x07, | |||||
| UFSHCI_DESC_DEVICEFATALERROR = 0x08, | |||||
| UFSHCI_DESC_INVALID_CRYPTO_CONFIGURATION = 0x09, | |||||
| UFSHCI_DESC_GENERAL_CRYPTO_ERROR = 0x0A, | |||||
| UFSHCI_DESC_INVALID = 0x0F, | |||||
| }; | |||||
| enum response_code { | |||||
| UFSHCI_RESPONSE_CODE_TARGET_SUCCESS = 0x00, | |||||
| UFSHCI_RESPONSE_CODE_TARGET_FAILURE = 0x01, | |||||
| UFSHCI_RESPONSE_CODE_PARAMETER_NOTREADABLE = 0xF6, | |||||
| UFSHCI_RESPONSE_CODE_PARAMETER_NOTWRITEABLE = 0xF7, | |||||
| UFSHCI_RESPONSE_CODE_PARAMETER_ALREADYWRITTEN = 0xF8, | |||||
| UFSHCI_RESPONSE_CODE_INVALID_LENGTH = 0xF9, | |||||
| UFSHCI_RESPONSE_CODE_INVALID_VALUE = 0xFA, | |||||
| UFSHCI_RESPONSE_CODE_INVALID_SELECTOR = 0xFB, | |||||
| UFSHCI_RESPONSE_CODE_INVALID_INDEX = 0xFC, | |||||
| UFSHCI_RESPONSE_CODE_INVALID_IDN = 0xFD, | |||||
| UFSHCI_RESPONSE_CODE_INVALID_OPCODE = 0xFE, | |||||
| UFSHCI_RESPONSE_CODE_GENERAL_FAILURE = 0xFF, | |||||
| }; | |||||
| /* UFSHCI spec 4.0, section 6.1.1 "UTP Transfer Request Descriptor" */ | |||||
| enum ufshci_command_type { | |||||
| UFSHCI_COMMAND_TYPE_UFS_STORAGE = 0x01, | |||||
| UFSHCI_COMMAND_TYPE_NULLIFIED_UTRD = 0x0F, | |||||
| }; | |||||
| enum ufshci_data_direction { | |||||
| UFSHCI_DATA_DIRECTION_NO_DATA_TRANSFER = 0x00, | |||||
| UFSHCI_DATA_DIRECTION_FROM_SYS_TO_TGT = 0x01, | |||||
| UFSHCI_DATA_DIRECTION_FROM_TGT_TO_SYS = 0x10, | |||||
| UFSHCI_DATA_DIRECTION_RESERVED = 0b11, | |||||
| }; | |||||
| enum ufshci_overall_command_status { | |||||
| UFSHCI_OCS_SUCCESS = 0x0, | |||||
| UFSHCI_OCS_INVALID_COMMAND_TABLE_ATTRIBUTES = 0x01, | |||||
| UFSHCI_OCS_INVALID_PRDT_ATTRIBUTES = 0x02, | |||||
| UFSHCI_OCS_MISMATCH_DATA_BUFFER_SIZE = 0x03, | |||||
| UFSHCI_OCS_MISMATCH_RESPONSE_UPIU_SIZE = 0x04, | |||||
| UFSHCI_OCS_COMMUNICATION_FAILURE_WITHIN_UIC_LAYERS = 0x05, | |||||
| UFSHCI_OCS_ABORTED = 0x06, | |||||
| UFSHCI_OCS_HOST_CONTROLLER_FATAL_ERROR = 0x07, | |||||
| UFSHCI_OCS_DEVICE_FATAL_ERROR = 0x08, | |||||
| UFSHCI_OCS_INVALID_CRYPTO_CONFIGURATION = 0x09, | |||||
| UFSHCI_OCS_GENERAL_CRYPTO_ERROR = 0x0A, | |||||
| UFSHCI_OCS_INVALID = 0xF, | |||||
| }; | |||||
| struct ufshci_utp_xfer_req_desc { | |||||
| /* dword 0 */ | |||||
| uint32_t cci:8; /* [7:0] */ | |||||
| uint32_t total_ehs_length:8; /* [15:8] */ | |||||
| uint32_t reserved0:7; /* [22:16] */ | |||||
| uint32_t ce:1; /* [23] */ | |||||
| uint32_t interrupt:1; /* [24] */ | |||||
| uint32_t data_direction:2; /* [26:25] */ | |||||
| uint32_t reserved1:1; /* [27] */ | |||||
| uint32_t command_type:4; /* [31:28] */ | |||||
Done Inline ActionsSo using bit fields like this means that this is little endian-only. Likely not a huge deal since I don't think powerpc is relevant and it would be a huge. pain to fix... imp: So using bit fields like this means that this is little endian-only. Likely not a huge deal… | |||||
Done Inline ActionsI didn't think about big endian deeply enough in the driver, I'll revisit it overall later. jaeyoon: I didn't think about big endian deeply enough in the driver, I'll revisit it overall later.
(I… | |||||
Done Inline ActionsThat's fine. Somewhere this restriction should be noted. imp: That's fine. Somewhere this restriction should be noted. | |||||
Done Inline ActionsI added the following comment to the top of ufshci.h. /* * Note: This driver currently assumes a little-endian architecture. * Big-endian support is not yet implemented. */ jaeyoon: I added the following comment to the top of ufshci.h.
```
/*
* Note: This driver currently… | |||||
| /* dword 1 */ | |||||
| uint32_t data_unit_number_lower; /* [31:0] */ | |||||
| /* dword 2 */ | |||||
| uint8_t overall_command_status; /* [7:0] */ | |||||
| uint8_t common_data_size; /* [15:8] */ | |||||
| uint16_t last_data_byte_count; /* [31:16] */ | |||||
| /* dword 3 */ | |||||
| uint32_t data_unit_number_upper; /* [31:0] */ | |||||
| /* dword 4 */ | |||||
| uint32_t utp_command_descriptor_base_address; /* [31:0] */ | |||||
| /* dword 5 */ | |||||
| uint32_t utp_command_descriptor_base_address_upper; /* [31:0] */ | |||||
| /* dword 6 */ | |||||
| uint16_t response_upiu_length; /* [15:0] */ | |||||
| uint16_t response_upiu_offset; /* [31:16] */ | |||||
| /* dword 7 */ | |||||
| uint16_t prdt_length; /* [15:0] */ | |||||
| uint16_t prdt_offset; /* [31:16] */ | |||||
| } __packed __aligned(8); | |||||
| _Static_assert(sizeof(struct ufshci_utp_xfer_req_desc) == 32, | |||||
| "ufshci_utp_xfer_req_desc must be 32 bytes"); | |||||
| /* | |||||
| * According to the UFSHCI specification, the size of the UTP command | |||||
| * descriptor is as follows. The size of the transfer request is not limited, | |||||
| * a transfer response can be as long as 65535 * dwords, and a PRDT can be as | |||||
| * long as 65565 * PRDT entry size(16 bytes). However, for ease of use, this | |||||
| * UFSHCI Driver imposes the following limits. The size of the transfer | |||||
| * request and the transfer response is 1024 bytes or less. The PRDT region | |||||
| * limits the number of scatter gathers to 256 + 1, using a total of 4096 + | |||||
| * 16 bytes. Therefore, only 8KB size is allocated for the UTP command | |||||
| * descriptor. | |||||
| */ | |||||
| #define UFSHCI_UTP_COMMAND_DESCRIPTOR_SIZE 8192 | |||||
| #define UFSHCI_UTP_XFER_REQ_SIZE 512 | |||||
| #define UFSHCI_UTP_XFER_RESP_SIZE 512 | |||||
| /* | |||||
| * To reduce the size of the UTP Command Descriptor(8KB), we must use only | |||||
| * 256 + 1 PRDT entries. The reason for adding the 1 is that if the data is | |||||
| * not aligned, one additional PRDT_ENTRY is used. | |||||
| */ | |||||
| #define UFSHCI_MAX_PRDT_ENTRY_COUNT (256 + 1) | |||||
| /* UFSHCI spec 4.0, section 6.1.2 "UTP Command Descriptor" */ | |||||
| struct ufshci_prdt_entry { | |||||
| /* dword 0 */ | |||||
| uint32_t data_base_address; /* [31:0] */ | |||||
| /* dword 1 */ | |||||
| uint32_t data_base_address_upper; /* [31:0] */ | |||||
| /* dword 2 */ | |||||
| uint32_t reserved; /* [31:0] */ | |||||
| /* dword 3 */ | |||||
| uint32_t data_byte_count; /* [17:0] Maximum byte | |||||
| * count is 256KB */ | |||||
| } __packed __aligned(8); | |||||
| _Static_assert(sizeof(struct ufshci_prdt_entry) == 16, | |||||
| "ufshci_prdt_entry must be 16 bytes"); | |||||
| /* UFSHCI spec 4.0, section 6.1.2 "UTP Command Descriptor" */ | |||||
| struct ufshci_utp_cmd_desc { | |||||
| uint8_t command_upiu[UFSHCI_UTP_XFER_REQ_SIZE]; | |||||
| uint8_t response_upiu[UFSHCI_UTP_XFER_RESP_SIZE]; | |||||
| uint8_t prd_table[sizeof(struct ufshci_prdt_entry) * UFSHCI_MAX_PRDT_ENTRY_COUNT]; | |||||
| uint8_t padding[3072 - sizeof(struct ufshci_prdt_entry)]; | |||||
| } __packed __aligned(128); | |||||
| _Static_assert(sizeof(struct ufshci_utp_cmd_desc) == UFSHCI_UTP_COMMAND_DESCRIPTOR_SIZE, | |||||
| "ufshci_utp_cmd_desc must be 8192 bytes"); | |||||
| #define UFSHCI_UTP_TASK_MGMT_REQ_SIZE 32 | |||||
| #define UFSHCI_UTP_TASK_MGMT_RESP_SIZE 32 | |||||
| /* UFSHCI spec 4.0, section 6.3.1 "UTP Task Management Request Descriptor" */ | |||||
| struct ufshci_utp_task_mgmt_req_desc { | |||||
| /* dword 0 */ | |||||
| uint32_t reserved0:24; /* [23:0] */ | |||||
| uint32_t interrupt:1; /* [24] */ | |||||
| uint32_t reserved1:7; /* [31:25] */ | |||||
| /* dword 1 */ | |||||
| uint32_t reserved2; /* [31:0] */ | |||||
| /* dword 2 */ | |||||
| uint8_t overall_command_status; /* [7:0] */ | |||||
| uint8_t reserved3; /* [15:8] */ | |||||
| uint16_t reserved4; /* [31:16] */ | |||||
| /* dword 3 */ | |||||
| uint32_t reserved5; /* [31:0] */ | |||||
| /* dword 4-11 */ | |||||
| uint8_t request_upiu[UFSHCI_UTP_TASK_MGMT_REQ_SIZE]; | |||||
| /* dword 12-19 */ | |||||
| uint8_t response_upiu[UFSHCI_UTP_TASK_MGMT_RESP_SIZE]; | |||||
| } __packed __aligned(8); | |||||
| _Static_assert(sizeof(struct ufshci_utp_task_mgmt_req_desc) == 80, | |||||
| "ufshci_utp_task_mgmt_req_desc must be 80 bytes"); | |||||
| /* UFS spec 4.0, section 10.6.2 "Basic Header Format" */ | |||||
| struct ufshci_upiu_header { | |||||
| /* dword 0 */ | |||||
| union { | |||||
| struct { | |||||
| uint8_t trans_code:6; /* [5:0] */ | |||||
| uint8_t dd:1; /* [6] */ | |||||
| uint8_t hd:1; /* [7] */ | |||||
| }; | |||||
| uint8_t trans_type; | |||||
| }; | |||||
| union { | |||||
| struct { | |||||
| uint8_t task_attribute:2; /* [1:0] */ | |||||
| uint8_t cp:1; /* [2] */ | |||||
| uint8_t retransmit_indicator:1; /* [3] */ | |||||
| #define UFSHCI_OPERATIONAL_FLAG_W 0x2 | |||||
| #define UFSHCI_OPERATIONAL_FLAG_R 0x4 | |||||
| uint8_t operational_flags:4; /* [7:4] */ | |||||
| }; | |||||
| uint8_t flags; | |||||
| }; | |||||
| uint8_t lun; | |||||
| uint8_t task_tag; | |||||
| /* dword 1 */ | |||||
| #define UFSHCI_COMMAND_SET_TYPE_SCSI 0 | |||||
| uint8_t cmd_set_type:4; /* [3:0] */ | |||||
| uint8_t iid:4; /* [7:4] */ | |||||
| uint8_t ext_iid_or_function; | |||||
| uint8_t response; | |||||
| uint8_t ext_iid_or_status; | |||||
| /* dword 2 */ | |||||
| uint8_t ehs_length; | |||||
| uint8_t device_infomation; | |||||
| uint16_t data_segment_length; /* (Big-endian) */ | |||||
| } __packed __aligned(4); | |||||
| _Static_assert(sizeof(struct ufshci_upiu_header) == 12, | |||||
| "ufshci_upiu_header must be 12 bytes"); | |||||
| #define UFSHCI_MAX_UPIU_SIZE 512 | |||||
| #define UFSHCI_UPIU_ALIGNMENT 8 /* UPIU requires 64-bit alignment. */ | |||||
| struct ufshci_upiu { | |||||
| /* dword 0-2 */ | |||||
| struct ufshci_upiu_header header; | |||||
| /* dword 3-127 */ | |||||
| uint8_t reserved[UFSHCI_MAX_UPIU_SIZE - | |||||
| sizeof(struct ufshci_upiu_header)]; | |||||
| } __packed __aligned(8); | |||||
| _Static_assert(sizeof(struct ufshci_upiu) == 512, | |||||
| "ufshci_upiu must be 512 bytes"); | |||||
| struct ufshci_cmd_command_upiu { | |||||
| /* dword 0-2 */ | |||||
| struct ufshci_upiu_header header; | |||||
| /* dword 3 */ | |||||
| uint32_t expected_data_transfer_length; /* (Big-endian) */ | |||||
| /* dword 4-7 */ | |||||
| uint8_t cdb[16]; | |||||
| } __packed __aligned(4); | |||||
| _Static_assert(sizeof(struct ufshci_cmd_command_upiu) == 32, | |||||
| "bad size for ufshci_cmd_command_upiu"); | |||||
| _Static_assert(sizeof(struct ufshci_cmd_command_upiu) <= UFSHCI_UTP_XFER_REQ_SIZE, | |||||
| "bad size for ufshci_cmd_command_upiu"); | |||||
| _Static_assert(sizeof(struct ufshci_cmd_command_upiu) % UFSHCI_UPIU_ALIGNMENT == 0, | |||||
| "UPIU requires 64-bit alignment"); | |||||
| struct ufshci_cmd_response_upiu { | |||||
| /* dword 0-2 */ | |||||
| struct ufshci_upiu_header header; | |||||
| /* dword 3 */ | |||||
| uint32_t residual_transfer_count; /* (Big-endian) */ | |||||
| /* dword 4-7 */ | |||||
| uint8_t reserved[16]; | |||||
| /* Sense Data */ | |||||
| uint16_t sense_data_len; /* (Big-endian) */ | |||||
| uint8_t sense_data[18]; | |||||
| /* Add padding to align the kUpiuAlignment. */ | |||||
| uint8_t padding[4]; | |||||
| } __packed __aligned(4); | |||||
| _Static_assert(sizeof(struct ufshci_cmd_response_upiu) == 56, | |||||
| "bad size for ufshci_cmd_response_upiu"); | |||||
| _Static_assert(sizeof(struct ufshci_cmd_response_upiu) <= UFSHCI_UTP_XFER_RESP_SIZE, | |||||
| "bad size for ufshci_cmd_response_upiu"); | |||||
| _Static_assert(sizeof(struct ufshci_cmd_response_upiu) % UFSHCI_UPIU_ALIGNMENT == 0, | |||||
| "UPIU requires 64-bit alignment"); | |||||
| /* UFS Spec 4.0, section 10.7.8 "QUERY REQUEST UPIU". */ | |||||
| enum ufshci_query_function { | |||||
| UFSHCI_QUERY_FUNC_STANDARD_READ_REQUEST = 0x01, | |||||
| UFSHCI_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81, | |||||
| }; | |||||
| /* UFS Spec 4.0, section 10.7.8 "QUERY REQUEST UPIU". */ | |||||
| enum ufshci_query_opcode { | |||||
| UFSHCI_QUERY_OPCODE_NOP = 0, | |||||
| UFSHCI_QUERY_OPCODE_READ_DESCRIPTOR, | |||||
| UFSHCI_QUERY_OPCODE_WRITE_DESCRIPTOR, | |||||
| UFSHCI_QUERY_OPCODE_READ_ATTRIBUTE, | |||||
| UFSHCI_QUERY_OPCODE_WRITE_ATTRIBUTE, | |||||
| UFSHCI_QUERY_OPCODE_READ_FLAG, | |||||
| UFSHCI_QUERY_OPCODE_SET_FLAG, | |||||
| UFSHCI_QUERY_OPCODE_CLEAR_FLAG, | |||||
| UFSHCI_QUERY_OPCODE_TOGGLE_FLAG, | |||||
| }; | |||||
| struct ufshci_query_param { | |||||
| enum ufshci_query_function function; | |||||
| enum ufshci_query_opcode opcode; | |||||
| uint8_t type; | |||||
| uint8_t index; | |||||
| uint8_t selector; | |||||
| uint64_t value; | |||||
| size_t desc_size; | |||||
| }; | |||||
| struct ufshci_query_request_upiu { | |||||
| /* dword 0-2 */ | |||||
| struct ufshci_upiu_header header; | |||||
| /* dword 3 */ | |||||
| uint8_t opcode; | |||||
| uint8_t idn; | |||||
| uint8_t index; | |||||
| uint8_t selector; | |||||
| /* dword 4-5 */ | |||||
| union { | |||||
| /* The Write Attribute opcode uses 64 - bit value. */ | |||||
| uint64_t value_64; /* (Big-endian) */ | |||||
| struct { | |||||
| uint8_t reserved1[2]; | |||||
| uint16_t length; /* (Big-endian) */ | |||||
| uint32_t value_32; /* (Big-endian) */ | |||||
| }; | |||||
| } __packed __aligned(4); | |||||
Done Inline Actionswhy not uint32_t here and similar imp: why not uint32_t here and similar | |||||
| /* dword 6 */ | |||||
| uint8_t reserved2[4]; | |||||
| /* dword 7 */ | |||||
| uint8_t reserved3[4]; | |||||
| uint8_t command_data[256]; | |||||
| } __packed __aligned(4); | |||||
| _Static_assert(sizeof(struct ufshci_query_request_upiu) == 288, | |||||
| "bad size for ufshci_query_request_upiu"); | |||||
| _Static_assert(sizeof(struct ufshci_query_request_upiu) <= UFSHCI_UTP_XFER_REQ_SIZE, | |||||
| "bad size for ufshci_query_request_upiu"); | |||||
| _Static_assert(sizeof(struct ufshci_query_request_upiu) % UFSHCI_UPIU_ALIGNMENT == 0, | |||||
| "UPIU requires 64-bit alignment"); | |||||
| /* UFS Spec 4.0, section 10.7.9 "QUERY RESPONSE UPIU". */ | |||||
| enum ufshci_query_response_code { | |||||
| UFSHCI_QUERY_RESP_CODE_SUCCESS = 0x00, | |||||
| UFSHCI_QUERY_RESP_CODE_PARAMETER_NOT_READABLE = 0xf6, | |||||
| UFSHCI_QUERY_RESP_CODE_PARAMETER_NOT_WRITEABLE = 0xf7, | |||||
| UFSHCI_QUERY_RESP_CODE_PARAMETER_ALREADY_WRITTEN = 0xf8, | |||||
| UFSHCI_QUERY_RESP_CODE_INVALID_LENGTH = 0xf9, | |||||
| UFSHCI_QUERY_RESP_CODE_INVALID_VALUE = 0xfa, | |||||
| UFSHCI_QUERY_RESP_CODE_INVALID_SELECTOR = 0xfb, | |||||
| UFSHCI_QUERY_RESP_CODE_INVALID_INDEX = 0xfc, | |||||
| UFSHCI_QUERY_RESP_CODE_INVALID_IDN = 0xfd, | |||||
| UFSHCI_QUERY_RESP_CODE_INVALID_OPCODE = 0xfe, | |||||
| UFSHCI_QUERY_RESP_CODE_GENERAL_FAILURE = 0xff, | |||||
| }; | |||||
| struct ufshci_query_response_upiu { | |||||
| /* dword 0-2 */ | |||||
| struct ufshci_upiu_header header; | |||||
| /* dword 3 */ | |||||
| uint8_t opcode; | |||||
| uint8_t idn; | |||||
| uint8_t index; | |||||
| uint8_t selector; | |||||
| /* dword 4-5 */ | |||||
| union { | |||||
| /* The Read / Write Attribute opcodes use 64 - bit value. */ | |||||
| uint64_t value_64; /* (Big-endian) */ | |||||
| struct { | |||||
| uint8_t reserved1[2]; | |||||
| uint16_t length; /* (Big-endian) */ | |||||
| union { | |||||
| uint32_t value_32; /* (Big-endian) */ | |||||
| struct { | |||||
| uint8_t reserved2[3]; | |||||
| uint8_t flag_value; | |||||
| }; | |||||
| }; | |||||
| }; | |||||
| } __packed __aligned(4); | |||||
| /* dword 6 */ | |||||
| uint8_t reserved3[4]; | |||||
| /* dword 7 */ | |||||
| uint8_t reserved4[4]; | |||||
| uint8_t command_data[256]; | |||||
| } __packed __aligned(4); | |||||
| _Static_assert(sizeof(struct ufshci_query_response_upiu) == 288, | |||||
| "bad size for ufshci_query_response_upiu"); | |||||
| _Static_assert(sizeof(struct ufshci_query_response_upiu) <= UFSHCI_UTP_XFER_RESP_SIZE, | |||||
| "bad size for ufshci_query_response_upiu"); | |||||
| _Static_assert(sizeof(struct ufshci_query_response_upiu) % UFSHCI_UPIU_ALIGNMENT == 0, | |||||
| "UPIU requires 64-bit alignment"); | |||||
| /* UFS 4.0, section 10.7.11 "NOP OUT UPIU" */ | |||||
| struct ufshci_nop_out_upiu { | |||||
| /* dword 0-2 */ | |||||
| struct ufshci_upiu_header header; | |||||
| /* dword 3-7 */ | |||||
| uint8_t reserved[20]; | |||||
| } __packed __aligned(8); | |||||
| _Static_assert(sizeof(struct ufshci_nop_out_upiu) == 32, | |||||
| "ufshci_upiu_nop_out must be 32 bytes"); | |||||
| /* UFS 4.0, section 10.7.12 "NOP IN UPIU" */ | |||||
| struct ufshci_nop_in_upiu { | |||||
| /* dword 0-2 */ | |||||
| struct ufshci_upiu_header header; | |||||
| /* dword 3-7 */ | |||||
| uint8_t reserved[20]; | |||||
| } __packed __aligned(8); | |||||
| _Static_assert(sizeof(struct ufshci_nop_in_upiu) == 32, | |||||
| "ufshci_upiu_nop_in must be 32 bytes"); | |||||
| union ufshci_reponse_upiu { | |||||
| struct ufshci_upiu_header header; | |||||
| struct ufshci_cmd_response_upiu cmd_response_upiu; | |||||
| struct ufshci_query_response_upiu query_response_upiu; | |||||
| struct ufshci_nop_in_upiu nop_in_upiu; | |||||
| }; | |||||
| struct ufshci_completion { | |||||
| union ufshci_reponse_upiu response_upiu; | |||||
| size_t size; | |||||
| }; | |||||
| typedef void (*ufshci_cb_fn_t) (void *, const struct ufshci_completion *, bool); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1 "UFS Descriptors". All descriptors use | |||||
| * big-endian byte ordering. | |||||
| */ | |||||
| enum ufshci_descriptor_type { | |||||
| UFSHCI_DESC_TYPE_DEVICE = 0x00, | |||||
| UFSHCI_DESC_TYPE_CONFIGURATION = 0x01, | |||||
| UFSHCI_DESC_TYPE_UNIT = 0x02, | |||||
| UFSHCI_DESC_TYPE_INTERCONNECT = 0x04, | |||||
| UFSHCI_DESC_TYPE_STRING = 0x05, | |||||
| UFSHCI_DESC_TYPE_GEOMETRY = 0X07, | |||||
| UFSHCI_DESC_TYPE_POWER = 0x08, | |||||
| UFSHCI_DESC_TYPE_DEVICE_HEALTH = 0x09, | |||||
| UFSHCI_DESC_TYPE_FBO_EXTENSION_SPECIFICATION = 0x0a, | |||||
| }; | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.2 "Device Descriptor". DeviceDescriptor use | |||||
| * big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_device_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint8_t bDevice; | |||||
| uint8_t bDeviceClass; | |||||
| uint8_t bDeviceSubClass; | |||||
| uint8_t bProtocol; | |||||
| uint8_t bNumberLU; | |||||
| uint8_t bNumberWLU; | |||||
| uint8_t bBootEnable; | |||||
| uint8_t bDescrAccessEn; | |||||
| uint8_t bInitPowerMode; | |||||
| uint8_t bHighPriorityLUN; | |||||
| uint8_t bSecureRemovalType; | |||||
| uint8_t bSecurityLU; | |||||
| uint8_t bBackgroundOpsTermLat; | |||||
| uint8_t bInitActiveICCLevel; | |||||
| /* 0x10 */ | |||||
| uint16_t wSpecVersion; | |||||
| uint16_t wManufactureDate; | |||||
| uint8_t iManufacturerName; | |||||
| uint8_t iProductName; | |||||
| uint8_t iSerialNumber; | |||||
| uint8_t iOemID; | |||||
| uint16_t wManufacturerID; | |||||
| uint8_t bUD0BaseOffset; | |||||
| uint8_t bUDConfigPLength; | |||||
| uint8_t bDeviceRTTCap; | |||||
| uint16_t wPeriodicRTCUpdate; | |||||
| uint8_t bUfsFeaturesSupport; | |||||
| /* 0x20 */ | |||||
| uint8_t bFFUTimeout; | |||||
| uint8_t bQueueDepth; | |||||
| uint16_t wDeviceVersion; | |||||
| uint8_t bNumSecureWPArea; | |||||
| uint32_t dPSAMaxDataSize; | |||||
| uint8_t bPSAStateTimeout; | |||||
| uint8_t iProductRevisionLevel; | |||||
| uint8_t Reserved[5]; | |||||
| /* 0x2a */ | |||||
| /* 0x30 */ | |||||
| uint8_t ReservedUME[16]; | |||||
| /* UFS 4.0 Start:0x40 */ | |||||
| uint8_t ReservedHpb[3]; | |||||
| uint8_t Reserved2[12]; | |||||
| uint32_t dExtendedUfsFeaturesSupport; | |||||
| uint8_t bWriteBoosterBufferPreserveUserSpaceEn; | |||||
| uint8_t bWriteBoosterBufferType; | |||||
| uint32_t dNumSharedWriteBoosterBufferAllocUnits; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_device_descriptor) == 89, | |||||
| "bad size for ufshci_device_descriptor"); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.3 "Configuration Descriptor". | |||||
| * ConfigurationDescriptor use big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_unit_descriptor_configurable_parameters { | |||||
| uint8_t bLUEnable; | |||||
| uint8_t bBootLunID; | |||||
| uint8_t bLUWriteProtect; | |||||
| uint8_t bMemoryType; | |||||
| uint32_t dNumAllocUnits; | |||||
| uint8_t bDataReliability; | |||||
| uint8_t bLogicalBlockSize; | |||||
| uint8_t bProvisioningType; | |||||
| uint16_t wContextCapabilities; | |||||
| union { | |||||
| struct { | |||||
| uint8_t Reserved[3]; | |||||
| uint8_t ReservedHpb[6]; | |||||
| } __packed; | |||||
| uint16_t wZoneBufferAllocUnits; | |||||
| }; | |||||
| uint32_t dLUNumWriteBoosterBufferAllocUnits; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_unit_descriptor_configurable_parameters) == 27, | |||||
| "bad size for ufshci_unit_descriptor_configurable_parameters"); | |||||
| #define UFSHCI_CONFIGURATION_DESCEIPTOR_LU_NUM 8 | |||||
| struct ufshci_configuration_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint8_t bConfDescContinue; | |||||
| uint8_t bBootEnable; | |||||
| uint8_t bDescrAccessEn; | |||||
| uint8_t bInitPowerMode; | |||||
| uint8_t bHighPriorityLUN; | |||||
| uint8_t bSecureRemovalType; | |||||
| uint8_t bInitActiveICCLevel; | |||||
| uint16_t wPeriodicRTCUpdate; | |||||
| uint8_t Reserved; | |||||
| uint8_t bRPMBRegionEnable; | |||||
| uint8_t bRPMBRegion1Size; | |||||
| uint8_t bRPMBRegion2Size; | |||||
| uint8_t bRPMBRegion3Size; | |||||
| uint8_t bWriteBoosterBufferPreserveUserSpaceEn; | |||||
| uint8_t bWriteBoosterBufferType; | |||||
| uint32_t dNumSharedWriteBoosterBufferAllocUnits; | |||||
| /* 0x16 */ | |||||
| struct ufshci_unit_descriptor_configurable_parameters | |||||
| unit_config_params[UFSHCI_CONFIGURATION_DESCEIPTOR_LU_NUM]; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_configuration_descriptor) == (22 + 27 * 8), | |||||
| "bad size for ufshci_configuration_descriptor"); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.4 "Geometry Descriptor". GeometryDescriptor | |||||
| * use big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_geometry_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint8_t bMediaTechnology; | |||||
| uint8_t Reserved; | |||||
| uint64_t qTotalRawDeviceCapacity; | |||||
| uint8_t bMaxNumberLU; | |||||
| uint32_t dSegmentSize; | |||||
| /* 0x11 */ | |||||
| uint8_t bAllocationUnitSize; | |||||
| uint8_t bMinAddrBlockSize; | |||||
| uint8_t bOptimalReadBlockSize; | |||||
| uint8_t bOptimalWriteBlockSize; | |||||
| uint8_t bMaxInBufferSize; | |||||
| uint8_t bMaxOutBufferSize; | |||||
| uint8_t bRPMB_ReadWriteSize; | |||||
| uint8_t bDynamicCapacityResourcePolicy; | |||||
| uint8_t bDataOrdering; | |||||
| uint8_t bMaxContexIDNumber; | |||||
| uint8_t bSysDataTagUnitSize; | |||||
| uint8_t bSysDataTagResSize; | |||||
| uint8_t bSupportedSecRTypes; | |||||
| uint16_t wSupportedMemoryTypes; | |||||
| /* 0x20 */ | |||||
| uint32_t dSystemCodeMaxNAllocU; | |||||
| uint16_t wSystemCodeCapAdjFac; | |||||
| uint32_t dNonPersistMaxNAllocU; | |||||
| uint16_t wNonPersistCapAdjFac; | |||||
| uint32_t dEnhanced1MaxNAllocU; | |||||
| /* 0x30 */ | |||||
| uint16_t wEnhanced1CapAdjFac; | |||||
| uint32_t dEnhanced2MaxNAllocU; | |||||
| uint16_t wEnhanced2CapAdjFac; | |||||
| uint32_t dEnhanced3MaxNAllocU; | |||||
| uint16_t wEnhanced3CapAdjFac; | |||||
| uint32_t dEnhanced4MaxNAllocU; | |||||
| /* 0x42 */ | |||||
| uint16_t wEnhanced4CapAdjFac; | |||||
| uint32_t dOptimalLogicalBlockSize; | |||||
| /* UFS 4.0 Start:0x48 */ | |||||
| uint8_t ReservedHpb[5]; | |||||
| uint8_t Reserved2[2]; | |||||
| uint32_t dWriteBoosterBufferMaxNAllocUnits; | |||||
| uint8_t bDeviceMaxWriteBoosterLUs; | |||||
| uint8_t bWriteBoosterBufferCapAdjFac; | |||||
| uint8_t bSupportedWriteBoosterBufferUserSpaceReductionTypes; | |||||
| uint8_t bSupportedWriteBoosterBufferTypes; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_geometry_descriptor) == 87, | |||||
| "bad size for ufshci_geometry_descriptor"); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.5 "Unit Descriptor". UnitDescriptor use | |||||
| * big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_unit_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint8_t bUnitIndex; | |||||
| uint8_t bLUEnable; | |||||
| uint8_t bBootLunID; | |||||
| uint8_t bLUWriteProtect; | |||||
| uint8_t bLUQueueDepth; | |||||
| uint8_t bPSASensitive; | |||||
| uint8_t bMemoryType; | |||||
| uint8_t bDataReliability; | |||||
| uint8_t bLogicalBlockSize; | |||||
| uint64_t qLogicalBlockCount; | |||||
| /* 0x13 */ | |||||
| uint32_t dEraseBlockSize; | |||||
| uint8_t bProvisioningType; | |||||
| uint64_t qPhyMemResourceCount; | |||||
| /* 0x20 */ | |||||
| uint16_t wContextCapabilities; | |||||
| uint8_t bLargeUnitGranularity_M1; | |||||
| /* UFS 4.0 Start:0x23 */ | |||||
| uint8_t ReservedHpb[6]; | |||||
| uint32_t dLUNumWriteBoosterBufferAllocUnits; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_unit_descriptor) == 45, | |||||
| "bad size for ufshci_unit_descriptor"); | |||||
| enum LUWriteProtect { | |||||
| kNoWriteProtect = 0x00, | |||||
| kPowerOnWriteProtect = 0x01, | |||||
| kPermanentWriteProtect = 0x02, | |||||
| }; | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.6 "RPMB Unit Descriptor". RpmbUnitDescriptor | |||||
| * use big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_rpmb_unit_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint8_t bUnitIndex; | |||||
| uint8_t bLUEnable; | |||||
| uint8_t bBootLunID; | |||||
| uint8_t bLUWriteProtect; | |||||
| uint8_t bLUQueueDepth; | |||||
| uint8_t bPSASensitive; | |||||
| uint8_t bMemoryType; | |||||
| uint8_t Reserved; | |||||
| uint8_t bLogicalBlockSize; | |||||
| uint64_t qLogicalBlockCount; | |||||
| /* 0x13 */ | |||||
| uint32_t dEraseBlockSize; | |||||
| uint8_t bProvisioningType; | |||||
| uint64_t qPhyMemResourceCount; | |||||
| /* 0x20 */ | |||||
| uint8_t Reserved1[3]; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_rpmb_unit_descriptor) == 35, | |||||
| "bad size for RpmbUnitDescriptor"); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.7 "Power Parameters Descriptor". | |||||
| * PowerParametersDescriptor use big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_power_parameters_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint16_t wActiveICCLevelsVCC[16]; | |||||
| uint16_t wActiveICCLevelsVCCQ[16]; | |||||
| uint16_t wActiveICCLevelsVCCQ2[16]; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_power_parameters_descriptor) == 98, | |||||
| "bad size for PowerParametersDescriptor"); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.8 "Interconnect Descriptor". | |||||
| * InterconnectDescriptor use big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_interconnect_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint16_t bcdUniproVersion; | |||||
| uint16_t bcdMphyVersion; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_interconnect_descriptor) == 6, | |||||
| "bad size for InterconnectDescriptor"); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.9-13 "String Descriptor". StringDescriptor | |||||
| * use big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_string_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint16_t UC[126]; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_string_descriptor) == 254, | |||||
| "bad size for StringDescriptor"); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.14 "Device Health Descriptor". | |||||
| * DeviceHealthDescriptor use big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_device_healthd_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint8_t bPreEOLInfo; | |||||
| uint8_t bDeviceLifeTimeEstA; | |||||
| uint8_t bDeviceLifeTimeEstB; | |||||
| uint8_t VendorPropInfo[32]; | |||||
| uint32_t dRefreshTotalCount; | |||||
| uint32_t dRefreshProgress; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_device_healthd_descriptor) == 45, | |||||
| "bad size for DeviceHealthDescriptor"); | |||||
| /* | |||||
| * UFS Spec 4.0, section 14.1.4.15 "Vendor Specific Descriptor". | |||||
| * VendorSpecificDescriptor use big-endian byte ordering. | |||||
| */ | |||||
| struct ufshci_vendor_specific_descriptor { | |||||
| uint8_t bLength; | |||||
| uint8_t bDescriptorIDN; | |||||
| uint8_t DATA[254]; | |||||
| } __packed; | |||||
| _Static_assert(sizeof(struct ufshci_vendor_specific_descriptor) == 256, | |||||
| "bad size for VendorSpecificDescriptor"); | |||||
Done Inline Actionswhy did you choose to assign all of the _attributes, but not the flags? imp: why did you choose to assign all of the _attributes, but not the flags? | |||||
Done Inline ActionsI also added assign to all of the flags. jaeyoon: I also added assign to all of the flags. | |||||
| /* UFS Spec 4.0, section 14.2 "Flags". */ | |||||
| enum ufshci_flags { | |||||
| UFSHCI_FLAG_F_RESERVED = 0x0, | |||||
| UFSHCI_FLAG_F_DEVICE_INIT = 0x1, | |||||
| UFSHCI_FLAG_F_PERMANENT_WP_EN, | |||||
| UFSHCI_FLAS_F_POWER_ON_WP_EN, | |||||
| UFSHCI_FLAG_F_BACKGROUND_OPS_EN, | |||||
| UFSHCI_FLAG_F_DEVICE_LIFE_SPAN_MODE_EN, | |||||
| UFSHCI_FLAG_F_PURGE_ENABLE, | |||||
| UFSHCI_FLAG_F_PHY_RESOURCE_REMOVAL = 0x8, | |||||
| UFSHCI_FLAG_F_BUSY_RTC, | |||||
| UFSHCI_FLAG_F_PERMANENTLY_DISABLE_FW_UPDATE = 0xb, | |||||
| UFSHCI_FLAG_F_WRITE_BOOSTER_EN = 0xe, | |||||
| UFSHCI_FLAG_F_WB_BUFFER_FLUSH_EN = 0xf, | |||||
| UFSHCI_FLAG_F_WB_BUFFER_FLUSH_DURING_HIBERNATE = 0x10, | |||||
| UFSHCI_FLAG_FLAG_COUNT = 0x11, | |||||
| }; | |||||
| /* UFS Spec 4.0, section 14.3 "Attributes". */ | |||||
| enum ufshci_attributes { | |||||
| UFSHCI_ATTR_B_BOOT_LUN_EN = 0x00, | |||||
| UFSHCI_ATTR_B_CURRENT_POWER_MODE = 0x02, | |||||
| UFSHCI_ATTR_B_ACTIVE_ICC_LEVEL = 0x03, | |||||
| UFSHCI_ATTR_B_OUT_OF_ORDER_DATA_EN = 0x04, | |||||
| UFSHCI_ATTR_B_BACKGROUND_OP_STATUS = 0x05, | |||||
| UFSHCI_ATTR_B_PURGE_STATUS = 0x06, | |||||
| UFSHCI_ATTR_B_MAX_DATA_IN_SIZE = 0x07, | |||||
| UFSHCI_ATTR_B_MAX_DATA_OUT_SIZE = 0x08, | |||||
| UFSHCI_ATTR_D_DYN_CAP_NEEDED = 0x09, | |||||
| UFSHCI_ATTR_B_REF_CLK_FREQ = 0x0a, | |||||
| UFSHCI_ATTR_B_CONFIG_DESCR_LOCK = 0x0b, | |||||
| UFSHCI_ATTR_B_MAX_NUM_OF_RTT = 0x0c, | |||||
| UFSHCI_ATTR_W_EXCEPTION_EVENT_CONTROL = 0x0d, | |||||
| UFSHCI_ATTR_W_EXCEPTION_EVENT_STATUS = 0x0e, | |||||
| UFSHCI_ATTR_D_SECONDS_PASSED = 0x0f, | |||||
| UFSHCI_ATTR_W_CONTEXT_CONF = 0x10, | |||||
| UFSHCI_ATTR_B_DEVICE_FFU_STATUS = 0x14, | |||||
| UFSHCI_ATTR_B_PSA_STATE = 0x15, | |||||
| UFSHCI_ATTR_D_PSA_DATA_SIZE = 0x16, | |||||
| UFSHCI_ATTR_B_REF_CLK_GATING_WAIT_TIME = 0x17, | |||||
| UFSHCI_ATTR_B_DEVICE_CASE_ROUGH_TEMPERAURE = 0x18, | |||||
| UFSHCI_ATTR_B_DEVICE_TOO_HIGH_TEMP_BOUNDARY = 0x19, | |||||
| UFSHCI_ATTR_B_DEVICE_TOO_LOW_TEMP_BOUNDARY = 0x1a, | |||||
| UFSHCI_ATTR_B_THROTTLING_STATUS = 0x1b, | |||||
| UFSHCI_ATTR_B_WB_BUFFER_FLUSH_STATUS = 0x1c, | |||||
| UFSHCI_ATTR_B_AVAILABLE_WB_BUFFER_SIZE = 0x1d, | |||||
| UFSHCI_ATTR_B_WB_BUFFER_LIFE_TIME_EST = 0x1e, | |||||
| UFSHCI_ATTR_D_CURRENT_WB_BUFFER_SIZE = 0x1f, | |||||
| UFSHCI_ATTR_B_REFRESH_STATUS = 0x2c, | |||||
| UFSHCI_ATTR_B_REFRESH_FREQ = 0x2d, | |||||
| UFSHCI_ATTR_B_REFRESH_UNIT = 0x2e, | |||||
| UFSHCI_ATTR_B_REFRESH_METHOD = 0x2f, | |||||
| UFSHCI_ATTR_K_ATTRIBUTE_COUNT = 0x30, | |||||
| }; | |||||
| #endif /* __UFSHCI_H__ */ | |||||
We have new, streamlined rules. Of course you're allowed to use the long form, but since you are using the SPDX-License-Idendifier, you may omit it. Don't know if this went through sumsung legal or not, but the project doesn't require the boilerplate anymore.
Also, unless Samsung requires it, All Rights Reserved can be omitted. It's all about an obsolete latin American treaty that's been out of relevance for 25 or more years.
Same comment generally everwhere, I'm just going to say it here.