一.协议分析
1. usb描述符流程
2. 一个u盘的各个描述符解析
-
设备描述符:
-
send: 0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00
-
0x80
-
0x06 --> 请求类型: get_Desc
-
0x00 0x01 --> 0x01代表设备描述符
-
0x00 0x00
-
0x40 0x00 --> 长度为0x40,此时还没有确定ep0的maxPktSize
-
recv: 0x12 0x01 0x00 0x02 0x00 0x00 0x00 0x40 0x51 0x09 0x43 0x16 0x00 0x01 0x01 0x02 0x03 0x01
-
0x12 --> len
-
0x01 --> 设备描述符
-
0x00 0x02 -->usb2.0
-
0x00 0x00 --> class及subclass
-
0x00 -->
-
0x40 --> MaxPacketSize=64个字节
-
0x51 0x09 --> VID
-
0x43 0x16 --> PID
-
0x00 0x01 -->自定义Version
-
0x01 --> iManufacture string字段
-
0x02 --> iProduct string字段
-
0x03 --> 序列号 string
-
0x01 --> bNumConfigruation
-
-
//获取配置描述符
-
usb_raw: 0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00
-
0x80
-
0x06 --> 请求类型: get_Desc
-
0x00 0x02 --> 0x02代表配置描述符
-
0x00 0x00
-
0x09 0x00 --> 配置描述符的长度为0x09
-
usb_raw: 0x09 0x02 0x20 0x00 0x01 0x01 0x00 0x80 0x32
-
0x09 --> len
-
0x02 --> 配置描述符0x02
-
0x20 0x00 --> 配置描述符集合总长充0x20=32B
-
0x01 --> 接口数=1
-
0x01 --> 该配置的标号=1
-
0x00 --> 该配置的字符串索引值
-
0x80 --> 该设备的属性
-
0x32 --> 电流(0x32*2mA=100mA)
-
//完整的获取配置描述符--> len=0x20,只看接口描述符
-
usb_raw: 0x80 0x06 0x00 0x02 0x00 0x00 0x20 0x00
-
usb_raw: 0x09 0x02 0x20 0x00 0x01 0x01 0x00 0x80 0x32 0x09 0x04 0x00 0x00 0x02
0x08 0x06 0x50 0x00 0x07 0x05 0x81 0x02 0x40 0x00 0xff 0x07 0x05 0x02
0x02 0x40 0x00 0xff
-
0x09
-
0x04 --> 接口描述符0x04
-
0x00 --> 该接口的标号
-
0x00 --> 备用标号
-
0x02 --> 本接口的端点数=2个端点
-
0x08 --> 本接口的类 0x08(大容量存储设备接口类为0x08)
-
0x06 --> 本接口的子类 0x06(scsi透明命令子集的子类代码为0x06)
-
0x50 --> 本接口的协议为仅批量传输,0x50
-
0x00 --> 本接口的字符串索引
-
-
0x07
-
0x05 --> 端点描述符0x05
-
0x81 --> 本端点的地址(8代表输入,1代表ep1)
-
0x02 --> 本端点的属性(2: bulk传输)
-
0x40 --> 本端点的最大包长度
-
0x00
-
0xff --> 本端点的查询时间
-
-
0x07
-
0x05 --> 端点描述符0x05
-
0x02 --> 本端点的地址(8代表输入,1代表ep1)
-
0x02 --> 本端点的属性(2: bulk传输)
-
0x40 --> 本端点的最大包长度
-
0x00
-
0xff --> 本端点的查询时间
-
//获取字符串描述符
-
usb_raw: 0x80 0x06 0x00 0x03 0x00 0x00 0xff 0x00
-
0x80
-
0x06 --> 请求类型: get_Desc
-
0x00 0x03 --> wValue:0x00代表语言ID,0x03代表字符串描述符
-
0x00 0x00 --> wIndex:
-
0xff 0x00 --> wLentgh
-
usb_raw: 0x04 0x03 0x09 0x04
-
0x04 --> len
-
0x03 --> 字符串描述符
-
0x09 0x04 --> 0x0409 美式英语ID
-
-
-
//获取字符串描述符之语言Product-->DataTraveler G3
-
usb_raw: 0x80 0x06 0x02 0x03 0x09 0x04 0xff 0x00
-
0x80
-
0x06 --> 请求类型: get_Desc
-
0x02 0x03 --> 0x02代表字符串索引2,0x03代表字符串描述符
-
0x09 0x04
-
0xff 0x00 --> wLentgh
-
usb_raw: 0x20 0x03 0x44 0x00 0x61 0x00 0x74 0x00 0x61 0x00 0x54 0x00 0x72 0x00
0x61 0x00 0x76 0x00 0x65 0x00 0x6c 0x00 0x65 0x00 0x72 0x00 0x20 0x00
0x47 0x00 0x33 0x00
二.调试技巧
2.1 打印usb协议包
-
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
-
__u8 requesttype, __u16 value, __u16 index, void *data,
-
__u16 size, int timeout)
-
{
-
struct usb_ctrlrequest *dr;
-
int ret;
-
-
dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
-
if (!dr)
-
return -ENOMEM;
-
-
dr->bRequestType = requesttype;
-
dr->bRequest = request;
-
dr->wValue = cpu_to_le16(value);
-
dr->wIndex = cpu_to_le16(index);
-
dr->wLength = cpu_to_le16(size);
-
-
dump_raw_char((char*)dr,sizeof(struct usb_ctrlrequest));//打印host发给device的数据
-
/* dbg("usb_control_msg"); */
-
-
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
-
-
if(ret > 0)
-
dump_raw_char((char*)data, ret); //打印device返回给host的命令
-
printk("\n");
-
kfree(dr);
-
-
return ret;
-
}
-
EXPORT_SYMBOL_GPL(usb_control_msg);
2.2其中dump_raw_char的实现如下,
-
int dump_raw_char(char* p, int len)
-
{
-
int i;
-
printk("usb_raw: ");
-
for(i=0; i<len; i++)
-
printk("0x%02x ", (unsigned char)p[i]);
-
printk("\n");
-
return 0;
-
}
-
EXPORT_SYMBOL_GPL(dump_raw_char);
2.3 在driver/usb/core/hub.h中添加定义
-
extern int dump_raw_char(char* p, int len);
阅读(2311) | 评论(0) | 转发(0) |