USB URB的status及其代表的意义

平时在处理客户问题时,经常需要分析出现问题时抓取的usbmon log,这个log中有一个字段非常重要:URB Status word,这个字段就是struct urb结构体中的status成员变量。

通过这个status的值,可以分析出模块端和HOST端usb的一些状态,有利于定位到问题点。

Linux内核中对该成员变量的注释如下:

表明该字段仅仅表示批量传输、控制传输和中断传输的URB状态,等时传输不在其中,不过我们的模组也没有等时传输的端点。

在讲解URB的status之前先看下linux中URB的处理流程,如下图所示:

① 使用usb_alloc_urb()创建一个URB结构体

② 对于不同的传输方式,分别使用相应的函数初始化URB,中断传输使用usb_fill_int_urb(),批量传输使用usb_fill_bulk_urb(),控制传输使用usb_fill_control_urb(),等时传输比较特殊需要手动初始化URB。

③ 使用usb_submit_urb()向usb控制器提交上一步初始化完成的URB,提交成功函数返回0,提交失败函数返回一个负数。当提交失败时,usbmon log中的Event Type字段就为 E(submission error)。

④ URB被提交到了usb控制器中,这个URB将来会有三种命运,而这三种URB的结束方式就对应到URB的status。

  第一种:成功完成传输

  第二种:传输发生了错误

  第三种:URB从usb控制器中"unlinked"

⑤ 当URB结束时,会调用之前注册的complete回调函数

URB成功传输的情况

在这种情况下,URB被成功发送给设备,并且设备返回正确的确认。对于一个输出URB,表示数据被成功发送;对于一个输入URB,成功获取请求的数据。此时,urb->status = 0;

下面是一条qmi消息成功交互的过程:

ffff8800b7d91740 1791319201 S Ii:3:008:9 -115:256 8 <              // 这里的-115(EINPROGRESS)仅仅表示URB被提交给usb控制器去处理了
ffff8800b7d90600 1791319354 S Co:3:008:0 s 21 00 0000 0004 000c 12 = 010b0000 00000001 27000000
ffff8800b7d90600 1791320572 C Co:3:008:0 0 12 >                     // 这里urb status为0,表示qmi request消息成功发送给模块了
ffff8800b7d91740 1791329515 C Ii:3:008:9 0:256 8 = a1010000 04000000                                                // 这里Ti的urb status为0,表明可以读取qmi的response信息了
ffff8800b7d915c0 1791329530 S Ci:3:008:0 s a1 01 0000 0004 1000 4096 <
ffff8800b7d91740 1791329570 S Ii:3:008:9 -115:256 8 <
ffff8800b7d915c0 1791331992 C Ci:3:008:0 0 19 = 01120080 00000101 27000700 02040000 000000      // 这里返回0,表示HOST端成功的读取了模块的qmi response

再看一下AT指令的交互过程:

ffff8800b1480f00 2819829981 S Bo:3:008:3 -115 1 = 61
ffff8800b1480f00 2819830240 C Bo:3:008:3 0 1 >                     // 成功向模块发送了 A
ffff8800b1480f00 2819926000 S Bo:3:008:3 -115 1 = 74  
ffff8800b1480f00 2819926105 C Bo:3:008:3 0 1 >                     // 成功向模块发送了T
ffff8800b1480f00 2821094084 S Bo:3:008:3 -115 1 = 0d
ffff8800b1480f00 2821094267 C Bo:3:008:3 0 1 >                    // 成功向模块发送了换行
ffff8800b1481e00 2821094738 C Bi:3:008:4 0 6 = 0d0a4f4b 0d0a
ffff8800b1481e00 2821094752 S Bi:3:008:4 -115 4096 <
ffff8800b1481b00 2821097257 C Ii:3:008:5 0:256 10 = a1200000 02000200 0000     // 成功读取模块的AT Response  ==>  OK

URB传输异常

urb传输异常就有很多种了,下面列举一下常见的错误对应的status:

注:下面的usb status状态码在 linux-x.x.x/Documentation/usb/error-codes.txt 这个文件中有详细的说明,可以参考一下。

-EINPROGRESS (-115)

这个字段前面已经说过了,它出现在URB submission的时候,表示这个URB的控制权交给了usb控制器,将由usb控制器处理,这个并不是真正的错误。

-EPROTO (-71)

有两种原因会导致这个错误:

    • A bitstuff error happened during the transfer
    • No response packet was received in time by the hardware

这个错误经常发生在usb设备枚举失败时,下图就是EC25模块在客户树莓派上枚举失败对应的log,URB的status字段为-71

-EILSEQ (-84)

这个错误不太常见,具体可以参考error-codes.txt

-ECOMM (-70)

对于IN URB,在数据传输中,接收USB设备数据的速度  >  将数据写入内存中的速度

-ENOSR (-63)

在OUT URB数据传输中,数据不能从系统内存中获取的足够快,以便可以跟上请求的usb的数据速率

-EPIPE (-32)

这个表明usb管道"不通",批量端点可能会设置了halt条件,设置了这种条件的端点必然会堵塞管道,可以使用usb_clear_halt()清除halt

-EOVERFLOW (-75)

当发送给端点的数据包长度大于端点特定的数据包长度时会出现这个错误,从错误码也能看出来,数据“溢出了“

ENODEV (-19)

usb设备已经从系统中移除,但是hub没有及时检测到usb设备的断开,驱动仍然提交URB,就会导致这个错误发生。

Note: -EPROTO、-EILSEQ、-EOVERFLOW一般是由于usb设备、设备固件或usb数据线出问题导致的。

URB从usb控制器中"unlinked"

"unlinked"发生下下面的场景下:

(1)驱动中调用 usb_unlink_urb( ) 或 usb_kill_urb( ) 主动取消一个已经提交给usb控制器的URB

调用 usb_unlink_urb( ) 之后,URB的status值为-104(ECONNRESET)

调用 usb_kill_urb( ) 之后,URB的status值为-2(ENOENT)

(2)当URB已经提交给某个usb设备,但该设备被remove了,硬件断开了,比如将模块从主机上拔掉,这种情况下URB的status字段就为-108(ESHUTDOWN)

下面举几个例子:

使用 busybox microcom /dev/ttyUSB2 命令打开模块的AT口(open /dev/ttyUSB2),什么都不输入,然后 ctrl+x 退出 microcom(close /dev/ttyUSB2),相应的usbmon log如下:

可以看到,当主动退出microcom时,相应的URB的status字段值为-2,对应到串口驱动中就是调用了usb_wwan_close()中的usb_kill_urb()

对应的E(submission error)是在回调函数重新提交URB产生的,此时串口已经close,再去提交就产生了错误。

后面URB的status字段为-1(EPERM),这里分析 usb_submit_urb() 的代码,可以看到-1是 usb_submit_urb() 的返回值

usb_submit_urb

return usb_hcd_submit_urb;

同样使用 busybox microcom /dev/ttyUSB2 命令打开模块的AT口,然后此时拔掉EVB板,断开usb设备,对应的usbmon log如下,可以比较和前面的区别:

-108(ESHUTDOWN)是usb物理层断开URB对应的status

下面再看一下模块autosuspend过程中的usbmon log:

echo auto > /sys/bus/usb/devices/3-2.1/power/control 使用模块的autosuspend

ffff8800ba722240 2220899617 S Ci:3:009:0 s 80 00 0000 0000 0002 2 <
ffff8800ba722240 2220901604 C Ci:3:009:0 0 2 = 0000
ffff8800b7da3a40 2220901706 S Ii:3:009:5 -115:256 10 <
ffff8800b7da2180 2220901759 S Bi:3:009:4 -115 4096 <
ffff8800b7da2240 2220901798 S Bi:3:009:4 -115 4096 <
ffff8800b7da2f00 2220901824 S Bi:3:009:4 -115 4096 <
ffff8800b7da2d80 2220901850 S Bi:3:009:4 -115 4096 <
ffff8800ba722240 2220901891 S Co:3:009:0 s 21 22 0003 0002 0000 0
ffff8800ba722240 2220902834 C Co:3:009:0 0 0
ffff8800b7da3a40 2220905343 C Ii:3:009:5 0:256 10 = a1200000 02000200 0000
ffff8800b7da3a40  S Ii:3:009:5 -115:256 10 <    
ffff8800b7da2180 2223569116 C Bi:3:009:4 -2 0           // ① 这里等待了2s(2223, 569116 - 2220, 905360),然后进入了autosuspend  ② -2是这个URB在suspend函数中被usb_kill_urb()取消了

ffff8800b7da2180 2223569160 S Bi:3:009:4 -115 4096 <
ffff8800b7da2180 2223569172 E Bi:3:009:4 -1 0          // 这里和前面出现的原因相同,模块已经进入autosuspend,回调函数中又去提交这个URB
ffff8800b7da2240 2223569519 C Bi:3:009:4 -2 0
ffff8800b7da2240 2223569523 S Bi:3:009:4 -115 4096 <
ffff8800b7da2240 2223569528 E Bi:3:009:4 -1 0
ffff8800b7da2f00 2223569776 C Bi:3:009:4 -2 0
ffff8800b7da2f00 2223569810 S Bi:3:009:4 -115 4096 <
ffff8800b7da2f00 2223569815 E Bi:3:009:4 -1 0
ffff8800b7da2d80 2223570119 C Bi:3:009:4 -2 0
ffff8800b7da2d80 2223570159 S Bi:3:009:4 -115 4096 <
ffff8800b7da2d80 2223570167 E Bi:3:009:4 -1 0
ffff8800b7da3a40 2223571635 C Ii:3:009:5 -2:256 0
ffff8800ba722540 2223571783 S Co:3:009:0 s 00 03 0001 0000 0000 0
ffff8800ba722540 2223572943 C Co:3:009:0 0 0

ffff8800ba722540 2223573179 S Co:3::0 s 23 03 0002 0001 0000 0   // 这里是hub发出的,Port1:PORT_SUSPEND
ffff8800ba722540 2223574608 C Co:3::0 0 0

USB URB的status及其代表的意义的更多相关文章

  1. 解析UML箭头、线条代表的意义(转)

    在学习UML过程中,你经常会遇到UML类图关系,这里就向大家介绍一下UML箭头.线条代表的意义,相信通过本文的介绍你对UML中箭头.线条的意义有更明确的认识. AD: 本节向大家学习一下UML箭头.线 ...

  2. dojo表格分页之各个参数代表的意义(一)

    下面是dojo表格分页参数代表的意义 //每页可以显示10/15/20/25/30条记录 (1)pageSizes: [10, 15, 20, 25,30], //每页显示的记录从多少到多少,共多少条 ...

  3. ConnectTimeout和ReadTimeout所代表的意义

    参考:ConnectTimeout和ReadTimeout所代表的意义 ConnectTimeout 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间. 在java中,网络状况 ...

  4. 有关/proc/uptime这个文件里两个参数所代表的意义

    有关/proc/uptime这个文件里两个参数所代表的意义: [root@app ~]#cat /proc/uptime 3387048.81 3310821.00 第一个参数是代表从系统启动到现在的 ...

  5. X32,X64,X86 代表什意义

    X32,X64,X86是什么意思 各代表什么:X86指32位,X64指64位,现在用户最多的是XP,但win7是趋势,发展很快,建议你装个win7 32位的系统,下载的话地方很多,官方安装原版和gho ...

  6. preg_match的isU代表什么意义

    正则后面的/(.*)/isU  ,“isU”参数代表什么意思?这是正则中的修正符.i是同时查找大小写字母,s是圆点(.)匹配所有字符,包括换行符.如果没有设定s,则不包括换行符.U是反转了匹配数量的值 ...

  7. Makefile-有三个非常有用的变量。分别是$@,$^,$<代表的意义

    $@ 代表目标文件,$^ 代表所有的依赖文件,$< 代表第一个依赖文件. # 这是简化后的Makefilemain:main.o mytool1.o mytool2.o gcc -o $@ $^ ...

  8. 关于inet_ntop、inet_pton中的n和p分别代表的意义

    函数名中的p和n非别代表表达(presentation)和数值(numeric).地址的表达格式通常是ASCII字符串,数值格式则是存放到套接字地址结构中的二进制值. 参考自:https://blog ...

  9. Renice INC:不同颜色的酒帽所代表的意义

    酒帽就是酒瓶上方的热缩胶帽/锡帽/蜡封,也就是开瓶前要割掉的那一层保护物,所有的法国酒在酒帽上,都会有一个圆形贴纸,除了有不同颜色外,上面还有一串号码,有可能很多人在喝酒时都不会对这个酒帽有更多的在意 ...

随机推荐

  1. Python 为什么要在 18 年前引入布尔类型?且与 C、C++ 和 Java 都不同?

    花下猫语:在上一篇<Python 为什么能支持任意的真值判断? >文章中,我们分析了 Python 在真值判断时的底层实现,可以看出 Python 在对待布尔值时,采用了比较宽泛的态度.官 ...

  2. [netty4][netty-handler]netty之idle handler处理

    初始化时记录idle时间,并启动一个延时任务,延时时间为idle时间,延时任务是io.netty.handler.timeout.IdleStateHandler.AllIdleTimeoutTask ...

  3. 【NOI2015】 软件包管理器 - 树链剖分

    noi2015 软件包管理器 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...

  4. jvm之方法内联优化

    前言 在日常中工作中,我们时不时会代码进行一些优化,比如用新的算法,简化计算逻辑,减少计算量等.对于java程序来说,除了开发者本身对代码优化之外,还有一个"人"也在背后默默的优化 ...

  5. window下命令启动/停止nginx

    查看Nginx的版本号:nginx -v 启动Nginx:start nginx 快速停止或关闭Nginx:nginx -s stop 正常停止或关闭Nginx:nginx -s quit 配置文件修 ...

  6. badger 一个高性能的LSM K/V store

    原文:https://colobu.com/2017/10/11/badger-a-performant-k-v-store/ github地址:https://github.com/dgraph-i ...

  7. Spring官方宣布:新的Spring OAuth2.0授权服务器已经来了

    1. 前言 记不记得之前发过一篇文章Spring 官方发起Spring Authorization Server 项目.该项目是由Spring Security主导的一个社区驱动的.独立的孵化项目.由 ...

  8. CSS布局中浮动问题的四种解决方案

    一.起因: 子盒子设置浮动之后效果: 由此可见,蓝色的盒子设置浮动之后,因为脱离了标准文档流,它撑不起父盒子的高度,导致父盒子高度塌陷.如果网页中出现了这种问题,会导致我们整个网页的布局紊乱 二.解决 ...

  9. 阿里大牛教你基于Python的 Selenium自动化测试示例解析

    今天给大家讲解的是自动化测试示例的解析,如有不对的地方请多多指教. 自动化测试示例如下: from selenium import webdriver from selenium.webdriver. ...

  10. e3mall商城的归纳总结6之redis

    一.说在前面的话 前面几节我们主要对该项目的后端进行了增删改查,但是所有的数据都是存放在数据库中,这样的话数据库的压力显而易见是很大的,因此本节学习nosql的缓存,也就是redis的使用,在使用之前 ...