Linux下usb设备驱动详解

时间:2023-12-24 21:48:01

USB驱动分为两块,一块是USB的bus驱动,这个东西,Linux内核已经做好了,我们可以不管,我们只需要了解它的功能。形象的说,USB的bus驱动相当于铺出一条路来,让所有的信息都可以通过这条USB通道到达该到的地方,这部分工作由usb_core(drivers/usb/usb.c)来完成。当USB设备接到USB控制器接口时,usb_core就检测该设备的一些信息,如生产厂商的ID(VID)和产品的ID(PID),或者是设备所属的class、subclass跟protocol,以便确定应该调用哪一个驱动处理该设备。里面复杂细节我们不用管,我们要做的是另一块工作——usb的设备驱动。也就是说,我们就等着usb_core告诉我们要工作了,我们才工作。

OHCI(Open Host Controller Interface)是支持USB1.1的标准,但它不仅仅是针对USB,还支持其他的一些接口,比如它还支持Apple的火线(Firewire,IEEE 1394)接口。与UHCI相比,OHCI的硬件复杂,硬件做的事情更多,所以实现对应的软件驱动的任务,就相对较简单。主要用于非x86的USB,如扩展卡、嵌入式开发板的USB主控。本文也是基于OHCI来介绍usb设备驱动的。

USB从设备的分类可以从USB设备接口描述符(Standard Interface   Descriptor)对应的的bInterfaceClass这一个byte得到。bInterfaceClass的典型代码为1,2,3,6,7,8,9,10,11,255。分别代表的意思为

1-audio:表示一个音频设备。
2-communication  device:通讯设备,如电话,moden等等。
3-HID:人机交互设备,如键盘,鼠标等。
6-image图象设备,如扫描仪,摄像头等,有时数码相机也可归到这一类。
7-打印机类。如单向,双向打印机等。
8-mass storage海量存储类。所有带有一定存储功能的都可以归到这一类。
9-hub类。
11-chip card/smart card。
255-vendor specific.厂家的自定义类,主要用于一些特殊的设备。如接口转接卡等。

  1. USB 4种传输方式

针对设备对系统资源需求的不同,在USB规范中规定了4种数据传输方式:

(1)等时传输。该方式用来连接需要连续传输,且对数据的正确性要求不高而对时间极为敏感的外部设备,如麦克风、音响及电话等。等时传输方式以固定的传输速率,连续不断地在主机与USB设备之间传输数据,在传输数据发生错误是,USB并不处理这些错误,而是继续传送信的数据。

(2)中断传输。改方式传输的数据量很小,但这些数据需要及时处理,以达到实时效果,以此方式主要用在键盘、鼠标以及游戏手柄等外部设备上。

(3)控制传输。改方式用来处理主机的USB设备的数据传输。包括设备控制指令、设备状态查询及确认命令。当USB设备收到这些数据和命令后,将依据先进先出的原则按队列方式处理到达的数据。

(4)批量传输、该方式用来传输要求正确无误的数据。通常打印机、扫描仪和数码相机以这种方式与主机连接。

在这4种数据传输方式中,除等时传输方式外,其他3种方式在数据传输发生错误是,都会试图重行发送数据以保证其正确性。

3.USB枚举

枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序。调试USB设备,很重要的一点就是USB的枚举过程,只要枚举成功了,那么就已经成功大半了。

3.1 USB枚举过程概述

USB主机检测到USB设备插入后,就会先对设备复位。设备复位后,USB主机就会对地址为0的设备发送获取设备描述符的标准请求。所有的USB设备在总线复位后其他地址都为0,这样主机可以跟那些刚刚插入的设备通过地址0通信。主机在建立阶段发出获取设备描述符的输入请求,设备受到请求后,将设备描述符返回给主机。主机在成功获取到一个数据包的设备描述符后并且确认没有错误后(有些usb设备的断点0大小不足18字节,但至少有8字节,而标准的设备描述符有18个字节,在这种情况下,USB设备只能暂时按最大包将部分设备描述符返回,而主机在成功获取到前面一部分描述符后,就不会在请求剩下的设备描述符部分,而是进入设置地址阶段),就会返回一个0长度的状态数据包给设备。

然后主机再对设备复位一下,接下来就会静茹到设置地址阶段。这时USB主机发出一个设置地址的请求(建立过程,设置地址无数据过程),地址包含在建立包过程,具体的地址USB主机会负责管理,它会分配一个唯一的地址给新的设备。USB设备在收到地址后,返回0长度的状态包,主机收到0长度的状态包后,会返回一个ACK给设备。设备在收到这个ACK后,就可以启用这个新地址了。这样设备就分配到了一个唯一的设备地址,以后主机就通过它来访问该设备。

然后主机再次获取设备描述符,这次跟第一次可能有点不一样,这次需要获取全部的18个字节的设备描述符。当然,若果你的端点0缓冲大小大于18个自己的话,那就跟第一次的情形一样了。

接下来,主机会获取配置描述符。配置描述符总共为9个字节。主机在获得到配置描述符后,根据里面的配置集合总长度,再获得配置集合。配置集合包括配置描述符,接口描述符,端点描述符等。

如果有字符串描述符的话,还要获取字符串描述符。另外HID设备还有HID描述符等。

USB设备枚举过程主要可分为8个部分:

1、获取设备描述符

2、复位

3、设置地址

4、再次获取设备描述符

5、获取配置描述符

6、获取接口、端点描述符

7、获取字符串描述符

8、选择设备配置

(附3是HP1108打印机插到pc上时通过Bus Hound抓到的枚举过程,可以以作为一个很好的学习例子。)

3.2 USB枚举过程详解

USB协议定义了设备的6种状态,仅在枚举过程中,设备就经历了4个状态的迁移:上电状态(Powered),默认状态(Default),地址状态(Address)和配置状态(Configured)(其他两种是连接状态和挂起状态(Suspend))。

(1)用户把USB设备插入USB端口或系统启动时给设备上电

这里的USB端口指的是主机下的根hub或主机下行端口上的hub端口。Hub给端口供电(hub.c:usb_hub_power_on()),连接着的设备处于上电状态。此时,USB设备处于加电状态,它所连接的端口是无效的。

(2) Hub监测它各个端口数据线上(D+/D-)的电压

在hub端,数据线D+和D-都有一个阻值在14.25k到24.8k的下拉电阻Rpd,而在设备端,D+(全速,高速)和D-(低速)上有一个1.5k的上拉电阻Rpu。当设备插入到hub端口时,有上拉电阻的一根数据线被拉高到幅值的90%的电压(大致是3V)。hub检测到它的一根数据线是高电平,就认为是有设备插入,并能根据是D+还是D-被拉高来判断到底是什么设备(全速/低速)插入端口。检测到设备后,hub继续给设备供电,但并不急于与设备进行USB传输。

USB接口定义如下图所示:

(3)Host了解连接的设备

每个hub利用它自己的中断端点向主机报告它的各个端口的状态(hub.c:usb_hub_events()),报告的内容只是hub端口的设备连接/断开的事件。如果有连接/断开事件发生(hub.c:usb_hub_port_connect_change()),那么host会发送一个 usb_hub_port_status请求给hub以了解此次状态改变的确切含义。usb_hub_port_status等请求属于所有hub都要求支持的hub类标准请求(standard hub-class requests)。

(4) Hub检测所插入的设备是高速还是低速设备

hub通过检测USB总线空闲(Idle)时差分线的高低电压来判断所连接设备的速度类型,当host发来usb_hub_port_status请求时,hub就可以将此设备的速度类型信息回复给host。

(5) hub复位设备

主机一旦得知新设备已连上以后,它至少等待100ms以使得插入操作的完成以及设备电源稳定工作。然后主机控制器就向hub发出一个 usb_set_port_feature请求让hub复位其管理的端口(刚才设备插上的端口)。hub通过驱动数据线到复位状态(D+和D-全为低电平 ),并持续至少10ms。当然,hub不会把这样的复位信号发送给其他已有设备连接的端口,所以其他连在该hub上的设备自然看不到复位信号,不受影响。

(6) Host检测所连接的全速设备是否是支持高速模式

对于USB1.1协议,host不进行高速检测,设备将一直以全速工作。如果是USB 2.0协议,高速(High Speed)设备在初始时是默认全速(Full Speed )状态运行,所以对于一个支持USB 2.0的高速hub,当它发现它的端口连接的是一个全速设备时,会进行高速检测,看看目前这个设备是否还支持高速传输,如果是,那就切到高速信号模式,否则就一直在全速状态下工作。
    同样的,从设备的角度来看,如果是一个高速设备,在刚连接bub或上电时只能用全速信号模式运行(根据USB 2.0协议,高速设备必须向下兼容USB 1.1的全速模式)。随后hub会进行高速检测,之后这个设备才会切换到高速模式下工作。

(7) Hub建立设备和主机之间的信息通道

主机通过usb_hub_port_wait_reset不停地向hub发送usb_hub_port_status请求,以查询设备是否复位成功。Hub返回的报告信息中有专门的一位用来标志设备的复位状态。
    当hub撤销了复位信号,设备就处于默认/空闲状态(Default state),准备接收主机发来的请求。设备和主机之间的通信通过控制传输,默认地址0,端点号0进行。此时,设备能从总线上得到的最大电流是100mA。(所有的USB设备在总线复位后其地址都为0,这样主机就可以跟那些刚刚插入的设备通过地址0通信。)

(8) 主机发送usb_get_device_descriptor请求获取默认管道的最大包长度

默认管道(Default Pipe)在设备一端来看就是端点0。主机此时发送的请求是默认地址0,端点0,虽然所有未分配地址的设备都是通过地址0来获取主机发来的请求,但由于枚举过程不是多个设备并行处理,而是一次枚举一个设备的方式进行,所以不会发生多个设备同时响应主机发来的请求。
  设备描述符(附1)的第8字节(bMaxPacketSize)代表设备端点0的最大包大小。虽然说设备所返回的设备描述符(Device Descriptor)长度只有18字节,但系统也不在乎,此时,描述符的长度信息对它来说是最重要的。当完成第一次的控制传输后,也就是完成控制传输的状态阶段,系统会要求hub对设备进行再一次的复位操作(USB规范里面可没这要求)。再次复位的目的是使设备进入一个确定的状态。

(9) 主机给设备分配一个地址

主机控制器通过usb_set_address请求向设备分配一个唯一的地址。在完成这次传输之后,设备进入地址状态(Address state),之后就启用新地址继续与主机通信。这个地址对于设备来说是终生制的,设备在,地址在;设备消失(被拔出,复位,系统重启),地址被收回。同一个设备当再次被枚举后得到的地址不一定是上次那个了。

(10) 主机获取设备的信息

主机发送 usb_get_device_descriptor请求到新地址读取设备描述符,这次主机发送usb_get_device_descriptor会认真解析设备描述符的内容。设备描述符内信息包括端点0的最大包长度,设备所支持的配置(Configuration)个数,设备类型,VID(Vendor ID,由USB-IF分配), PID((Product ID,由厂商自己定制)等信息。Get_Descriptor请求(Device type)和设备描述符(已抹去VID,PID等信息)

之后主机发送usb_get_configuration请求,读取配置描述符(附2),字符串等,逐一了解设备更详细的信息。事实上,对于配置描述符的标准请求中,有时bLength(附2)一项会大于实际配置描述符的长度(9字节),比如255。这样的效果便是:主机发送了一个usb_get_configuration 的请求,设备会把接口描述符,端点描述符等后续描述符一并回给主机,主机则根据描述符头部的标志判断送上来的具体是何种描述符。
    接下来,主机就会获取配置描述符。配置描述符总共为9字节。主机在获取到配置描述符后,根据里面的配置集合总长度,再获取配置集合。配置集合包括配置描述符,接口描述符,端点描符等等。
    如果有字符串描述符的话,还要获取字符串描述符。另外HID设备还有HID描述符等。

(11)  主机给设备挂载驱动

主机通过解析描述符后对设备有了足够的了解,会通过usb_find_drivers选择一个最合适的驱动给设备。然后tell the world(announce_device)说明设备已经找到了,最后调用设备模型提供的接口usbdevfs_add_device将设备添加到 usb 总线的设备列表里,然后 usb总线会遍历驱动列表usb_driver_list里的每个驱动,调用自己的 usb_match_id 函数看它们和当前连接的设备或接口是否匹配,匹配的话就将控制权交到相应的设备驱动了。

对于复合设备,通常应该是不同的接口(Interface)配置给不同的驱动,因此,需要等到当设备被配置并把接口使能后才可以把驱动挂载上去。

(12) 设备驱动选择一个配置

驱动(注意,这里是驱动,之后的事情都是由驱动来接管负责与设备的通信)根据前面设备回复的信息,发送usb_set_configuration请求来正式确定选择设备的哪个配置(Configuration)作为工作配置(对于大多数设备来说,一般只有一个配置被定义)。至此,设备处于配置状态(Configured),当然,设备也应该使能它的各个接口(Interface)。
    对于复合设备,主机会在这个时候根据设备接口信息,给它们挂载驱动。至此,USB枚举过程结束,设备可以正常使用了。

附1  设备描述符结构体

//设备描述符
struct usb_device_descriptor {
    __u8  bLength;//端点描述符长度,单位为Byte
    __u8  bDescriptorType;//描述符的类型

__le16 bcdUSB;//以bcd码,标出的usb的版本号
    __u8  bDeviceClass;//该设备所属的类
    __u8  bDeviceSubClass;//该设备所属的子类
    __u8  bDeviceProtocol;//该设备所用的协议
    __u8  bMaxPacketSize0;//端点0的最大包大小
    __le16 idVendor;//厂商id
    __le16 idProduct;//产品id
    __le16 bcdDevice;//设备版本号
    __u8  iManufacturer;//制造商描述符串索引
    __u8  iProduct;//产品描述符串索引
    __u8  iSerialNumber;//usb串号串索引
    __u8  bNumConfigurations;//该设备所拥有的配置个数
} __attribute__ ((packed));

附2  配置描述符结构体
struct usb_config_descriptor {
    __u8  bLength;//端点描述符长度,单位为Byte
    __u8  bDescriptorType;//描述符的类型

__le16 wTotalLength;//配置描述符的总长度
    __u8  bNumInterfaces;//该配置下的接口个数
    __u8  bConfigurationValue;//该配置的索引
    __u8  iConfiguration;//配置描述符串索引
    __u8  bmAttributes;
    __u8  bMaxPower;//该配置所能供应的最大电流,以2mA为单位
} __attribute__ ((packed));

附3  BUS HOUND 抓usb打印机HP1108的枚举过程

Bus Hound 5.04 capture on Windows XP Service Pack 3. Complements of www.perisoft.net

Device - Device ID (followed by the endpoint for USB devices)
            (19) Prolific USB-to-Serial Comm Port (COM2)
            (21) USB Composite Device
            (22) HP Smart Install [ROM=1.0 ]
            (23) USB Printing Support
            (24) P1100 USB EWS Device Driver
            (25) HP LaserJet Professional P1108
  Phase  - Phase Type
            CMD   SCSI/ATAPI command         RESET bus reset
            CTL   USB control transfer       SENSE SCSI sense data
            IN    Data in transfer           USTS  USB status
            OUT   Data out transfer          ok    command complete
  Data   - Hex dump of the data transferred
  Descr  - Description of the phase
  Cmd... - Position in the captured data

Device  Phase  Data                                                                                                    Description       Cmd.Phase.Ofs(rep)
------  -----  ------------------------------------------------------------------------------------------------------  ----------------  ------------------
  21.0  CTL    80 06 00 03  00 00 ff 00                                                                                GET DESCRIPTOR           1.1.0(2)    
  21.0  IN     04 03 09 04                                                                                             ....                     1.2.0       
  21.0  CTL    80 06 02 03  09 04 ff 00                                                                                GET DESCRIPTOR           2.1.0(2)    
  21.0  IN     3e 03 48 00  50 00 20 00  4c 00 61 00  73 00 65 00  72 00 4a 00  65 00 74 00  20 00 50 00  72 00 6f 00  >.H.P. .L.a.s.e.         2.2.0       
               66 00 65 00  73 00 73 00  69 00 6f 00  6e 00 61 00  6c 00 20 00  50 00 31 00  31 00 30 00  38 00        f.e.s.s.i.o.n.a.         2.2.32      
  21.0  CTL    80 06 00 01  00 00 12 00                                                                                GET DESCRIPTOR           5.1.0       
  21.0  IN     12 01 00 02  00 00 00 40  f0 03 2a 00  00 01 01 02  03 01                                               .......@..*.....         5.2.0       
  21.0  CTL    80 06 00 02  00 00 09 00                                                                                GET DESCRIPTOR           6.1.0       
  21.0  IN     09 02 20 00  01 01 00 c0  31                                                                            .. .....1                6.2.0       
  21.0  CTL    80 06 00 02  00 00 20 00                                                                                GET DESCRIPTOR           7.1.0       
  21.0  IN     09 02 20 00  01 01 00 c0  31 09 04 00  00 02 08 06  50 05 07 05  04 02 00 02  00 07 05 84  02 00 02 00  .. .....1.......         7.2.0       
  21.0  CTL    80 06 00 03  00 00 02 00                                                                                GET DESCRIPTOR           8.1.0       
  21.0  IN     04 03                                                                                                   ..                       8.2.0       
  21.0  CTL    80 06 00 03  00 00 04 00                                                                                GET DESCRIPTOR           9.1.0       
  21.0  IN     04 03 09 04                                                                                             ....                     9.2.0       
  21.0  CTL    80 06 03 03  09 04 02 00                                                                                GET DESCRIPTOR          10.1.0       
  21.0  IN     2a 03                                                                                                   *.                      10.2.0       
  21.0  CTL    80 06 03 03  09 04 2a 00                                                                                GET DESCRIPTOR          11.1.0       
  21.0  IN     2a 03 30 00  30 00 30 00  30 00 30 00  30 00 30 00  30 00 30 00  51 00 38 00  37 00 57 00  42 00 50 00  *.0.0.0.0.0.0.0.        11.2.0       
               52 00 53 00  49 00 31 00  63 00                                                                         R.S.I.1.c.              11.2.32      
  21.0  CTL    00 09 01 00  00 00 00 00                                                                                SET CONFIG              12.1.0       
  21.0  CTL    01 0b 00 00  00 00 00 00                                                                                SET INTERFACE           13.1.0       
  21.0  CTL    a1 fe 00 00  00 00 01 00                                                                                GET MAX LUN             14.1.0       
  21.0  IN     00                                                                                                      .                       14.2.0       
  21.4  OUT    55 53 42 43  08 90 9e 89  24 00 00 00  80 00 06 12  00 00 00 24  00 00 00 00  00 00 00 00  00 00 00     USBC....$.......        15.1.0       
  21.4  IN     05 80 02 02  1f 00 00 00  48 50 20 20  20 20 20 20  53 6d 61 72  74 20 49 6e  73 74 61 6c  6c 20 20 20  ........HP              16.1.0       
               31 2e 30 20                                                                                             1.0                     16.1.32      
  21.4  IN     55 53 42 53  08 90 9e 89  00 00 00 00  00                                                               USBS.........           17.1.0       
  22    CMD    12 00 00 00  24 00                                                                                      INQUIRY                 18.1.0       
  22    IN     05 80 02 02  1f 00 00 00  48 50 20 20  20 20 20 20  53 6d 61 72  74 20 49 6e  73 74 61 6c  6c 20 20 20  ........HP              18.2.0       
               31 2e 30 20                                                                                             1.0                     18.2.32      
  22    CMD    12 00 00 00  24 00                                                                                      INQUIRY                 19.1.0(2)    
  21.4  OUT    55 53 42 43  00 8e ae 8a  24 00 00 00  80 00 06 12  00 00 00 24  00 00 00 00  00 00 00 00  00 00 00     USBC....$.......        20.1.0(2)    
  21.4  IN     05 80 02 02  1f 00 00 00  48 50 20 20  20 20 20 20  53 6d 61 72  74 20 49 6e  73 74 61 6c  6c 20 20 20  ........HP              21.1.0(2)    
               31 2e 30 20                                                                                             1.0                     21.1.32      
  21.4  IN     55 53 42 53  00 8e ae 8a  00 00 00 00  00                                                               USBS.........           22.1.0(2)    
  22    IN     05 80 02 02  1f 00 00 00  48 50 20 20  20 20 20 20  53 6d 61 72  74 20 49 6e  73 74 61 6c  6c 20 20 20  ........HP              19.2.0       
               31 2e 30 20                                                                                             1.0                     19.2.32      
  22    CMD    25 00 00 00  00 00 00 00  00 00                                                                         READ CAPACITY           27.1.0(2)    
  21.4  OUT    55 53 42 43  08 90 9e 89  08 00 00 00  80 00 0a 25  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00     USBC...........%        28.1.0(2)    
  21.4  USTS   04 00 00 c0                                                                                             stall pid               29.1.0(2)    
  21.4  RESET                                                                                                                                  30.1.0(2)    
  21.4  IN     55 53 42 53  08 90 9e 89  08 00 00 00  01                                                               USBS.........           31.1.0(2)    
  21.4  OUT    55 53 42 43  08 90 9e 89  12 00 00 00  80 00 0c 03  00 00 00 12  00 00 00 00  00 00 00 00  00 00 00     USBC............        32.1.0(2)    
  21.4  IN     70 00 06 00  00 00 00 0a  00 00 00 00  28 00 00 00  00 00                                               p...........(...        33.1.0(2)    
  21.4  IN     55 53 42 53  08 90 9e 89  00 00 00 00  00                                                               USBS.........           34.1.0(2)    
  22    SENSE  70 00 06 00  00 00 00 0a  00 00 00 00  28 00 00 00  00 00                                               medium changed          27.2.0       
  22    CMD    4a 01 00 00  00 00 00 00  08 00                                                                         GET EVENT STATUS        43.1.0(2)    
  21.4  OUT    55 53 42 43  98 16 ae 8a  08 00 00 00  80 00 0a 4a  01 00 00 00  00 00 00 08  00 00 00 00  00 00 00     USBC...........J        44.1.0(2)    
  21.4  IN     00 00 00 00  00 00 00 00                                                                                ........                45.1.0(2)    
  21.4  IN     55 53 42 53  98 16 ae 8a  00 00 00 00  00                                                               USBS.........           46.1.0(2)    
  22    IN     00 00 00 00  00 00 00 00                                                                                ........                43.2.0       
  22    CMD    00 00 00 00  00 00                                                                                      TEST UNIT READY         51.1.0(4)    
  21.4  OUT    55 53 42 43  08 50 c7 89  00 00 00 00  00 00 06 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00     USBC.P..........        52.1.0(4)    
  21.4  IN     55 53 42 53  08 50 c7 89  00 00 00 00  01                                                               USBS.P.......           53.1.0(4)    
  21.4  OUT    55 53 42 43  08 50 c7 89  12 00 00 00  80 00 0c 03  00 00 00 12  00 00 00 00  00 00 00 00  00 00 00     USBC.P..........        54.1.0(4)    
  21.4  IN     70 00 06 00  00 00 00 0a  00 00 00 00  28 00 00 00  00 00                                               p...........(...        55.1.0(4)    
  21.4  IN     55 53 42 53  08 50 c7 89  00 00 00 00  00                                                               USBS.P.......           56.1.0(4)    
  22    SENSE  70 00 06 00  00 00 00 0a  00 00 00 00  28 00 00 00  00 00                                               medium changed          51.2.0       
  22    CMD    d0 00 00 00  00 00                                                                                                              75.1.0       
  21.4  OUT    55 53 42 43  08 50 c7 89  00 00 00 00  00 00 06 d0  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00     USBC.P..........        76.1.0       
  21.4  IN     55 53 42 53  08 50 c7 89  00 00 00 00  00                                                               USBS.P.......           77.1.0       
  22    ok                                                                                                                                     75.2.0       
  21.0  CTL    80 06 00 03  00 00 ff 00                                                                                GET DESCRIPTOR          78.1.0(2)    
  21.0  IN     04 03 09 04                                                                                             ....                    78.2.0       
  21.0  CTL    80 06 02 03  09 04 ff 00                                                                                GET DESCRIPTOR          79.1.0(2)    
  21.0  IN     3e 03 48 00  50 00 20 00  4c 00 61 00  73 00 65 00  72 00 4a 00  65 00 74 00  20 00 50 00  72 00 6f 00  >.H.P. .L.a.s.e.        79.2.0       
               66 00 65 00  73 00 73 00  69 00 6f 00  6e 00 61 00  6c 00 20 00  50 00 31 00  31 00 30 00  38 00        f.e.s.s.i.o.n.a.        79.2.32      
  21.0  CTL    80 06 00 01  00 00 12 00                                                                                GET DESCRIPTOR          82.1.0       
  21.0  IN     12 01 00 02  00 00 00 40  f0 03 2a 00  00 01 01 02  03 01                                               .......@..*.....        82.2.0       
  21.0  CTL    80 06 00 02  00 00 09 00                                                                                GET DESCRIPTOR          83.1.0       
  21.0  IN     09 02 3e 00  02 01 00 c0  31                                                                            ..>.....1               83.2.0       
  21.0  CTL    80 06 00 02  00 00 3e 00                                                                                GET DESCRIPTOR          84.1.0       
  21.0  IN     09 02 3e 00  02 01 00 c0  31 09 04 00  00 02 07 01  02 04 07 05  01 02 00 02  00 07 05 81  02 00 02 00  ..>.....1.......        84.2.0       
               09 04 01 00  03 ff 02 10  06 07 05 02  02 00 02 00  07 05 82 02  00 02 00 07  05 83 03 08  00 0c        ................        84.2.32      
  21.0  CTL    00 09 01 00  00 00 00 00                                                                                SET CONFIG              85.1.0       
  21.0  CTL    80 06 04 03  09 04 ff 00                                                                                GET DESCRIPTOR          86.1.0       
  21.0  IN     10 03 50 00  72 00 69 00  6e 00 74 00  65 00 72 00                                                      ..P.r.i.n.t.e.r.        86.2.0       
  21.0  CTL    80 06 06 03  09 04 ff 00                                                                                GET DESCRIPTOR          87.1.0       
  21.0  IN     0e 03 48 00  50 00 20 00  45 00 57 00  53 00                                                            ..H.P. .E.W.S.          87.2.0       
  23.0  CTL    80 06 00 02  00 00 09 01                                                                                GET DESCRIPTOR          88.1.0       
  23.0  IN     09 02 20 00  01 01 00 c0  31 09 04 00  00 02 07 01  02 04 07 05  01 02 00 02  00 07 05 81  02 00 02 00  .. .....1.......        88.2.0       
  23.0  CTL    00 09 01 00  00 00 00 00                                                                                SET CONFIG              89.1.0       
  23.0  CTL    80 06 00 01  00 00 12 00                                                                                GET DESCRIPTOR          90.1.0       
  23.0  IN     12 01 00 02  00 00 00 40  f0 03 2a 00  00 01 01 04  03 01                                               .......@..*.....        90.2.0       
  23.0  CTL    a1 00 00 00  00 00 f1 03                                                                                GET DEVICE ID           91.1.0       
  23.0  IN     00 8c 4d 46  47 3a 48 65  77 6c 65 74  74 2d 50 61  63 6b 61 72  64 3b 4d 44  4c 3a 48 50  20 4c 61 73  ..MFG:Hewlett-Pa        91.2.0       
               65 72 4a 65  74 20 50 72  6f 66 65 73  73 69 6f 6e  61 6c 20 50  31 31 30 38  3b 43 4d 44  3a 5a 4a 53  erJet Profession        91.2.32      
               2c 50 4a 4c  2c 41 43 4c  2c 48 54 54  50 3b 43 4c  53 3a 50 52  49 4e 54 45  52 3b 44 45  53 3a 48 50  ,PJL,ACL,HTTP;CL        91.2.64      
               20 4c 61 73  65 72 4a 65  74 20 50 72  6f 66 65 73  73 69 6f 6e  61 6c 20 50  31 31 30 38  3b 46 57 56   LaserJet Profes        91.2.96      
               45 52 3a 32  30 31 32 30  38 31 34 3b                                                                   ER:20120814;            91.2.128     
  24.0  CTL    80 06 00 01  00 00 12 00                                                                                GET DESCRIPTOR          92.1.0       
  24.0  IN     12 01 00 02  00 00 00 40  f0 03 2a 00  00 01 01 06  03 01                                               .......@..*.....        92.2.0       
  24.0  CTL    80 06 00 02  00 00 09 00                                                                                GET DESCRIPTOR          93.1.0       
  24.0  IN     09 02 27 00  01 01 00 c0  31                                                                            ..'.....1               93.2.0       
  24.0  CTL    80 06 00 02  00 00 27 00                                                                                GET DESCRIPTOR          94.1.0       
  24.0  IN     09 02 27 00  01 01 00 c0  31 09 04 01  00 03 ff 02  10 06 07 05  02 02 00 02  00 07 05 82  02 00 02 00  ..'.....1.......        94.2.0       
               07 05 83 03  08 00 0c                                                                                   .......                 94.2.32      
  24.0  CTL    80 00 00 00  00 00 02 00                                                                                GET STATUS              95.1.0       
  24.0  IN     01 00                                                                                                   ..                      95.2.0       
  24.0  CTL    00 09 01 00  00 00 00 00                                                                                SET CONFIG              96.1.0       
  21.0  CTL    01 0b 00 00  01 00 00 00                                                                                SET INTERFACE           97.1.0       
  21.0  CTL    80 06 00 02  00 00 3e 00                                                                                GET DESCRIPTOR          98.1.0       
  21.0  IN     09 02 20 00  01 01 00 c0  31 09 04 00  00 02 08 06  50 05 07 05  04 02 00 02  00 07 05 84  02 00 02 00  .. .....1.......        98.2.0