USB Mass Storage 6.7 The Thirteen Cases章节的理解
来源:互联网 发布:为什么要优化系统 编辑:程序博客网 时间:2024/06/05 01:05
Case(1), case(6), case(12)状态下是正常的数据传输,被称为“The thin diagonal”。其它的状态是协议外的内容,是一些判断。
6.7.1 主机期望发起一次无数据传输的命令
CBW包中的dCBWDataTransferLength字段=0,Direction位不考虑。
主机做的工作:
(1) 发送一个CBW
(2) 偿试接收CSW
(3) 如果在STALL状态下接收到CSW:先清空BULK—IN端口数据,再接收CSW
(4) 判断CSW,如果“bCSWStatus = 00h or 01h, and the dCSWDataResidue is 0.”,它是CASE(1),其它是一个相位错误,需要主机发送一个复位来清除错误。
设备做的工作:
(1) 等待接收一个CBW
(2) CBW有效,则执行命令
(3) 分析包,如果是CASE(1),说明无数据传输,设置bCSWStatus to 00h or 01h.,bCSWStatus to 00h or 01h.。如果是CASE(2)或CASE(3),设置bCSWStatus to 02h.
(4) 发送CSW。
6.7.2 主机期望从设备接收数据
这种情况下CBW中的dCBWDataTransferLength为非0并且Direction为1(Data-In)。
主机做的工作:
(1) 发送CBW
(2) 偿试接收数据
(3) 如果在STALL状态下接收到数据:1)主将接收数据2)主机将清空BULK_IN端口
(4) 偿试接收CSW
(5) 如果在STALL状态下接收到CSW:1)主机将清空bulk_in端口2)主机将偿试再次接收CSW。
(6) 分析CSW,如果是CASE(4),CASE(5),CASE(6), bCSWStatus = 00h or 01h, 接收数据的大小应等于dCBWDataTransferLength – dCSWDataResidue。如果是CASE(7),CASE(8),且bCSWStatus = 02h,主机需要发送复位来清除错误。
设备做的工作:
(1) 等待并接收CBW
(2) CBW有效则执行命令。如果是CASE(6),发送dCBWDataTransferLength字节数据给主机,设置bCSWStatus to 00h or 01h,dCSWDataResidue to zero。
CASE(4),CASE(5):说明设备发送的数据长度比主机要求的数据长度小。有两种处理方法:1)发送实际数据后再发送填充数据使用总长度等于dCBWDataTransferLength,设置dCSWDataResidue=dCBWDataTransferLength;2)发送实际数据长度,设置dCSWDataResidue=dCBWDataTransferLength-发送数据的长度。
CASE(7),CASE(8):说明设备要发送的数据超出主机要求的数据长度。两种处理:1)发送主机要求的数据长度,(下一句不知怎么翻译)2)发送设备的数据长度(超出主机要求的数据长度)。这两种处理后均设置bulk_in端口为STALL状态,并设置CSW包相位错误(bCSWStatus to 02h)。
(3) 发送CSW。
6.7.3 主机期望发送数据到设备
这种情况下CBW中的dCBWDataTransferLength为非0并且Direction为0(Data-In)。
主机做的工作:
(1) 发送CBW
(2) 发送数据到设备,在数据传输结尾,主机将发送一个短包。
(3) 在STALL状态下发送数据,主机将清空bulk_out端口
(4) 偿试接收CSW
(5) 在STALL状态下接收CSW,主机清空bulk_in端口,再偿试接收CSW
(6) CSW有效,如果是CASE(9),CASE(11),CASE(12),设备实际接收的数据等于dCBWDataTransferLength – dCSWDataResidue。如果是CASE(9),(13),主机需要发送复位来清除错误。
设备做的工作
(1) 接收CBW
(2) CBW有效:
如果是CASE(9),CASE(11),CASE(12),有可能设备需要的数据小于主机发送的长度:
1) 设备接收它需要的数据长度,并设置dCSWDataResidue = dCBWDataTransferLength – 实际接收数据的长度。之后设置bulk_out端口为STALL状态。
2) 设备接收主机发送的所有数据。
3) 发送CSW。
//-----------------------------------------------------------------------------/// Pre-processes a command by checking the differences between the host and/// device expectations in term of transfer type and length./// Once one of the thirteen cases is identified, the actions to do during the/// post-processing phase are stored in the dCase variable of the command /// state./// \param pMsdDriver Pointer to a MSDDriver instance/// \return 1 if the command is supported, false otherwise//-----------------------------------------------------------------------------static unsigned char MSDD_PreProcessCommand(MSDDriver *pMsdDriver){ unsigned int hostLength = 0; //记录cbw包中的数据传输大小 unsigned int deviceLength = 0; //分析cbw包中的SCSI命令中的数据传输大小 unsigned char hostType; //记录cbw包中的数据传输方向 unsigned char deviceType; //分析cbw包中的SCSI命令中的数据传输方向 unsigned char isCommandSupported; //分析cbw包中的SCSI命令是否支持 MSDCommandState *commandState = &(pMsdDriver->commandState); MSCsw *csw = &(commandState->csw); MSCbw *cbw = &(commandState->cbw); MSDLun *lun = &(pMsdDriver->luns[(unsigned char) cbw->bCBWLUN]); // Get information about the command// Host-side//获取cbw包中标明的数据传输方向和数据传输大小 MSDD_GetCommandInformation(cbw, &hostLength, &hostType);// Device-side//分析cbw包中scsi命令,取得scsi命令中标明的数据传输方向和大小 isCommandSupported = SBC_GetCommandInformation(cbw->pCommand, &deviceLength, &deviceType, lun);// Initialize data residue and result status// dCSWDataResidue记录传输数据大小, csw->dCSWDataResidue = 0; csw->bCSWStatus = MSD_CSW_COMMAND_PASSED; // Check if the command is supported if (isCommandSupported) { // Identify the command case if(hostType == MSDD_NO_TRANSFER) { // Case 1 (Hn = Dn) if(deviceType == MSDD_NO_TRANSFER) { //TRACE_WARNING("Case 1\n\r"); commandState->postprocess = 0; commandState->length = 0; } else if(deviceType == MSDD_DEVICE_TO_HOST) { // Case 2 (Hn < Di) TRACE_WARNING( "MSDD_PreProcessCommand: Case 2\n\r"); commandState->postprocess = MSDD_CASE_PHASE_ERROR; commandState->length = 0; } else { //if(deviceType == MSDD_HOST_TO_DEVICE) { // Case 3 (Hn < Do) TRACE_WARNING( "MSDD_PreProcessCommand: Case 3\n\r"); commandState->postprocess = MSDD_CASE_PHASE_ERROR; commandState->length = 0; } } // Case 4 (Hi > Dn) else if(hostType == MSDD_DEVICE_TO_HOST) { if(deviceType == MSDD_NO_TRANSFER) { TRACE_WARNING( "MSDD_PreProcessCommand: Case 4\n\r"); commandState->postprocess = MSDD_CASE_STALL_IN; commandState->length = 0; csw->dCSWDataResidue = hostLength; } else if(deviceType == MSDD_DEVICE_TO_HOST) { if(hostLength > deviceLength) { // Case 5 (Hi > Di) TRACE_WARNING( "MSDD_PreProcessCommand: Case 5\n\r"); commandState->postprocess = MSDD_CASE_STALL_IN; commandState->length = deviceLength; csw->dCSWDataResidue = hostLength - deviceLength; } else if(hostLength == deviceLength) { // Case 6 (Hi = Di) commandState->postprocess = 0; commandState->length = deviceLength; } else { //if(hostLength < deviceLength) { // Case 7 (Hi < Di) TRACE_WARNING( "MSDD_PreProcessCommand: Case 7\n\r"); commandState->postprocess = MSDD_CASE_PHASE_ERROR; commandState->length = hostLength; } } else { //if(deviceType == MSDD_HOST_TO_DEVICE) { // Case 8 (Hi <> Do) TRACE_WARNING( "MSDD_PreProcessCommand: Case 8\n\r"); commandState->postprocess = MSDD_CASE_STALL_IN | MSDD_CASE_PHASE_ERROR; commandState->length = 0; } } else if(hostType == MSDD_HOST_TO_DEVICE) { if(deviceType == MSDD_NO_TRANSFER) { // Case 9 (Ho > Dn) TRACE_WARNING( "MSDD_PreProcessCommand: Case 9\n\r"); commandState->postprocess = MSDD_CASE_STALL_OUT; commandState->length = 0; csw->dCSWDataResidue = hostLength; } else if(deviceType == MSDD_DEVICE_TO_HOST) { // Case 10 (Ho <> Di) TRACE_WARNING( "MSDD_PreProcessCommand: Case 10\n\r"); commandState->postprocess = MSDD_CASE_STALL_OUT | MSDD_CASE_PHASE_ERROR; commandState->length = 0; } else { //if(deviceType == MSDD_HOST_TO_DEVICE) { if(hostLength > deviceLength) { // Case 11 (Ho > Do) TRACE_WARNING( "MSDD_PreProcessCommand: Case 11\n\r"); commandState->postprocess = MSDD_CASE_STALL_OUT; commandState->length = deviceLength; csw->dCSWDataResidue = hostLength - deviceLength; } else if(hostLength == deviceLength) { // Case 12 (Ho = Do) //TRACE_WARNING( // "MSDD_PreProcessCommand: Case 12\n\r"); commandState->postprocess = 0; commandState->length = deviceLength; } else { //if(hostLength < deviceLength) { // Case 13 (Ho < Do) TRACE_WARNING( "MSDD_PreProcessCommand: Case 13\n\r"); commandState->postprocess = MSDD_CASE_PHASE_ERROR; commandState->length = hostLength; } } } } return isCommandSupported;}
- USB Mass Storage 6.7 The Thirteen Cases章节的理解
- usb Mass Storage
- USB Mass Storage协议
- USB OTG mass storage
- USB mass storage协议
- USB mass storage协议
- USB Mass Storage协议
- USB Mass Storage协议
- USB Mass Storage协议
- USB mass storage framework
- USB Mass Storage协议
- USB Mass Storage协议
- USB Mass Storage
- USB mass storage协议
- USB mass storage协议
- USB Mass Storage 系统结构
- USB Mass Storage学习笔记
- usb mass storage之旅
- 用汇编的眼光看C++(之指针1)
- 帮盖尔优化SQL
- doc 命令 cd 的一个有用的参数,学习dos十几年,最近才发现
- 抓包工具:tcpdump和wireshark
- 手工焊接的基本操作概述
- USB Mass Storage 6.7 The Thirteen Cases章节的理解
- cerrno <errno.h> <cerrno>
- 数据库连接池---------------也优化了代码
- sysbench官网
- 优化数据库访问代码
- 第一部分 Cassandra 1.0.X常用命令指南
- 导入工程的“The import android cannot be resolved”错误解决方法
- nginx 支持yum 和 apt-get install的安装方式了,Happy啊。
- ODBC与BDE