參考文章:
USB底層協定
相關資料如下:
//這裡資料成員并沒有完全列出
struct usb_device{ //usb裝置
struct device dev;
char devpath[];
u8 portnum;
struct usb_host_endpoint ep0;
struct usb_host_endpoint *ep_in[];
struct usb_host_endpoint *ep_out[];
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:請求針對是裝置,接口還是端點
bRequestType;
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[] = dev->ep_out[] = &dev->ep0;
if (unlikely(!parent)) {//根集線器與
dev->devpath[] = '';
dev->dev.parent = bus->controller;
sprintf(dev->dev.bus_id,"usb%d",bus->busnum);
}
else{
if (parent->devpath[] == '') { //插在根集線器
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[],"%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;
}