struct urb { /* private: usb core and host controller only fields in the urb */ struct kref kref; /* URB引用计数 */ void *hcpriv; /* host控制器的私有数据 */ atomic_t use_count; /* 当前提交计数 */ atomic_t reject; /* 提交失败计数 */ int unlinked; /* 连接失败代码 */ /* public: documented fields in the urb that can be used by drivers */ struct list_head urb_list; /* list head for use by the urb's * current owner */ struct list_head anchor_list; /* the URB may be anchored */ struct usb_anchor *anchor; struct usb_device *dev; /* 指向这个 urb 要发送的目标 struct usb_device 的指针,这个变量必须在这个 urb 被发送到 USB 核心之前被 USB 驱动初始化.*/ struct usb_host_endpoint *ep; /* (internal) pointer to endpoint */ unsigned int pipe; int status; unsigned int transfer_flags; /* 传输设置*/ void *transfer_buffer; /* 指向用于发送数据到设备(OUT urb)或者从设备接收数据(IN urb)的缓冲区指针。为了主机控制器驱动正确访问这个缓冲, 它必须使用 kmalloc 调用来创建, 不是在堆栈或者静态内存中。 对控制端点, 这个缓冲区用于数据中转*/ dma_addr_t transfer_dma; /* 用于以 DMA 方式传送数据到 USB 设备的缓冲区*/ int transfer_buffer_length; /* transfer_buffer 或者 transfer_dma 变量指向的缓冲区大小。如果这是 0, 传送缓冲没有被 USB 核心所使用。对于一个 OUT 端点, 如果这个端点大小比这个变量指定的值小, 对这个 USB 设备的传输将被分成更小的块,以正确地传送数据。这种大的传送以连续的 USB 帧进行。在一个 urb 中提交一个大块数据, 并且使 USB 主机控制器去划分为更小的块, 比以连续地顺序发送小缓冲的速度快得多*/ int actual_length; /* 当这个 urb 完成后, 该变量被设置为这个 urb (对于 OUT urb)发送或(对于 IN urb)接受数据的真实长度.对于 IN urb, 必须是用此变量而非 transfer_buffer_length , 因为接收的数据可能比整个缓冲小*/ unsigned char *setup_packet; /* 指向控制urb的设置数据包指针.它在传送缓冲中的数据之前被传送(用于控制 urb)*/ dma_addr_t setup_dma; /* 控制 urb 用于设置数据包的 DMA 缓冲区地址,它在传送普通缓冲区中的数据之前被传送(用于控制 urb)*/ int start_frame; /* 设置或返回初始的帧数量(用于等时urb) */ int number_of_packets; int interval; int error_count; /* 等时urb的错误计数,由USB核心设置 */ void *context; /* 指向一个可以被USB驱动模块设置的数据块. 当 urb 被返回到驱动时,可在结束处理例程中使用. */ usb_complete_t complete; /* 结束处理例程函数指针, 当 urb 被完全传送或发生错误,它将被 USB 核心调用. 此函数检查这个 urb, 并决定释放它或重新提交给另一个传输中*/ struct usb_iso_packet_descriptor iso_frame_desc[0]; };