Chinaunix首页 | 论坛 | 博客
  • 博客访问: 290234
  • 博文数量: 49
  • 博客积分: 3083
  • 博客等级: 中校
  • 技术积分: 710
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-27 08:22
文章分类

全部博文(49)

文章存档

2009年(8)

2008年(41)

分类: LINUX

2008-11-27 14:16:07

在内核中的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 coreUrb的引用计数器,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 EndPointUrb无法像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);来释放Urbusb_kill_urb常常在设备从系统中移除的时候使用,终止该Urb的生命周期

usb_unlink_urb这个函数在返回到调用者之前不等待这个 urb 完全停止。因为要完全停止一个Urb,必须要USB core能够睡眠当前进程。当然,Urb的transfer_flags需要一个URB_ASYNC_UNLINK
阅读(2029) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~