Chinaunix首页 | 论坛 | 博客
  • 博客访问: 259334
  • 博文数量: 130
  • 博客积分: 4012
  • 博客等级: 上校
  • 技术积分: 2030
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-10 10:40
文章分类

全部博文(130)

文章存档

2010年(130)

我的朋友

分类: LINUX

2010-01-10 23:50:19

在内核中的USB代码和USB设备进行通信,使用的是Urb(USB request block)Urb可以看成是一个USB的驱动和USB endpoint通信的桥梁。有两种方式

关于Urb的一些基础认识 - gene_lu - 清风

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

转自:http://blog.chinaunix.net/u1/44250/showart.php?id=1669039

阅读(562) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~