当驱动有数据发送到 USB 设备(如同在驱动的 write 函数中发生的), 一个 urb 必须被 分配来传送数据到设备.

urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb)

{

retval = -ENOMEM; goto error;

}

在 urb 被成功分配后, 一个 DMA 缓冲也应当被创建来发送数据到设备以最有效的方式, 并且被传递到驱动的数据应当被拷贝到缓冲:

buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma); if (!buf)

{

retval = -ENOMEM; goto error;

}

if (copy_from_user(buf, user_buffer, count))

{

retval = -EFAULT; goto error;

}

应当数据被正确地从用户空间拷贝到本地缓冲, urb 在它可被提交给 USB 核心之前必须 被正确初始化:

/* initialize the urb properly */ usb_fill_bulk_urb(urb, dev->udev,

usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),

buf, count,
skel_write_bulk_callback, dev); urb->transfer_flags |=
URB_NO_TRANSFER_DMA_MAP;

现在 urb 被正确分配, 数据被正确拷贝, 并且 urb 被正确初始化, 它可被提交给 USB 核心来传递给设备.

/*
send the data out the bulk port */ retval = usb_submit_urb(urb, GFP_KERNEL); if
(retval)

{

err("%s
- failed submitting write urb, error %d", FUNCTION , retval); goto error;

}


urb 被成功传递到 USB 设备(或者在传输中发生了什么), urb 回调被 USB 核心调用. 在我们的例子中, 我们初始化 urb 来指向函数
skel_write_bulk_callback, 并且那就是 被调用的函数:

static
void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs)

{

/*
sync/async unlink faults aren't errors */ if (urb->status &&

!(urb->status
== -ENOENT ||

urb->status ==
-ECONNRESET || urb->status == -ESHUTDOWN)){

dbg("%s - nonzero write
bulk status received: %d",

FUNCTION  , urb->status);

}

/*
free up our allocated buffer */

usb_buffer_free(urb->dev,
urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma);

}

回调函数做的第一件事是检查 urb 的状态来决定是否这个 urb 成功完成或没有. 错误值,

-ENOENT, -ECONNRESET, 和 -ESHUTDOWN 不是真正的传送错误, 只是报告伴随成功传送的 情况. (见
urb 的可能错误的列表, 在"结构 struct urb"一节中详细列出). 接着这个回 调释放安排给这个 urb 传送的已分配的缓冲.

在 urb 的回调函数在运行时另一个 urb 被提交给设备是普遍的. 当流数据到设备时是有 用的. 记住 urb 回调是在中断上下文运行,
因此它不应当做任何内存分配, 持有任何旗 标, 或者任何可导致进程睡眠的事情. 当从回调中提交 urb, 使用
GFP_ATOMIC 标志来告 知 USB 核心不要睡眠, 如果它需要分配新内存块在提交过程中.

最新文章

  1. DevExpress免费公开课,讲解即将发布的16.2新版功能
  2. ABP理论学习之Swagger UI集成
  3. JavaScript把客户端时间转换为北京时间
  4. KnockoutJS 3.X API 第四章(14) 绑定语法细节
  5. Windows Server 2012安装时所需要的KEY
  6. JQuery Datatables Dom 和 Language 参数详细说明
  7. 161031、java.util.StringTokenizer使用及源码
  8. SqlServer数据库的查询优化
  9. 快递查询API接口(trackingmore)
  10. opencv获取图片sift特征
  11. Windows手动搭建PHP运行环境
  12. Windows的免費hMailServer搭配SpamAssassin過濾垃圾郵件:安裝與設定
  13. KeilMDK4.7a下载地址/中文乱码解决/自动关联设置
  14. 不在界面上用控件 动态创建idhttp,IdAntiFreeze来用
  15. 使用Curl进行抓取远程内容时url中文编码问题
  16. 实例学习SSIS(四)--使用日志记录和错误流重定向
  17. iOS上传代码到Github平台
  18. linux日志logger命令详解
  19. Git-Book
  20. Linux命令:linux软链接的创建、删除和更新---ln

热门文章

  1. pl/sql基础知识—函数快速入门
  2. 【Leetcode栈】有效的括号(20)
  3. nodeJs学习-13 router
  4. jq 添加内容
  5. [自考]C++中一些特殊用法 2016-10-16 22:12 318人阅读 评论(30) 收藏
  6. BZOJ 1008 越狱题解
  7. MUI - 实现关闭除指定页面外的其他所有页面的功能
  8. sql —— order by
  9. Java实现接口用来弥补Java单继承的缺陷
  10. mysql 中 DATE_ADD(date,INTERVAL expr type)