struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) { struct urb *urb; urb = kmalloc(sizeof(struct urb) + iso_packets * sizeof(struct usb_iso_packet_descriptor), mem_flags); if (!urb) { printk(KERN_ERR "alloc_urb: kmalloc failed\n"); return NULL; } usb_init_urb(urb); return urb; }
它只做了两件事情,拿kmalloc来为urb申请内存,然后调用usb_init_urb进行初始化.usb_alloc_urb它的第一个参数iso_packets , 表示的是struct urb 结构最后那个变长数组
iso_frame_desc的元素数目,也就是应该与number_of_packets的值相同,所以对于控制/中断/批量传输,这个参数都应该为0.
第二个问题是参数mem_flags的类型gfp_t,它在include/linux/types.h里定义。
typedef unsigned __bitwise__ gfp_t;
void usb_free_urb(struct urb *urb) { if (urb) kref_put(&urb->kref, urb_destroy); }
usb_free_urb更潇洒,只调用kref_put将urb的引用计数减一,减了之后如果变为0,也就是没人再用它了,就调用urb_destroy将它销毁掉。
static inline 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_fn, void *context) { urb->dev = dev; urb->pipe = pipe; urb->setup_packet = setup_packet; urb->transfer_buffer = transfer_buffer; urb->transfer_buffer_length = buffer_length; urb->complete = complete_fn; urb->context = context; }
urb 的元素有很多,这里只是填充了一部分,剩下那些不是控制传输管不着的,就是自有安排可以不用去管的。
static inline 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_fn, void *context) { urb->dev = dev; urb->pipe = pipe; urb->transfer_buffer = transfer_buffer; urb->transfer_buffer_length = buffer_length; urb->complete = complete_fn; urb->context = context; } static inline 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_fn, void *context, int interval) { urb->dev = dev; urb->pipe = pipe; urb->transfer_buffer = transfer_buffer; urb->transfer_buffer_length = buffer_length; urb->complete = complete_fn; urb->context = context; if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) urb->interval = 1 << (interval - 1); else urb->interval = interval; urb->start_frame = -1; }
负责批量传输的usb_fill_bulk_urb和负责控制传输的usb_fill_control_urb的相比,只是少初始化了一个setup_packet,因为批量传输里没有Setup包的概念,中断传输里也没有,所以usb_fill_int_urb里也没有初始化setup_packet这一说。