比思論壇

標題: 关于Urb的一些基础认识 [打印本頁]

作者: lcmj44444444    時間: 2013-1-5 20:29
標題: 关于Urb的一些基础认识
在内核中的USB代码和USB设备进行通信,使用的是Urb(USB request block)。Urb可以看成是一个USB的驱动和USB 的endpoint通信的桥梁。有两种方式

Urb的定义如下
struct urb
{
       /* private, usb core and host controller only fields in the urb */
       struct kref kref;             /* reference count of the URB */
       spinlock_t lock;             /* lock for the URB */
       void *hcpriv;                /* private data for host controller */
       struct list_head urb_list; /* list pointer to all active urbs */
       int bandwidth;               /* bandwidth for INT/ISO request */
       atomic_t use_count;              /* concurrent submissions counter */
       u8 reject;               /* submissions will fail */

       /* public, documented fields in the urb that can be used by drivers */
       struct usb_device *dev;        /* (in) pointer to associated device */
       unsigned int pipe;          /* (in) pipe information */
       int status;               /* (return) non-ISO status */
       unsigned int transfer_flags;    /* (in) URB_SHORT_NOT_OK | ...*/
       void *transfer_buffer;           /* (in) associated data buffer */
       dma_addr_t transfer_dma;     /* (in) dma addr for transfer_buffer */
       int transfer_buffer_length;     /* (in) data buffer length */
       int actual_length;           /* (return) actual transfer length */
       unsigned char *setup_packet; /* (in) setup packet (control only) */
       dma_addr_t setup_dma;        /* (in) dma addr for setup_packet */
       int start_frame;             /* (modify) start frame (ISO) */
       int number_of_packets;         /* (in) number of ISO packets */
       int interval;                   /* (modify) transfer interval (INT/ISO) */
       int error_count;             /* (return) number of ISO errors */
       void *context;               /* (in) context for completion */
       usb_complete_t complete;     /* (in) completion routine */
       struct usb_iso_packet_descriptor iso_frame_desc[0];   /* (in) ISO ONLY */
};
一个Urb的生命周期
1、   USB 设备驱动创建Urb
为了不破坏USB core中Urb的引用计数器,Urb不能静态创建。或者在另一个结构中。只能通过对usb_alloc_urb的调用来创建。函数原型为:
struct urb *usb_alloc_urb(int iso_packets, int mem_flags);

2、 分配一个Endpoint,由于Endpoint有四种类型,所以在分配的时候也有4个方法:
Interrupt EndPoint
void usb_fill_int_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context, int interval);

Bulk EndPoint
void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context);

Control EndPoint
void usb_fill_control_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, unsigned char *setup_packet, void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context);

Isochronous EndPoint
Isochronous EndPoint的Urb无法像Interrupt EndPoint 、Bulk EndPoint 、Control EndPoint一样被初始化,只能通过编写驱动者进行初始化。

3、  通过USB设备驱动程序,提交给USB core
当Urb被创建并且初始化完成之后就可以通过usb_submit_urb提交给Usb core 了
int usb_submit_urb(struct urb *urb, int mem_flags);
4、 当Urb完成数据传输任务后,释放该Urb
通过int usb_kill_urb(struct urb *urb); 或者int usb_unlink_urb(struct urb *urb);来释放Urb。usb_kill_urb常常在设备从系统中移除的时候使用,终止该Urb的生命周期
usb_unlink_urb这个函数在返回到调用者之前不等待这个 urb 完全停止。因为要完全停止一个Urb,必须要USB core能够睡眠当前进程。当然,Urb的transfer_flags需要一个URB_ASYNC_UNLINK。





歡迎光臨 比思論壇 (http://108.170.5.76/) Powered by Discuz! X2.5