参考文章:
USB底层协议
相关数据如下:
//这里数据成员并没有完全列出
struct usb_device{ //usb设备
struct device dev;
char devpath[16];
u8 portnum;
struct usb_host_endpoint ep0;
struct usb_host_endpoint *ep_in[16];
struct usb_host_endpoint *ep_out[16];
struct usb_bus *bus;
struct usb_device *parent;
struct list_head filelist;
};
struct usb_host_endpoint{ //usb端点
struct usb_endpoint_descriptor desc;
struct list_head urb_list;
void *hcpriv;
}
struct usb_hcd{ //usb主机控制器驱动
struct usb_bus self; //usb主机控制器对应的usb总线
struct kref kref; //引用计数
};
struct usb_bus{ //usb总线
struct device *controller; /* host/master side hardware */
int busnum;
};
struct usb_ctrlrequest{ //usb 控制请求
//bit7:data transaction 阶段的方向bit6-bit5:request type bit1-bit0:请求针对是设备,接口还是端点
__u8 bRequestType;
__u8 bRequest;
__le16 wValue;
__le16 wIndex;
__le16 wLength;
}__attribute((packed));
static inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus)
{
return container_of(bus, struct usb_hcd, self);
}
//增加usb主机控制器的引用计数
struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd)
{
if (hcd)
kref_get (&hcd->kref);
return hcd;
}
struct usb_device *usb_alloc_dev(struct usb_device *parent, \
struct usb_bus *bus, \
unsigned portl)
{
struct usb_device *dev;
dev = kzalloc(sizeof(*dev),GFP_KERNEL);
if(!usb_get_hcd(bus_to_hcd(bus))){};
device_initialize(&dev->dev);
dev->dev.bus = & usb_bus_type;//总线类型
dev->dev.type = & usb_device_type;
dev->dev.dma_mask = bus->controller->dma_mask;
dev->state = USB_STATE_ATTACHED;
INIT_LIST_HEAD(&dev->ep0.urb_list);
dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
dev->ep_in[0] = dev->ep_out[0] = &dev->ep0;
if (unlikely(!parent)) {//根集线器与
dev->devpath[0] = '0';
dev->dev.parent = bus->controller;
sprintf(dev->dev.bus_id,"usb%d",bus->busnum);
}
else{
if (parent->devpath[0] == '0') { //插在根集线器
snprintf(dev->devpath, sizeof dev->devpath,
"%d", port1);
}else{
snprintf(dev->devpath, sizeof dev->devpath,
"%s.%d", parent->devpath, port1);
}
dev->dev.parent = &parent->dev;
sprintf(dev->dev.bus_id[0],"%d-%s",bus->busnum,dev->devpath);
}
dev->portnum = port1;
dev->bus = bus;
dev->parent = parent;
INIT_LIST_HEAD(&dev->filelist);
//电源管理暂时忽略
return dev;
}
设备连接上之后hub设置状态(Powered),hub会发出reset信号,复位usb设备使其进入Default状态。这是hub会获得设备的速度与端点0的处理的最大数据长度,对于高速时64字节,对于低速8 字节全速是8,16,32,64中的一个。此时开始设置地址。给设备发出SET_ADDRESS请求调用函数usb_control_msg
int usb_control_msg(struct usb_device *dev,unsigned pipe,__u8 request \
__u8 requesttype,__u16 value,__u16 index,\
void *data,__u16 size,int timeout)
{
struct usb_ctrlrequest *dr;
dr = kmalloc(sizeof(struct usb_ctrlrequest),GFP_NOIO);
dr->bRequestType = requesttype;
dr->bRequest = request;
dr->wValue = cpu_to_le16(value);
dr->wIndex = cpu_to_le16(index);
dr->wLength = cpu_to_le16(size);
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
kfree(dr);
return ret;
}