分类: LINUX
2011-05-08 21:29:01
前面总结了usb hid keyboard ,现在总结usb mass storage ,在枚举阶段没什么好总结的,hid和mass storage差不多,都是同样的枚举过程,但是在他们的配置描述符、接口描述符、端点描述符,也许还有之类描述符是不同的,需要按照usb mass storage的协议来配置,下面是列出usb的相关描述符。
/********************************************************************/
const usb_device_descriptor device_desc = {
.length = USB_DEVICE_DESC_SIZE,
.type = USB_DEVICE_DESCRIPTOR_TYPE,
.usb_spec_lo =0x00,
.usb_spec_hi =0x02,
.device_class = 0x00,
.device_subclass = 0x00,
.device_protocol = 0x00,
.max_packet_size = USB_MAX_PACKET0, /*8*/
.vendor_lo = 0x51,
.vendor_hi = 0xC2,
.product_lo = 0x03,
.product_hi = 0x20,
.device_lo =0x00,
.device_hi = 0x01,
.manufacturer_str = 0x01,
.product_str= 0x02,
.serial_number_str = 0x03,
.number_configurations = 0x01, //
};
typedef struct usb_scsi_hid_config
{
const usb_configuration_descriptor config;
const usb_interface_descriptor scsi_inter;
const usb_endpoint_descriptor scsi_endpoint_in;
const usb_endpoint_descriptor scsi_endpoint_out;
}USB_CON_INT_ENDP_DESCRIPTOR_STRUCT;
#define USB_CON_INT_ENDP_DESCRIPTOR_STRUCT_LENGTH (sizeof(USB_CON_INT_ENDP_DESCRIPTOR_STRUCT))
const USB_CON_INT_ENDP_DESCRIPTOR_STRUCT usb_scsi_hid_con_int_endp = {
/*config*/
{
.length= USB_CONFIGUARTION_DESC_SIZE,
.type = USB_CONFIGURATION_DESCRIPTOR_TYPE,
.total_length_lo = USB_CON_INT_ENDP_DESCRIPTOR_STRUCT_LENGTH&0xff,
.total_length_hi = (USB_CON_INT_ENDP_DESCRIPTOR_STRUCT_LENGTH>>8)&0xff,
.number_interfaces = 0x02,
.configuration_id = 0x01,
.configuration_str = 0x00,
.attributes = USB_CONFIG_BUS_POWERED,
.max_power = USB_CONFIG_POWER_MA(100)
},
/*usb mass storage interface descriptor*/
{
.length = USB_INTERFACE_DESC_SIZE,
.type = USB_INTERFACE_DESCRIPTOR_TYPE,
.interface_id = 0x01,
.alternate_setting = 0x00,
.number_endpoints = 0x02,
.interface_class = USB_DEVICE_CLASS_STORAGE,
.interface_subclass = 0x06,
.interface_protocol = 0x50,
.interface_str = 0x04
},
/*usb mass storage Bulk in 1*/
{
/* Endpoint, EP1 Bulk IN */
.length = USB_ENDPOINT_DESC_SIZE, /* bLength */
.type = USB_ENDPOINT_DESCRIPTOR_MSD_TYPE, /* bDescriptorType */
.endpoint = USB_ENDPOINT_IN(1), /* bEndpointAddress */
.attributes = USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
.max_packet_lo = 0x40, /* wMaxPacketSize */
.max_packet_hi =0x00,
.interval = 0x00, /* bInterval: ignore for Bulk transfer */
},
/*usb mass storage Bulk out 2*/
{
/* Endpoint, EP2 Bulk OUT */
.length = USB_ENDPOINT_DESC_SIZE, /* bLength */
.type = USB_ENDPOINT_DESCRIPTOR_MSD_TYPE, /* bDescriptorType */
.endpoint = USB_ENDPOINT_OUT(2), /* bEndpointAddress */
.attributes = USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
.max_packet_lo = 0x40, /* wMaxPacketSize */
.max_packet_hi =0x00,
.interval = 0x00, /* bInterval: ignore for Bulk transfer */
},
};
1:usb mass storage 是用来传送大量数据的,在usb里面一共有四种传输:控制传输、中断传输、批量传输、等时传输。控制和批量端点用于异步的数据传输,驱动需要他们就立马工作。中断和等时端点是周期性的,即在固定时间段连续的传输数据。如果还有疑问请百度或者google,也可以看看ldd3。在前面总结的hid keyboard就是用的中断传输,而现在则需要批量传输,毕竟我们是大量的传输数据。
2:前面说了枚举,在这里就省略枚举,但是有一点需要注意在set config,set config 就需要和 hid有不同的配置,具体硬件怎么工作,请参考自己的硬件手册。
3:如果set config 和 set interface通过的话,那么就应该出现了GET MAX LUN命令,这里又是一个知识点。LUN其实就是有几个存储设备,一般而言u盘只有一个LUN(logical unit number.),fudan ABC说:logical unit number.通常在谈到scsi 设备的时候不可避免的要说起LUN.关于LUN,曾几何时,一位来自Novell(SUSE)的参与开发Linux 内核中usb 子系统的工程师这样对我说,一个lun 就是一个device 中的一个drive.换言之,usb 中引入lun 的目的在于,举例来说,有些读卡器可以有多个插槽,比如就是两个,其中一个支持CF 卡,另一个支持SD 卡,那么这种情况要区分这两个插槽里的冬冬,就得引入lun 这么一个词.这叫逻辑单元.很显然,像U盘这样简单的设备其LUN必然是一个.有时候,人们常把U 盘中一个分区当作一个LUN,这样说可能对小学三年级以下的朋友是可以接受的,但是作为一个成年人,不应该这么理解. 哈,有他们解释,我就不用解释了。
4:好了usb mass storage的枚举已经完成了,枚举是完成了,但是scsi才刚开始,下回请看usb 旅途之scsi。