ATF UFS初始化笔记

1. JESD220 中关于UFS初始化的描述

原文

13.1.3 Initialization and boot code download process
The initialization and boot code download process is made up of the following phases: partial initialization, boot transfer and initialization completion.

13.1.3.1 Partial initialization
The partial initialization phase starts after power on, or hardware reset, or EndPointReset and involves the entire UFS stack. At the end of this phase, the UniPro boot sequence shall be completed, and the UTP layer shall be capable of accessing Device Descriptor (if the bDescrAccessEn field of the Device Descriptor is ‘01h’) and exchanging UPIU for READ command and TEST UNIT READY command. If the bDescrAccessEn field is ‘00h‘ descriptors will be accessible only after the initialization completion phase. Each single layer in the UFS protocol stack executes the initialization process on both UFS host and UFS device sides.

a) Physical Layer (M-PHY) --> No SW action.
After reset events, the physical layer will move from DISABLED state to HIBERN8 state.

b) Link Layer (UniPro)
On host and device side UniPro boot sequence takes place:

c) UFS Transport Layer (UTP)
At the end of the UFS Interconnect Layer initialization on both host and device side, the host shall send a NOP OUT UPIU to verify that the device UTP Layer is ready. For some implementations, the device UTP layer may not be initialized yet, therefore the device may not respond promptly to NOP OUT UPIU sending NOP IN UPIU. The host waits until it receives the NOP IN UPIU from the device. When the NOP IN UPIU is received, the host is acknowledged that the UTP layer on the device is ready to execute UTP transactions.
ufs_check_resp(&utrd, NOP_IN_UPIU, NOP_OUT_TIMEOUT_MS);

d) Link Configuration
The host may configure the Link Attributes (i.e., Gear, HS Series, PWM Mode in Rx and Tx) by using DME primitives at UniPro level.

e) Device Descriptor Reading
The UFS host may optionally discover relevant device info for the boot process by accessing the Device Descriptor (i.e., Device Class/Subclass, Boot Enable, Boot LUs size, etc.). The UFS host is allowed to access the Device Descriptor only if the bDescrAccessEn is ‘01h’, otherwise this descriptor can be accessed only after the device has fully completed its initialization.

13.1.3.2 Boot transfer
The following steps can be executed only if bBootEnable field is set.

13.1.3.3 Initialization completion
After the host has completed the boot code download from the Boot well known logical unit, the initialization process proceeds as described in the following. The host sets the fDeviceInit flag to “01h” to communicate to the UFS device that it can complete its initialization. The device shall reset the fDeviceInit flag when the initialization is complete. The host polls the fDeviceInit flag to check the completion of the process. When the fDeviceInit is reset, the device is ready to accept any command.

翻译

UFS 学习笔记(功能认识篇) 有中文版。以下内容摘自UFS 学习笔记(功能认识篇)
3.1 部分初始化
部分初始化阶段在上电、硬件复位或端点复位之后开始,并涉及整个 UFS 堆栈。在此阶段结束时,应完成 UniPro 引导序列,并且UTP层应能够访问设备描述符(如果设备描述符的 bDescrAccessEn(描述符访问使能)字段为 01h)并交换读取命令和测试单元就绪命令的 UPIU。如果 bDescrAccessEn 字段为 00h,则只有在初始化完成阶段之后才能访问描述符。UFS 协议堆栈中的每个单独层在 UFS 主机和 UFS 设备两侧执行初始化过程。

a) 物理层(M-PHY)

复位事件后,物理层将从 DISABLED 状态转移到 HIBERN8 状态。

b) 链路层(UniPro)

在主机和设备端进行 UniPro 引导序列:

使用 DME_RESET.req 原语重置 UniPro 堆栈;
等待通过 DME_RESET.cnf_L 原语指示的复位完成;
使用 DME_ENABLE.req 原语启用 UniPro 堆栈;
等待通过 DME_ENABLE.cnf_L 原语指示的启用完成;
使用 DME_LINKSTARTUP.req 原语启动 UniPro 链路启动序列。UniPro 链路启动由一系列多相握手组成,以在 UFS 主机和设备之间建立初始双向链路通信;
等待通过 DME_LINKSTARTUP.cnf_L 原语指示的链路启动完成。

c) UFS传输层(UTP)

在主机和设备两侧的 UFS 互连层初始化结束后,主机应发送 NOP OUT UPIU 以验证设备的 UTP 层是否就绪。对于某些实现,设备的 UTP 层可能尚未初始化,因此设备可能无法及时响应 NOP OUT UPIU,并发送 NOP IN UPIU。主机等待接收到设备的 NOP IN UPIU。当接收到 NOP IN UPIU 时,主机确认设备的 UTP 层已准备好执行 UTP 事务。

d) 链路配置

主机可以使用 UniPro 级别的 DME 原语配置链路属性(如 Gear、HS Series、PWM Mode 在 Rx 和 Tx 中)。

e) 设备描述符读取

UFS 主机可以通过访问设备描述符(如设备类/子类、引导使能、引导 LU 大小等)来可选地发现引导过程的相关设备信息。只有在 bDescrAccessEn 为‘01h’时,UFS 主机才允许访问设备描述符,否则此描述符只能在设备完全完成初始化后才能访问。

3.2 引导传输(可选)
仅当 bBootEnable 字段设置时,才执行引导代码下载:

首先,UFS 主机向 Boot 固定逻辑单元发出 TEST UNIT READY 命令,以验证是否可以访问后者。如果命令成功,UFS 主机通过发出 SCSI READ 命令读取 Boot 固定逻辑单元,而 UFS 设备将开始在上行链路上发送引导代码。在此阶段,仅 Boot 固定逻辑单元可访问:该逻辑单元应接受读取命令,而其他逻辑单元可能尚未准备好。

3.3 初始化完成
在主机从 Boot 固定逻辑单元完成引导代码下载后,初始化过程按照以下描述继续进行。主机将 fDeviceInit 标志设置为“01h”,以向 UFS 设备通信,表示它可以完成其初始化。当初始化完成时,设备应将 fDeviceInit 标志复位。主机轮询 fDeviceInit 标志以检查进程的完成情况。当 fDeviceInit 被复位时,设备准备好接受任何。

在这里插入图片描述

2.ATF中代码与协议中的实现

田园诗人之园的ATF BL1 UFS初始化简单分析 中分析了ATF中UFS驱动初始化的流程。
田园诗人之园的ATF bl1 ufshc_dme_get/set处理流程分析分析了ATF DME操作是如何完成的。
这里就不做流程分析了,而是看一看ATF UFS驱动中是如何和JESD 220协议中的内容一一对应实现的。

a) 物理层(M-PHY)

物理层的初始化没有代码来控制,这部分是硬件实现的。

b) 链路层(UniPro)

在主机和设备端进行 UniPro 引导序列:

  • 使用 DME_RESET.req 原语重置 UniPro 堆栈;
  • 等待通过 DME_RESET.cnf_L 原语指示的复位完成;
  • 使用 DME_ENABLE.req 原语启用 UniPro 堆栈;
  • 等待通过 DME_ENABLE.cnf_L 原语指示的启用完成;
    在ATF中ufs_init–>ufshc_reset实现了这个操作。软件这边主要通过操作HCE寄存器的HCE_ENABLE位来实现UNIPRO的reset, 代码片段如下。
static int ufshc_reset(uintptr_t base)
{..../* disable controller if enabled */if (mmio_read_32(base + HCE) & HCE_ENABLE) {result = ufshc_hce_disable(base);...}for (retries = 0; retries < HCE_ENABLE_OUTER_RETRIES; ++retries) {result = ufshc_hce_enable(base);}...
}

下图是HCE寄存器的定义。
HCE寄存器定义

  • 使用 DME_LINKSTARTUP.req 原语启动 UniPro 链路启动序列。UniPro 链路启动由一系列多相握手组成,以在 UFS 主机和设备之间建立初始双向链路通信;
  • 等待通过 DME_LINKSTARTUP.cnf_L 原语指示的链路启动完成。
    ATF UFS驱动在ufs_init–>ufshc_link_startup中实现了这个逻辑
static int ufshc_link_startup(uintptr_t base)
{int data, result;int retries;for (retries = DME_LINKSTARTUP_RETRIES; retries > 0; retries--) {result = ufshc_dme_link_startup(base);if (result != 0) {/* Reset controller before trying again */result = ufshc_reset(base);...}assert(mmio_read_32(base + HCS) & HCS_DP);data = mmio_read_32(base + IS);if (data & UFS_INT_ULSS)mmio_write_32(base + IS, UFS_INT_ULSS);/* clear UE set due to line-reset */if (data & UFS_INT_UE) {mmio_write_32(base + IS, UFS_INT_UE);}/* clearing line-reset, UECPA is cleared on read */mmio_read_32(base + UECPA);return 0;}return -EIO;
}

ufshc_dme_link_startup实现非常简单,就是调用了UFSHC DME的寄存器发送了DME_LINKSTARTUP的UIC opcode给UNIPRO,使能链路层。

static int ufshc_dme_link_startup(uintptr_t base)
{uic_cmd_t cmd;memset(&cmd, 0, sizeof(cmd));cmd.op = DME_LINKSTARTUP;return ufshc_send_uic_cmd(base, &cmd);
}

c) UFS传输层(UTP)

UTP初始化需要主机发送NOP OUT UPIU给设备,然后设备返回正确的NOP IN UPIU给主机。在ATF中实现的代码在ufs_init–>ufs_enum–>ufs_verify_init中。

static void ufs_verify_init(void)
{utp_utrd_t utrd;int result;//初始化一个NOP OUT UPIU并发送给设备get_utrd(&utrd);ufs_prepare_nop_out(&utrd);ufs_send_request(utrd.task_tag);//接收NOP IN UPIUAQ	result = ufs_check_resp(&utrd, NOP_IN_UPIU, NOP_OUT_TIMEOUT_MS);assert(result == 0);(void)result;
}

d) 链路配置

主机可以使用 UniPro 级别的 DME 原语配置链路属性(如 Gear、HS Series、PWM Mode 在 Rx 和 Tx 中)
链路配置主要在dwufs_phy_initdwufs_phy_set_pwr_mode中实现。

static int dwufs_phy_init(ufs_params_t *params)
{.../* Unipro VS_MPHY disable */ufshc_dme_set(VS_MPHY_DISABLE_OFFSET, 0, VS_MPHY_DISABLE_MPHYDIS); //Disable MPHY//选择HS-Gear的模式,HS-Gear有Series A和B选,可以看下面的图。//以下是UNIPRO中的Attribute模式原文:Phy Adapter 5.8 TX and RX Frequency Series in High Speed Mode A=1 B=2ufshc_dme_set(PA_HS_SERIES_OFFSET, 0, 2);

HS Gear模式

	//下面这些hardcode的0x81**的Attribute可能是kirin960芯片里UFS PHY特有的Attribute,在UNIPRO和MPHY中协议中没找到,我也不知道具体的bit是指代什么/* MPHY CBRATESEL */ufshc_dme_set(0x8114, 0, 1);				/* MPHY CBOVRCTRL2 */ufshc_dme_set(0x8121, 0, 0x2d);/* MPHY CBOVRCTRL3 */ufshc_dme_set(0x8122, 0, 0x1);ufshc_dme_set(VS_MPHY_CFG_UPDT_OFFSET, 0, 1);/* MPHY RXOVRCTRL4 rx0 */ufshc_dme_set(0x800d, 4, 0x58);/* MPHY RXOVRCTRL4 rx1 */ufshc_dme_set(0x800d, 5, 0x58);/* MPHY RXOVRCTRL5 rx0 */ufshc_dme_set(0x800e, 4, 0xb);/* MPHY RXOVRCTRL5 rx1 */ufshc_dme_set(0x800e, 5, 0xb);/* MPHY RXSQCONTROL rx0 */ufshc_dme_set(0x8009, 4, 0x1);/* MPHY RXSQCONTROL rx1 */ufshc_dme_set(0x8009, 5, 0x1);ufshc_dme_set(VS_MPHY_CFG_UPDT_OFFSET, 0, 1);ufshc_dme_set(0x8113, 0, 0x1);ufshc_dme_set(VS_MPHY_CFG_UPDT_OFFSET, 0, 1);
	//配置RX_HS_G3_SYNC_LENGTH_Capability, RX_HS_G2_SYNC_LENGTH_Capability, //RX_Min_ActivateTime_Capability和TX_Hibern8Time_Capability Attributeufshc_dme_set(RX_HS_G3_SYNC_LENGTH_CAP_OFFSET, 4, 0x4a);ufshc_dme_set(RX_HS_G3_SYNC_LENGTH_CAP_OFFSET, 5, 0x4a);ufshc_dme_set(RX_HS_G2_SYNC_LENGTH_CAP_OFFSET, 4, 0x4a);ufshc_dme_set(RX_HS_G2_SYNC_LENGTH_CAP_OFFSET, 5, 0x4a);ufshc_dme_set(RX_MIN_ACTIVATETIME_CAP_OFFSET, 4, 0x7);ufshc_dme_set(RX_MIN_ACTIVATETIME_CAP_OFFSET, 5, 0x7);ufshc_dme_set(TX_HIBERN8TIME_CAP_OFFSET, 0, 0x5);ufshc_dme_set(TX_HIBERN8TIME_CAP_OFFSET, 1, 0x5);ufshc_dme_set(VS_MPHY_CFG_UPDT_OFFSET, 0, 1);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

	ufshc_dme_set(PA_LOCAL_TX_LCC_ENABLE_OFFSET, 0, 0);

在这里插入图片描述
这个在UNIPRO和MPHY协议中没找到。VS_MK2_EXTN_SUPPORT_OFFSET 0xD0AB。感觉是使能某个硬件。

	ufshc_dme_set(VS_MK2_EXTN_SUPPORT_OFFSET, 0, 0);result = ufshc_dme_get(VS_MK2_EXTN_SUPPORT_OFFSET, 0, &data);assert((result == 0) && (data == 0));
	ufshc_dme_set(DL_AFC0_CREDIT_THRESHOLD_OFFSET, 0, 0);ufshc_dme_set(DL_TC0_OUT_ACK_THRESHOLD_OFFSET, 0, 0);ufshc_dme_set(DL_TC0_TX_FC_THRESHOLD_OFFSET, 0, 9);(void)result;return 0;
}

在这里插入图片描述

在这里插入图片描述
0xd0a0和0x1556这两个Attribute在UNIPRO和MPHY协议中没找到

static int dwufs_phy_set_pwr_mode(ufs_params_t *params)
{....if ((flags & UFS_FLAGS_VENDOR_SKHYNIX) != 0U) {NOTICE("ufs: H**** device must set VS_DebugSaveConfigTime 0x10\n");/* VS_DebugSaveConfigTime */result = ufshc_dme_set(0xd0a0, 0x0, 0x10);/* sync length */result = ufshc_dme_set(0x1556, 0x0, 0x48);}
	result = ufshc_dme_get(PA_TACTIVATE_OFFSET, 0, &data);if (data < 7) {result = ufshc_dme_set(PA_TACTIVATE_OFFSET, 0, 7);}

在这里插入图片描述
获取支持的tx和rx的lane并设置

	result = ufshc_dme_get(PA_CONNECTED_TX_DATA_LANES_OFFSET, 0, &tx_lanes);result = ufshc_dme_get(PA_CONNECTED_RX_DATA_LANES_OFFSET, 0, &rx_lanes);result = ufshc_dme_set(PA_ACTIVE_TX_DATA_LANES_OFFSET, 0, tx_lanes);result = ufshc_dme_set(PA_ACTIVE_RX_DATA_LANES_OFFSET, 0, rx_lanes);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

	result = ufshc_dme_set(PA_TX_SKIP_OFFSET, 0, 0);

在这里插入图片描述
配置UFS为HS-GEAR3 Series B

	result = ufshc_dme_set(PA_TX_GEAR_OFFSET, 0, 3);result = ufshc_dme_set(PA_RX_GEAR_OFFSET, 0, 3);result = ufshc_dme_set(PA_HS_SERIES_OFFSET, 0, 2);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

	result = ufshc_dme_set(PA_TX_TERMINATION_OFFSET, 0, 1);result = ufshc_dme_set(PA_RX_TERMINATION_OFFSET, 0, 1);result = ufshc_dme_set(PA_SCRAMBLING_OFFSET, 0, 0);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

result = ufshc_dme_set(PA_PWR_MODE_USER_DATA0_OFFSET, 0, 8191);result = ufshc_dme_set(PA_PWR_MODE_USER_DATA1_OFFSET, 0, 65535);result = ufshc_dme_set(PA_PWR_MODE_USER_DATA2_OFFSET, 0, 32767);result = ufshc_dme_set(DME_FC0_PROTECTION_TIMEOUT_OFFSET, 0, 8191);result = ufshc_dme_set(DME_TC0_REPLAY_TIMEOUT_OFFSET, 0, 65535);result = ufshc_dme_set(DME_AFC0_REQ_TIMEOUT_OFFSET, 0, 32767);result = ufshc_dme_set(PA_PWR_MODE_USER_DATA3_OFFSET, 0, 8191);result = ufshc_dme_set(PA_PWR_MODE_USER_DATA4_OFFSET, 0, 65535);result = ufshc_dme_set(PA_PWR_MODE_USER_DATA5_OFFSET, 0, 32767);result = ufshc_dme_set(DME_FC1_PROTECTION_TIMEOUT_OFFSET, 0, 8191);result = ufshc_dme_set(DME_TC1_REPLAY_TIMEOUT_OFFSET, 0, 65535);result = ufshc_dme_set(DME_AFC1_REQ_TIMEOUT_OFFSET, 0, 32767);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置power mode为fast mode

	result = ufshc_dme_set(PA_PWR_MODE_OFFSET, 0, 0x11);do {data = mmio_read_32(base + IS);} while ((data & UFS_INT_UPMS) == 0);mmio_write_32(base + IS, UFS_INT_UPMS);data = mmio_read_32(base + HCS);if ((data & HCS_UPMCRS_MASK) == HCS_PWR_LOCAL)INFO("ufs: change power mode success\n");elseWARN("ufs: HCS.UPMCRS error, HCS:0x%x\n", data);(void)result;return 0;

在这里插入图片描述

e) 设备描述符读取

static void ufs_get_device_info(struct ufs_dev_desc *card_data)
{uint8_t desc_buf[DESC_DEVICE_MAX_SIZE];ufs_read_desc(DESC_TYPE_DEVICE, 0, (uintptr_t)desc_buf, DESC_DEVICE_MAX_SIZE);/** getting vendor (manufacturerID) and Bank Index in big endian* format*/card_data->wmanufacturerid = (uint16_t)((desc_buf[DEVICE_DESC_PARAM_MANF_ID] << 8) |(desc_buf[DEVICE_DESC_PARAM_MANF_ID + 1]));
}

初始化完成

ufs_init->ufs_enum->ufs_set_fdevice_init。通过QUERY UPIU 给UFS设备之上FDEVICE_INIT flag。

static int ufs_set_fdevice_init(void)
{unsigned int result;int timeout;ufs_set_flag(FLAG_DEVICE_INIT);timeout = FDEVICEINIT_TIMEOUT_MS;do {result = ufs_read_flag(FLAG_DEVICE_INIT);if (!result) {break;}mdelay(5);timeout -= 5;} while (timeout > 0);if (result != 0U) {return -ETIMEDOUT;}return 0;
}

3. Dump出代码中的初始化过程中的UPIU

UTRD header
在这里插入图片描述

NOP UPIU

NOP OUT UPIU

主机发送给设备的NOP OUT UPIU

UTRD header: 	0x11000000 0x0 0xf 0x0 0x1ffc0080 0x0 0x8000e 0x0 
CMD UPIU: 		0x1000000 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
RESP UPIU: 		0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
PRDT: 			0x0 0x0 0x0 0x0 
UTRD Header
CCI0
CE0
I1
DD0 - no data transfer
Command Type1
Overall Command Status0xF INVALID_OSC_VALUE
DUNU0
UTP Command Descriptor Base Address0x1ffc0080
UTP Command Descriptor Base Address Upper 32-bits0
Response UPIU Offset0x8
Response UPIU Length0xE
PRDT Length0
PRDT Offset0

在这里插入图片描述

[31:24][23:16][15:8][7:0]
Command Type=00(NOP OUT)Flags=00Reserved=00Task Tag=01
Reserved=00Reserved=00Reserved=00Reserved=00
Total EHS Length=00hReserved=00Data Length MSB=00Data Length LSB=00
Reserved=00Reserved=00Reserved=00Reserved=00
Reserved=00Reserved=00Reserved=00Reserved=00
Reserved=00Reserved=00Reserved=00Reserved=00
Header E2ECRC[31:24]=00Header E2ECRC[23:16]=00Header E2ECRC[15:8]=00Header E2ECRC[7:0]=00

NOP IN UPIU

设备返回给主机的NOP IN response

UTRD header: 	0x11000000 0x0 0x0 0x0 0x1ffc0080 0x0 0x8000e 0x0 
CMD UPIU: 		0x1000000 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
RESP UPIU: 		0x1000020 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
PRDT: 			0x0 0x0 0x0 0x0
UTRD Header
CCI0
CE0
I1
DD0 - no data transfer
Command Type1
Overall Command Status0x0 SUCCESS
DUNU0
UTP Command Descriptor Base Address0x1ffc0080
UTP Command Descriptor Base Address Upper 32-bits0
Response UPIU Offset0x8
Response UPIU Length0xE
PRDT Length0
PRDT Offset0

在这里插入图片描述

[31:24][23:16][15:8][7:0]
Command Type=20(NOP IN)Flags=00Reserved=00Task Tag=01
Reserved=00Reserved=00Reserved=00Reserved=00
Total EHS Length=00hReserved=00Data Length MSB=00Data Length LSB=00
Reserved=00Reserved=00Reserved=00Reserved=00
Reserved=00Reserved=00Reserved=00Reserved=00
Reserved=00Reserved=00Reserved=00Reserved=00
Header E2ECRC[31:24]=00Header E2ECRC[23:16]=00Header E2ECRC[15:8]=00Header E2ECRC[7:0]=00

TEST UNIT UPIU

COMMAND UPIU

UTRD header: 	0x11000000 0x0 0xf 0x0 0x1ffc0080 0x0 0x8000e 0x0 
CMD UPIU: 		0x1000001 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
RESP UPIU: 		0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
PRDT: 			0x0 0x0 0x0 0x0 
UTRD Header
CCI0
CE0
I1
DD0 - no data transfer
Command Type1
Overall Command Status0xF INVALID_OSC_VALUE
DUNU0
UTP Command Descriptor Base Address0x1ffc0080
UTP Command Descriptor Base Address Upper 32-bits0
Response UPIU Offset0x8
Response UPIU Length0xE
PRDT Length0
PRDT Offset0

在这里插入图片描述

[31:24][23:16][15:8][7:0]
Command Type=01(COMMAND)Flags=00LUN=00Task Tag=01
Command Set Type=00Reserved=00Reserved=00Reserved=00
Total EHS Length=00hReserved=00Data Length MSB=00Data Length LSB=00
Expected Data Transfer Length[31:24]=00[23:16]=00[15:8]=00[7:0]=00
CDB[0] (OP)=00(CDBCMD_TEST_UNIT_READY)CDB[1]=00CDB[2]=00CDB[3]=00
CDB[4]=00CDB[5]=00CDB[6]=00CDB[7]=00
CDB[8]=00CDB[9]=00CDB[10]=00CDB[11]=00
CDB[12]=00CDB[13]=00CDB[14]=00CDB[15]=00

RESPONSE UPIU

UTRD header: 	0x11000000 0x0 0x0 0x0 0x1ffc0080 0x0 0x8000e 0x0 
CMD UPIU: 		0x1000001 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
RESP UPIU: 		0x1000021 0x2000000 0x140000 0x0 0x0 0x0 0x0 0x0 0x701200 0x5 0xa00 0x200000 0x0 
PRDT: 			0x0 0x0 0x0 0x0 
UTRD Header
CCI0
CE0
I1
DD0 - no data transfer
Command Type1
Overall Command Status0x0 SUCCESS
DUNU0
UTP Command Descriptor Base Address0x1ffc0080
UTP Command Descriptor Base Address Upper 32-bits0
Response UPIU Offset0x8
Response UPIU Length0xE
PRDT Length0
PRDT Offset0

在这里插入图片描述

[31:24][23:16][15:8][7:0]
Command Type=21(RESPONSE)Flags=00LUN=00Task Tag=01
Command Set Type=00Reserved=00Response=00Status=02(CHECK CONDITION)
Total EHS Length=00hReserved=00Data Length MSB=Data Length LSB=00
Expected Data Transfer Length[31:24]=00[23:16]=00[15:8]=00[7:0]=00
Reserved=00Reserved=00Reserved=00Reserved=00
Reserved=00Reserved=00Reserved=00Reserved=00
Reserved=00Reserved=00Reserved=00Reserved=00
Reserved=00Reserved=00Reserved=00Reserved=00
K=00K+1=0x12K+2(Response Code)=0x70K+3=0
K+4=0x05K+5=0K+6=0K+7=0
K+8=0x0K+9=0x0AK+10=0K+11=0
K+12=0K+13=0K+14=0x20K+15=0
K+16=0K+17=0

在这里插入图片描述

SET FDEVICE_INIT UPIU

READ CAPACITY UPIU

READ DEVICE DESCRIPTOR UPIU

READ BLOCK UPIU

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/52581.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

List<Map<String, Object>>汇总统计排序

开发环境&#xff1a;jdk 1.8 需求一&#xff1a; 1、统计每个小时(升序)不同事件的产品产量 2、统计不同事件&#xff08;OK 、NG&#xff09;的总产量 public static void main(String[] args) {//数据源List<Map<String, Object>> list new ArrayList<Map…

云计算实训48——k8s环境搭建(详细版)

1.创建主机、设置ip、设置hostname 2.设置免密登录 # 生成私钥 [rootk8s-master ~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/id_rsa already exists. Overwrite (y/n)? y Enter passphr…

vue3 使用swiper制作带缩略图的轮播图

效果图 实现代码 <template><div class"wrap"><!-- 主轮播图 --><swiper :style"{--swiper-navigation-color: #fff,--swiper-pagination-color: #fff,}" :modules"modules" :navigation"true" :thumbs"{ …

计算机网络 第2章 物理层

文章目录 通信基础基本概念信道的极限容量编码与调制常用的编码方法常用的调制方法 传输介质双绞线同轴电缆光纤以太网对有限传输介质的命名规则无线传输介质物理层接口的特性 物理层设备中继器集线器一些特性 物理层任务&#xff1a;实现相邻节点之间比特&#xff08;0或1&…

pptpd配置文件/etc/pptpd.conf详解

正文共&#xff1a;1111 字 2 图&#xff0c;预估阅读时间&#xff1a;1 分钟 如果要在Linux系统配置PPTP&#xff08;Point-to-Point Tunneling Protocol&#xff0c;点到点隧道协议&#xff09;VPN&#xff0c;一般是使用pptpd软件。pptpd命令通常从配置文件/etc/pptpd.conf中…

单片机拍照_将采集的RGB图像封装为BMP格式保存到SD卡

文章目录 一、前言二、BMP文件结构2.1 BMP图片的格式说明 2.2 RGB888与RGB565格式是什么&#xff1f;&#xff08;1&#xff09;RGB565&#xff08;2&#xff09;RGB888&#xff08;3&#xff09;区别&#xff08;4&#xff09;如何构成&#xff08;5&#xff09;示例 三、实现…

【Leetcode56】合并区间(数组 | 排序)

文章目录 一、题目二、思路三、代码 一、题目 二、思路 先将所有子列表按照start_pos进行排序&#xff0c;有利于保持顺序性&#xff0c;每次处理新子列表时&#xff0c;只用和结果列表ans_lst的最后一个子列表对比&#xff0c;如果有重合则合并&#xff0c;然后将合并的新子列…

Java 入门指南:Java 并发编程 —— 同步工具类 Phaser(相位器)

文章目录 同步工具类Phaser主要特点核心方法使用步骤适用场景使用示例 同步工具类 JUC&#xff08;Java.util.concurrent&#xff09;是 Java 提供的用于并发编程的工具类库&#xff0c;其中包含了一些通信工具类&#xff0c;用于在多个线程之间进行协调和通信&#xff0c;特别…

创新实验报告VC++案例开发十二生肖的俄罗斯方块智力游戏完整代码设计方案

一&#xff0e;项目名称 十二生肖俄罗斯方块 二&#xff0e;开发背景&#xff1a; 俄罗斯方块是一个很低古老的一个小游戏&#xff0c;到但今日它还有很大的魅力。 三&#xff0e;技术路线或工作原理&#xff1a; 采用的软件及开发平台 Micosoft Visual 6.0 项目的总体方…

uniapp 原生插件开发 UI

前言&#xff1a; 在集成某些特定 原生SDK的时候&#xff0c;它本身是带UI控件的。当我们使用 uniapp 开发app的时候实是 可以使使用 nvue 页面&#xff0c;以 weex 的方式嵌入原生的UI控件。 我这边的场景是 接入连连app的支付&#xff0c;它有个自己的密码键盘 控件是原生的页…

树形弹窗选择框/vue2/Element/弹框选择

前言 此类选择器根据vueelementUI实现&#xff0c;使用vue3的可以根据此案例稍作改动即可实现&#xff0c;主要功能有弹出选择、搜索过滤、搜索结果高亮等&#xff0c;此选择器只支持单选&#xff0c;如需多选可在此基础进行改造。 效果图 代码实现 使用时&#xff0c;props-…

NVIDIA AI Workbench 让 Windows 上的 GPU 使用更加简便

NVIDIA AI Workbench 是一款免费的、用户友好型开发环境管理器&#xff0c;可在您选择的系统&#xff08;PC、工作站、数据中心或云&#xff09;上简化数据科学、ML 和 AI 项目。在 Windows、macOS 和 Ubuntu 上&#xff0c;您可以本地开发、测试项目和构建项目原型&#xff0c…

一文说清什么是数据仓库

01 数据仓库的概念 数据仓库的概念可以追溯到20世纪80年代&#xff0c;当时IBM的研究人员开发出了“商业数据仓库”。本质上&#xff0c;数据仓库试图提供一种从操作型系统到决策支持环境的数据流架构模型。 目前对数据仓库&#xff08;Data Warehouse&#xff09;的标准定义&a…

【研赛论文】数学建模2024华为杯论文word/latex模板

国赛结束&#xff0c;研究生瞩目的研赛马上就要来了&#xff0c;相信研究生同学也是在努力的准备当中&#xff0c;在这里祝愿大家能够获得一个好的名次。一举冲出重围&#xff0c;拿下国奖。在数模比赛当中&#xff0c;论文是参赛者唯一能够与评阅老师进行沟通的方式&#xff0…

工厂安灯系统在优化生产流程上的优势

工厂安灯系统通过可视化的方式&#xff0c;帮助工厂管理者和操作工人及时了解生产状态&#xff0c;快速响应问题&#xff0c;从而优化生产流程。 一、安灯系统实时监控与反馈 安灯系统的核心功能是实时监控生产线的状态。通过在生产现场设置灯光、显示屏等设备&#xff0c;工人…

VUE + NODE 历史版本安装

以node 12.20.0为例子&#xff0c;想下载哪个版本&#xff0c;后面写哪个版本 https://registry.npmmirror.com/binary.html?pathnode/v12.20.0/ 安装国内镜像7.1.0 cnpm npm install -g cnpm7.1.0 -g --registryhttps://registry.npmmirror.com 安装vue脚手架4.5.15 cnpm …

【最新顶刊综述】【多模态学习】Vision + X:A Survey on Multimodal Learning in the Light of Data

VisionX&#xff1a;基于数据的多模态学习综述 论文链接 0.论文摘要和信息 摘要 摘要——我们以多感官的方式感知世界并与世界交流&#xff0c;不同的信息源由人脑的不同部分复杂地处理和解释&#xff0c;构成一个复杂但和谐统一的感知系统。为了赋予机器真正的智能&#x…

【信创】麒麟KOS上安装使用网络抓包工具Wireshark

原文链接&#xff1a;【信创】麒麟KOS上安装使用网络抓包工具Wireshark Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于如何在麒麟桌面操作系统上安装和使用Wireshark的文章。Wireshark是一款强大的网络协议分析工具&#xff0c;广泛应用于网络故障排查、网络流…

OCR在线识别网站现已上线!

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 由作者亲自开发的ocr识别网站哈哈,暂时汇聚了三十多种验证码模型以及算法,欢迎各路朋友去尝试,网站地址如下 http://gbj5w3.natappfree.cc/ocr 验证码类型包括但…

qt绘制时钟

代码 #include "widget.h" #include "ui_widget.h"#include <QWidget> #include <QPaintEvent> //绘图事件 #include <QDebug> //测试 #include <QPainter> //画家 #include <QPen> //笔 #include <QBrush> //画刷 …