USB_SCSI之旅

本文详细介绍了USB Mass Storage设备中处理的SCSI命令,包括 Inquiry、READ FORMAT CAPACITIES、READ CAPACITY、READ(10)、MODE SENSE(6)、WRITE(10) 和 TEST UNIT READY。每个命令的用途、响应数据结构及实现代码进行了说明,例如 Inquiry 命令用于获取设备信息,READ FORMAT CAPACITIES 用于获取存储设备的格式容量列表,而 WRITE(10) 则用于主机向设备写入数据。
摘要由CSDN通过智能技术生成
 

现在总结一下scsi,scsi协议有很多,所以只总结这次在usb mass storage里面用到的协议,主要包括inquiry,format , read write等等命令。

 

下面会一个一个总结。

 

U盘需要处理的命令如下:

 

1:inquiry:设备的一个描述,告诉host你的设备是什么,名字叫什么,用的什么协议,这里用的SCSI协议—SPC2

2:READ FORMAT CAPACITIES:读格式容量(The READ FORMAT CAPACITIES command allows the host to request a list of the possible capacities that can be formatted on the currently installed medium.)

3:READ CAPACITY:读取容量信息

4:READ(10):回发在逻辑单元的数据,既回发MBR(Main Boot Record)主引导扇区

5:SENSE6:目的在于获得设备内部很多潜在的信息,其中包括了是否设置了写保(The MODE SENSE(6) command (see table 62) provides a means for a device server to report parameters to an application client. It is a complementary command to the MODE SELECT(6) command. Device servers that implement the MODE SENSE(6) command shall also implement the MODE SELECT(6) command.)

6:WRITE(10):host向slave发生数据并写在u盘存储器里面。

7:TEST UNIT READY:检查U盘准备好没有。

 

 

1:inquiry

 

// The standard INQUIRY data shall contain at least 36 bytes

// This is the reduced structure for Mass Storage Devices

typedef struct

{

  cyg_uint8 peripheral;        // Device Type

  cyg_uint8 rmb;               // Removable Media Bit

  cyg_uint8 version;           // Version Field

  cyg_uint8 resp_data_format;  // Response Data Format

  cyg_uint8 additional_len;    // Additional Length

  cyg_uint8 sccstp;            // SCC Supported (include embedded storage array)

  cyg_uint8 bque;              // Basic Queuing

  cyg_uint8 cmdque;            // Command Queuing

  cyg_uint8 vendor_id[8];

  cyg_uint8 product_id[16];

  cyg_uint8 product_rev[4];

} msd_scsi_inq_resp;

 

这个结构体就是为inquiry准备的数据包,这个命令是usb mass storage第一个接收到的命令

在这里只需要关注两个字段OPERATION CODE,ALLOCATION LENGTH。其它的还没用到,每个命令都有一个OPERATION CODE

用来标志这个命令是什么命令,毕竟我们不会看数字就知道什么意思,电脑也不会看文字就是要做什么,是吧。现在这里是12,我们查一查SPC-2

协议,就知道OPERATION CODE为12就知道这次host需要slave做什么操作。

既然知道了这个操作,那么咱们就应该回复一下,毕竟来而不往非礼也。那咱们得准备一下礼物送给host,不然这个门打不开,马上就关起来了

就好像现在这个社会,有钱有权什么都可以,这个社会让我们这些刚毕业的怎么生存啊,咱学习嵌入式就是为了多赚点money。下面就是一个能够回复

Host的inquiry包。

/*

 这是inquiry请求包

*/

const msd_scsi_inq_resp inrq_resp = {

  USBS_SCSI_DIRECT_ACCESS_BLOCK_DEVICE, // Direct Access Block device 0x00

  USBS_SCSI_REMOVABLE_DEVICE,          // Device is removable

  0x04,                                // Comply with SPC-2

  0x02,                                // Standard format

  0x20,                                /* Response is 0x20 + 4 bytes,表明这个请求包有多长,这里为36 */

  0x00,

  0x00,

  0x00,

  {'R','i','s','e','t','e','k',' '}, /*VENDOR IDENTIFICATION 8~15*/

  {'M','a','s','s',' ','S','t','o','r','a','g','e',' ',' ',' ',' '}, /*PRODUCT IDENTIFICATION 16-31*/

  {'0','.','0','1'}, /*PRODUCT REVISION LEVEL ,版本, 32~35*/

};

 

 

这个图下面还有数据端,但是在这里就只回了一个最小的数据包回去,那就总结这些字段就好了吧。

第0个字节:有这两个PERIPHERAL QUALIFIER,PERIPHERAL DEVICE TYPE东东需要关注,PERIPHERAL QUALIFIER这里三位全为0

PERIPHERAL DEVICE TYPE的值都为0,表明意思是Direct-access device。

第一个字节:只要关注RMB表明这个设备可不可以移除,原文为:A removable medium (RMB) bit of zero indicates that the medium is not removable. A RMB bit

of one indicates that the medium is removable.

第二个字节:VERSION表明数据交流使用的协议版本是SPC-2,其值为0x04,

第三个字节:An AERC bit of one indicates that the processor device is capable of accepting asynchronous event reports. An AERC bit of zero indicates that the processor device does not support asynchronous event reports;

                     RESPONSE DATA FORMAT:A RESPONSE DATA FORMAT field value of two indicates that the data shall be in the format specified in this standard.

                     这里写为2就好,整个字节的值就是为0x02。

第四个字节:ADDITIONAL LENGTH表明这个值附加了多少数据,Response is 0x20 + 4 bytes,表明这个请求包有多长,这里为36,前面有四个数据下面有32个刚好36个数据。

第五,第六,第七个字节都填0,想知道为什么的话,看看手册吧,不然这么总结就成了在翻译协议了。

第八字节—第十五字节:VENDOR IDENTIFICATION,在8个字节里面,随便写一些字符,写法如上面就可以了。而PRODUCT IDENTIFICATION和PRODUCT REVISION LEVEL都是想填什么就填什么,只要没有操作范围。一定要注意范围哦。

 

/*

Function: usb_msd_scsi_handle_inquiry:

                           Handle Inquiry Request Command

Data in : msd

Data out: NULL

*/

 

static inline cyg_int32 usb_msd_scsi_handle_inquiry( usb_msd * msd )

{

      cyg_int32 tx_bytes = sizeof(msd_scsi_inq_resp);

 

      DBG("USB Slave MSD: SCSI inquiry\n");

 

      // Copy over to message buffer

      memcpy( msd->buffer, (cyg_uint8 *) &inrq_resp, tx_bytes );

 

      usb_msd_tx_send(msd , tx_bytes);

 

      return tx_bytes;

}

通过端点2就把数据发给host,第一步就完成了。

 

2:READ FORMATCAPACITIES

下表就是READ FORMATCAPACITIES Command的命令表,这个命令也只需要关注两个字节,Operation Code (23h) and Logical Unit Number

Logical Unit Number(LUN),前面说过这个LUN,这里就为一个LUN。下面准备回复的数据。

 

 

这个usb_msd_scsi_read_format_capacities函数就是用来准备回复host数据的函数并且发送给host。还是按照协议回复,上图。

 

 

第一个需要准备的是Capacity List Header,然后是Current/Maximum Capacity Header等等。

 

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值