struct urb 结构中和 USB 设备驱动有关的成员是: struct usb_device *dev
指向这个 urb 要发送到的 struct usb_device 的指针. 这个变量必须被 USB 驱 动初始化, 在这个 urb 被发送到 USB 核心之前.
unsigned int pipe
端点消息, 给这个 urb 要被发送到的特定 struct usb_device. 这个变量必须被 USB 驱动初始化, 在这个 urb 被发送到 USB 核心之前.
为设置这个结构的成员, 驱动使用下面的函数是适当的, 依据流动的方向. 注意每 个端点只可是一个类型.
unsigned int usb_sndctrlpipe(struct usb_device *dev, unsigned int endpoint)
指定一个控制 OUT 端点给特定的带有特定端点号的 USB 设备.
unsigned int usb_rcvctrlpipe(struct usb_device *dev, unsigned int endpoint)
指定一个控制 IN 端点给带有特定端点号的特定 USB 设备.
unsigned int usb_sndbulkpipe(struct usb_device *dev, unsigned int endpoint)
指定一个块 OUT 端点给带有特定端点号的特定 USB 设备
unsigned int usb_rcvbulkpipe(struct usb_device *dev, unsigned int endpoint)
指定一个块 IN 端点给带有特定端点号的特定 USB 设备
unsigned int usb_sndintpipe(struct usb_device *dev, unsigned int endpoint)
指定一个中断 OUT 端点给带有特定端点号的特定 USB 设备
unsigned int usb_rcvintpipe(struct usb_device *dev, unsigned int endpoint)
指定一个中断 IN 端点给带有特定端点号的特定 USB 设备
unsigned int usb_sndisocpipe(struct usb_device *dev, unsigned int endpoint)
指定一个同步 OUT 端点给带有特定端点号的特定 USB 设备
unsigned int usb_rcvisocpipe(struct usb_device *dev, unsigned int endpoint)
指定一个同步 IN 端点给带有特定端点号的特定 USB 设备 unsigned int transfer_flags
这个变量可被设置为不同位值, 根据这个 USB 驱动想这个 urb 发生什么. 可用的 值是:
URB_SHORT_NOT_OK
当置位, 它指出任何在一个 IN 端点上可能发生的短读, 应当被 USB 核心当作一 个错误. 这个值只对从 USB 设备读的 urb 有用, 不是写 urbs.
URB_ISO_ASAP
如果这个 urb 是同步的, 这个位可被置位如果驱动想这个 urb 被调度, 只要带宽 允许它这样, 并且在此点设置这个 urb 中的 start_frame 变量. 如果对于同步 urb 这个位没有被置位, 驱动必须指定 start_frame 值并且必须能够正确恢复, 如果没有在那个时刻启动. 见下面的章节关于同步 urb 更多的消息.
URB_NO_TRANSFER_DMA_MAP
应当被置位, 当 urb 包含一个要被发送的 DMA 缓冲. USB 核心使用这个被 transfer_dma 变量指向的缓冲, 不是被 transfer_buffer 变量指向的缓冲.
URB_NO_SETUP_DMA_MAP
象 URB_NO_TRANSFER_DMA_MAP 位, 这个位用来控制有一个 DMA 缓冲已经建立的 urb. 如果它被置位, USB 核心使用这个被 setup_dma 变量而不是 setup_packet 变量指向的缓冲.
URB_ASYNC_UNLINK
如果置位, 给这个 urb 的对 usb_unlink_urb 的调用几乎立刻返回, 并且这个 urb 在后面被解除连接. 否则, 这个函数等待直到 urb 完全被去链并且在返回前 结束. 小心使用这个位, 因为它可有非常难于调试的同步问题.
URB_NO_FSBR
只有 UHCI USB 主机控制器驱动使用, 并且告诉它不要试图做 Front Side Bus Reclamation 逻辑. 这个位通常应当不设置, 因为有 UHCI 主机控制器的机器创建 了许多 CPU 负担, 并且 PCI 总线被等待设置了这个位的 urb 所饱和.
URB_ZERO_PACKET
如果置位, 一个块 OUT urb 通过发送不包含数据的短报文而结束, 当数据对齐到 一个端点报文边界. 这被一些坏掉的 USB 设备所需要(例如一些 USB 到 IR 的设 备) 为了正确的工作..
URB_NO_INTERRUPT
如果置位, 硬件当 urb 结束时可能不产生一个中断. 这个位应当小心使用并且只 在排队多个到相同端点的 urb 时使用. USB 核心函数使用这个为了做 DMA 缓冲传 送.
void *transfer_buffer
指向用在发送数据到设备(对一个 OUT urb)或者从设备中获取数据(对于一个 IN urb)的缓冲的指针. 对主机控制器为了正确存取这个缓冲, 它必须被使用一个对 kmalloc 调用来创建, 不是在堆栈或者静态地. 对控制端点, 这个缓冲是给发送的 数据阶段.
dma_addr_t transfer_dma
用来使用 DMA 传送数据到 USB 设备的缓冲. int transfer_buffer_length
缓冲的长度, 被 transfer_buffer 或者 transfer_dma 变量指向(由于只有一个可 被一个 urb 使用). 如果这是 0, 没有传送缓冲被 USB 核心所使用.
对于一个 OUT 端点, 如果这个端点最大的大小比这个变量指定的值小, 对这个 USB 设备的传送被分成更小的块为了正确的传送数据. 这种大的传送发生在连续的 USB 帧. 提交一个大块数据在一个 urb 中是非常快, 并且使 USB 主机控制器去划 分为更小的快, 比以连续的顺序发送小缓冲.
unsigned char *setup_packet
指向给一个控制 urb 的 setup 报文的指针. 它在位于传送缓冲中的数据之前被传 送. 这个变量只对控制 urb 有效.
dma_addr_t setup_dma
给控制 urb 的 setupt 报文的 DMA 缓冲. 在位于正常传送缓冲的数据之前被传送. 这个变量只对控制 urb 有效.
usb_complete_t complete
指向完成处理者函数的指针, 它被 USB 核心调用当这个 urb 被完全传送或者当 urb 发生一个错误. 在这个函数中, USB 驱动可检查这个 urb, 释放它, 或者重新 提交它给另一次传送.(见"completingUrbs: 完成回调处理者", 关于完成处理者的 更多细节).
usb_complete_t 类型定义如此:
typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); void *context
指向数据点的指针, 它可被 USB 驱动设置. 它可在完成处理者中使用当 urb 被返 回到驱动. 关于这个变量的细节见后续章节.
int actual_length
当这个 urb 被完成, 这个变量被设置为数据的真实长度, 或者由这个 urb (对于 OUT urb)发送或者由这个 urb(对于 IN urb)接受. 对于 IN urb, 这个必须被用来 替代 transfer_buffer_length 变量, 因为接收的数据可能比整个缓冲大小小.
int status
当这个 urb 被结束, 或者开始由 USB 核心处理, 这个变量被设置为 urb 的当前 状态. 一个 USB 驱动可安全存取这个变量的唯一时间是在 urb 完成处理者函数中 (在"CompletingUrbs: 完成回调处理者"一节中描述). 这个限制是阻止竞争情况, 发生在这个 urb 被 USB 核心处理当中. 对于同步 urb, 在这个变量中的一个成功 的值(0)只指示是否这个 urb 已被去链. 为获得在同步 urb 上的详细状态, 应当 检查 iso_frame_desc 变量.
这个变量的有效值包括: 0
这个 urb 传送是成功的.
-ENOENT
这个 urb 被对 usb_kill_urb 的调用停止.
-ECONNRESET
urb 被对 usb_unlink_urb 的调用去链, 并且 transfer_flags 变量被设置为 URB_ASYNC_UNLINK.
-EINPROGRESS
这个 urb 仍然在被 USB 主机控制器处理中. 如果你的驱动曾见到这个值, 它是一 个你的驱动中的 bug.
-EPROTO
这个 urb 发生下面一个错误:
- 一个 bitstuff 错误在传送中发生.
- · 硬件没有及时收到响应帧.
-EILSEQ
在这个 urb 传送中有一个 CRC 不匹配.
-EPIPE
这个端点现在被停止. 如果这个包含的端点不是一个控制端点, 这个错误可被清除 通过一个对函数 usb_clear_halt 的调用.
-ECOMM
在传送中数据接收快于能被写入系统内存. 这个错误值只对 IN urb.
-ENOSR
在传送中数据不能从系统内存中获取得足够快, 以便可跟上请求的 USB 数据速率. 这个错误只对 OUT urb.
-EOVERFLOW
这个 urb 发生一个"babble"错误. 一个"babble"错误发生当端点接受数据多于端 点的特定最大报文大小.
-EREMOTEIO
只发生在当 URB_SHORT_NOT_OK 标志被设置在 urb 的 transfer_flags 变量, 并 且意味着 urb 请求的完整数量的数据没有收到.
-ENODEV
这个 USB 设备现在从系统中消失.
-EXDEV
只对同步 urb 发生, 并且意味着传送只部分完成. 为了决定传送什么, 驱动必须 看单独的帧状态.
-EINVAL
这个 urb 发生了非常坏的事情. USB 内核文档描述了这个值意味着什么: ISO 疯了, 如果发生这个: 退出并回家.
它也可发生, 如果一个参数在 urb 结构中被不正确地设置了, 或者如果在提交这 个 urb 给 USB 核心的 usb_submit_urb 调用中, 有一个不正确的函数参数.
-ESHUTDOWN
这个 USB 主机控制器驱动有严重的错误; 它现在已被禁止, 或者设备和系统去掉 连接, 并且这个 urb 在设备被去除后被提交. 它也可发生当这个设备的配置改变, 而这个 urb 被提交给设备.
通常, 错误值 -EPROTO, -EILSEQ, 和 -EOVERFLOW 指示设备的硬件问题, 设备固 件, 或者连接设备到计算机的线缆.
int start_frame
设置或返回同步传送要使用的初始帧号. int interval
urb 被轮询的间隔. 这只对中断或者同步 urb 有效. 这个值的单位依据设备速度 而不同. 对于低速和高速的设备, 单位是帧, 它等同于毫秒. 对于设备, 单位是宏 帧的设备, 它等同于 1/8 微秒单位. 这个值必须被 USB 驱动设置给同步或者中断 urb, 在这个 urb 被发送到 USB 核心之前.
int number_of_packets
只对同步 urb 有效, 并且指定这个 urb 要处理的同步传送缓冲的编号. 这个值必 须被 USB 驱动设置给同步 urb, 在这个 urb 发送给 USB 核心之前.
int error_count
被 USB 核心设置, 只给同步 urb 在它们完成之后. 它指定报告任何类型错误的同 步传送的号码.
struct usb_iso_packet_descriptor iso_frame_desc[0]
只对同步 urb 有效. 这个变量是组成这个 urb 的一个 struct usb_iso_packet_descriptor 结构数组. 这个结构允许单个 urb 来一次定义多个 同步传送. 它也用来收集每个单独传送的传送状态.
结构 usb_iso_packet_descriptor 由下列成员组成:
unsigned int offset 报文数据所在的传送缓冲中的偏移(第一个字节从 0 开始). unsigned int length
这个报文的传送缓冲的长度. unsigned int actual_length
接收到给这个同步报文的传送缓冲的数据长度. unsigned int status
这个报文的单独同步传送的状态. 它可采用同样的返回值如同主 struct urb 结构 的状态变量.