Linux设备驱动之usb设备驱动详解

1.Linux usb设备驱动框架

USB是通用串行总线的总称,Linux内核几乎支持所有的usb设备,包括键盘,鼠标,打印机,modem,扫描仪。Linux的usb驱动分为主机驱动与gadget驱动。前者是设备连接到计算机上,通过主机驱动扫描usb设备,控制所连接的设备。而gadget驱动一般用于嵌入式设备,gadget驱动用于控制嵌入式设备。Linux的usb驱动两种类型图如下:

 

 

 

 

 

左侧是usb的主机驱动,右侧是gadget驱动。下面着重介绍一下usb的主机驱动:

(1)usb主机控制器-直接与硬件设备交互。

(2)usb core-向usb设备驱动提供API以及usb主机控制器驱动的程序。使用usb core所提供的函数,宏来完成数据处理的功能。

(3)usb设备驱动,即usb接口驱动,一般所说的usb驱动指的是usb接口驱动

 

 

 

 

2.usb系统的组成部分

usb系统一般由三个部分组成,主机,一个或多个usb hub,以及与之些hub连接的usb设备。

(1)主机

在任何的usb系统中仅有一个主机,主机系统中的usb接口即上图中的主机控制器,主机控制器可由硬件,软件或固件组成。主机主要负责:

a.检测usb设备的连接与拆除

b.管理主机与usb设备之间的控制流

c.管理主机与usb设备之间的数据流

d.收集状态和活动的统计

e.为连接的usb设备提供电源

 

 

(2)usb设备

所有的usb设备都是通过地址来存取的,这个地址在连接或枚举时分配。usb设备对usb系统来说是端点的集合,一组端点实现一个接口。设备端点是usb设备中唯一可寻址的部分。它是主机与设备之间通信流的结束点。一系列的相互独立的端点构成了usb逻辑设备。每个端点支持流进设备或者是流出设备。

主机与设备端点上的usb数据传输是通过管道的方式。

 

(3)hub

所有的usb device都连接在hub端口上。

 

 

 

3. usb传输模式

 

(1)控制传输模式(Control)

控制传输模式支持双向传输,用来处理从usb主机端口到usb设备端口的数据传输,用于控制指令,设备状态查询以及确认命令。

 

(2)等时传输方式(lsochronous )

等时传输是一种周期性的连续性的意向传输模式,通常用于对时间有着密切关系的信息的传输,对准确性要求不高,但对时间要求极为敏感的设备,如视频,音频的传输。

 

(3)中断传输模式(Interrupt)

中断传输模式用于非周期性的,自然发生的,数据量小的传输,数据传输的方向是从设备到主机。如usb键盘和鼠标

 

(4)批量传输模式(bulk)

批量传输模式是一种单向的,用于大量数据传输的模式,该方式用来传输正确无误的数据。通常打印机,扫描仪,数码相机以这种方式与主机连接

 

 

4. usb设备组成

(1)一个usb设备由可以有一个或多个配置

(2)一个配置通常可以有一个或多个接口

(3)一个接口通常可以有一个或多个端点

通常所尽的usb设备驱动是指接口驱动,即一个接口对应一个驱动。

所以Linux usb设备有四大描述符,分别为设备描述符,配置描述符,接口描述符,端点描述符。下面看一个这几个描述符的相关数据结构:

 

 

struct usb_device_descriptor

{
      _u8 bLength;  //此描述符的字节数
      _u8  bDescriptorType; //描述符的种类为设备
      _u16 bcdUSB;  //此设备与描述符兼容的usb设备说明版本号(BCD码)
      _u8   bDeviceClass; //设备类码
      _u8   bDeviceSubClass; //设备子类码
      _u8   bDeviceProtocol; //协议码
      _u8   bMaxPacketSize0; //端点0的最大包大小
      _u16 idVendor; //厂商标志
      _u16  idProduct; //产品标志
      _u16 bcdDevice; //设备发行号
      _u8   iManufacturer; //描述厂商的字串索引

      _u8   iProduct; //描述产品信息的字串索引

      _u8  iSerialNumber; //描述设备序列号信息的字串索引
      _u8  bNumConfigurations;//此设备支持的配置数

  }_attribute_ ((packed));

 

设备类码的典型值如下:

 

#define USB_CLASS_PER_INTERFACE 0

#define USB_CLAS_AUDIO 1     //声音设备

#define USB_CLASS_COMM 2   // 调制解调器,网卡,ISDN连接

#define USB_CLASS_HID  3    //HID设备,如鼠标,键盘

#define USB_CLASS_PHYSICAL 5 //物理设备

#define USB_CLASS_STILL_IMAGE 6 //静止图像捕捉设备

#define USB_CLASS_PRINTER 7//打印机

#define USB_CLASS_MASS_STORAGE //8 批量存储设备

#define USB_CLASS_HUB 9   //USB HUBS

#define USB_CLASS_CSCID 0x0B  //智能卡

#define USB_CLASS_VIDEO 0X0E //视频设备,如网络摄像头

#define USB_CLASS_VENDOR_SPEC 0xFF //厂商自定义的设备

 

  struct usb_config_descriptor{

 

 _u8 bLength ;//此描述符的字节数

_u8 bDescriptorType; //配置描述符类型

_u16 wTotalLength; //此配置信息的总长(包括配置,接口,端点和设备类型及厂商定义的描述符)

_u8 bNumInterfaces; //此配置所支持的接口数

_u8 bConfigurationValue ;//在setConfiguration()请求中用作参数来选定此配置

_u8 iConfiguration; //描述此配置的字串描述符索引

_u8 bmAttributes; //电源配置特性

_u8 bMaxpowe;r //此配置下的总线电源耗电量

}_attribute_ ((packed));

 

 

配置描述符给出了usb设备配置信息,以及此配置下的接口数。每个接口可能的独立操作。

 

 

 

struct usb_interface_descriptor{

 

_u8 bLength ;//此描述符的字节数

_u8 bDescriptorType;//接口描述符类

_u8 bInterfacNumber;//接口号,当前配置所支持的接口数组索引,从0开始

_u8 bNumEndpoints ;//此接口用的端点数量,如果是0,说明此接口只有缺省控制通道

_u8 bAlernateSetting;//可选设备的索引值

_u8 bInterfaceClass;// 类值,0值作为将来保留使用如果是0FFH,此接口由厂商说明

_u8 bInterfaceSubClass;//子类码

_u8 bInterfaceProtocol;//协议码

_u8 iInterface;//描述此接口的字串描述符索引

 

}_attribute_ ((packed));

 

struct usb_endpoint_descriptor{

_u8 bLength ;//此描述符的字节数

_u8 bDescriptorType;//端点描述符类

_u8 bEndpointAddress;此描述符所描述的端点的地址

_u8 bmAtrributes;//所指定的端点的特性,如果是00=控制传送,01=等时传送,10=批传送,11=中断传送

_u8 wMaxPacketSize;//当前配置下端点能够发送与接收的最大数据包大小

_u8 bInterval;//轮询数据传送端点的时间间隙

_u8 bRefresh

_u8 bSynchAddress

}_attribute_ ((packed));

 

以上给出了usb中的设备描述符,配置描述符,接口描述符和端点描述符。

 

 

5. usb设备驱动的几个重要的数据结构

 

usb_driver,usb_device,usb_bus.

 

 

/**
788 * stru ct usb_driver - identifies U SB interface driver to u sbcore
789 * @name: The driver name shou ld be u niqu e among U SB drivers,
790 *      and shou ld normally be the same as the modu le name.
791 * @probe: Called to see if the driver is willing to manage a particu lar
792 *      interface on a device.  If it is, probe retu rns zero and u ses
793 *      u sb_set_intfdata() to associate driver-specific data with the
794 *      interface.  It may also u se u sb_set_interface() to specify the
795 *      appropriate altsetting.  If u nwilling to manage the interface,
796 *      retu rn -ENODEV, if genu ine IO errors occu red, an appropriate
797 *      negative errno valu e.
798 * @disconnect: Called when the interface is no longer accessible, u su ally
799 *      becau se its device has been (or is being) disconnected or the
800 *      driver modu le is being u nloaded.
801 * @u nlocked_ioctl: U sed for drivers that want to talk to u serspace throu gh
802 *      the "u sbfs" filesystem.  This lets devices provide ways to
803 *      expose information to u ser space regardless of where they
804 *      do (or don't) show u p otherwise in the filesystem.
805 * @su spend: Called when the device is going to be su spended by the system.
806 * @resu me: Called when the device is being resu med by the system.
807 * @reset_resu me: Called when the su spended device has been reset instead
808 *      of being resu med.
809 * @pre_reset: Called by u sb_reset_device() when the device
810 *      is abou t to be reset.
811 * @post_reset: Called by u sb_reset_device() after the device
812 *      has been reset
813 * @id_table: U SB drivers u se ID table to su pport hotplu gging.
814 *      Export this with MODU LE_DEVICE_TABLE(u sb,...).  This mu st be set
815 *      or you r driver's probe fu nction will never get called.
816 * @dynids: u sed internally to hold the list of dynamically added device
817 *      ids for this driver.
818 * @drvwrap: Driver-model core stru ctu re wrapper.
819 * @no_dynamic_id: if set to 1, the U SB core will not allow dynamic ids to be
820 *      added to this driver by preventing the sysfs file from being created.
821 * @su pports_au tosu spend: if set to 0, the U SB core will not allow au tosu spend
822 *      for interfaces bou nd to this driver.
823 * @soft_u nbind: if set to 1, the U SB core will not kill U RBs and disable
824 *      endpoints before calling the driver's disconnect method.
825 *
826 * U SB interface drivers mu st provide a name, probe() and disconnect()
827 * methods, and an id_table.  Other driver fields are optional.
828 *
829 * The id_table is u sed in hotplu gging.  It holds a set of descriptors,
830 * and specialized data may be associated with each entry.  That table
831 * is u sed by both u ser and kernel mode hotplu gging su pport.
832 *
833 * The probe() and disconnect() methods are called in a context where
834 * they can sleep, bu t they shou ld avoid abu sing the privilege.  Most
835 * work to connect to a device shou ld be done when the device is opened,
836 * and u ndone at the last close.  The disconnect code needs to address
837 * concu rrency issu es with respect to open() and close() methods, as
838 * well as forcing all pending I/O requ ests to complete (by u nlinking
839 * them as necessary, and blocking u ntil the u nlinks complete).
840 */
841 stru ct usb_driver {
842          const char *name ;
843
844          int (*probe ) (stru ct u sb_interface *intf ,
845                        const stru ct u sb_device_id *id );
846
847          void (*disconnect ) (stru ct u sb_interface *intf );
848
849          int (*u nlocked_ioctl) (stru ct u sb_interface *intf , u nsigned int code ,
850                          void *bu f );
851
852          int (*su spend ) (stru ct u sb_interface *intf , pm_message_t message );
853          int (*resu me ) (stru ct u sb_interface *intf );
854          int (*reset_resu me)(stru ct u sb_interface *intf );
855
856          int (*pre_reset )(stru ct u sb_interface *intf );
857          int (*post_reset)(stru ct u sb_interface *intf );
858
859          const stru ct u sb_device_id *id_table ;
860
861          stru ct u sb_dynids dynids;
862          stru ct u sbdrv_wrap drvwrap;
863          u nsigned int no_dynamic_id:1;
864          u nsigned int su pports_au tosu spend:1;
865          u nsigned int soft_u nbind:1;
866 };

 

usb_driver中的probe函数扫描连接到主机上的usb设备,并且注册usb接口驱动。

 

disconnect函数是当usb设备移除时调用。

 

 

/*
310 * Allocated per bu s (tree of devices) we have:
311 */
312 stru ct u sb_bu s {
313          stru ct device *controller ;      /* host/master side hardware */
314          int bu snu m;                     /* Bu s nu mber (in order of reg) */
315          const char *bu s_name;           /* stable id (PCI slot_name etc) */
316          u 8 u ses_dma;                    /* Does the host controller u se DMA? */
317          u 8 u ses_pio_for_control;        /*
318                                          * Does the host controller u se PIO
319                                          * for control transfers?
320                                          */
321          u 8 otg_port;                    /* 0, or nu mber of OTG/HNP port */
322          u nsigned is_b_host:1;           /* tru e du ring some HNP roleswitches */
323          u nsigned b_hnp_enable:1;        /* OTG: did A-Host enable HNP? */
324          u nsigned sg_tablesize ;          /* 0 or largest nu mber of sg list entries */
325
326          int devnu m_next;                /* Next open device nu mber in
327                                          * rou nd-robin allocation */
328
329          stru ct u sb_devmap  devmap;       /* device address allocation map */
330          stru ct usb_device * root_hu b;    /* Root hu b */
331          stru ct u sb_bu s *hs_companion;   /* Companion EHCI bu s, if any */
332          stru ct list_head bu s_list;      /* list of bu sses */
333
334          int bandwidth_allocated;        /* on this bu s: how mu ch of the time
335                                          * reserved for periodic (intr/iso)
336                                          * requ ests is u sed, on average?
337                                          * U nits: microseconds/frame.
338                                          * Limits: Fu ll/low speed reserve 90%,
339                                          * while high speed reserves 80%.
340                                          */
341          int bandwidth_int_reqs;         /* nu mber of Interru pt requ ests */
342          int bandwidth_isoc_reqs;        /* nu mber of Isoc. requ ests */
343
344 #ifdef CONFIG_USB_DEVICE FS
345          stru ct dentry *u sbfs_dentry;    /* u sbfs dentry entry for the bu s */
346 #endif
347
348 #if defined (CONFIG_U SB_MON) || defined (CONFIG_U SB_MON_MODU LE)
349          stru ct mon_bu s *mon_bu s ;        /* non-nu ll when associated */
350          int monitored;                  /* non-zero when monitored */
351 #endif
352 };
353

 

 

**
370 * stru ct usb_device - kernel's representation of a U SB device
371 * @devnu m: device nu mber; address on a U SB bu s
372 * @devpath: device ID string for u se in messages (e.g., /port/...)
373 * @rou te: tree topology hex string for u se with xHCI
374 * @state: device state: configu red, not attached, etc.
375 * @speed: device speed: high/fu ll/low (or error)
376 * @tt: Transaction Translator info; u sed with low/fu ll speed dev, highspeed hu b
377 * @ttport: device port on that tt hu b
378 * @toggle: one bit for each endpoint, with ([0] = IN, [1] = OU T) endpoints
379 * @parent: ou r hu b, u nless we're the root
380 * @bu s: bu s we're part of
381 * @ep0: endpoint 0 data (defau lt control pipe)
382 * @dev: generic device interface
383 * @descriptor: U SB device descriptor
384 * @config: all of the device's configs
385 * @actconfig: the active configu ration
386 * @ep_in: array of IN endpoints
387 * @ep_ou t: array of OU T endpoints
388 * @rawdescriptors: raw descriptors for each config
389 * @bu s_mA: Cu rrent available from the bu s
390 * @portnu m: parent port nu mber (origin 1)
391 * @level: nu mber of U SB hu b ancestors
392 * @can_su bmit: U RBs may be su bmitted
393 * @persist_enabled:  U SB_PERSIST enabled for this device
394 * @have_langid: whether string_langid is valid
395 * @au thorized: policy has said we can u se it;
396 *      (u ser space) policy determines if we au thorize this device to be
397 *      u sed or not. By defau lt, wired U SB devices are au thorized.
398 *      WU SB devices are not, u ntil we au thorize them from u ser space.
399 *      FIXME -- complete doc
400 * @au thenticated: Crypto au thentication passed
401 * @wu sb: device is Wireless U SB
402 * @string_langid: langu age ID for strings
403 * @produ ct: iProdu ct string, if present (static)
404 * @manu factu rer: iManu factu rer string, if present (static)
405 * @serial: iSerialNu mber string, if present (static)
406 * @filelist: u sbfs files that are open to this device
407 * @u sb_classdev: U SB class device that was created for u sbfs device
408 *      access from u serspace
409 * @u sbfs_dentry: u sbfs dentry entry for the device
410 * @maxchild: nu mber of ports if hu b
411 * @children: child devices - U SB devices that are attached to this hu b
412 * @qu irks: qu irks of the whole device
413 * @u rbnu m: nu mber of U RBs su bmitted for the whole device
414 * @active_du ration: total time device is not su spended
415 * @connect_time: time device was first connected
416 * @do_remote_wakeu p:  remote wakeu p shou ld be enabled
417 * @reset_resu me: needs reset instead of resu me
418 * @wu sb_dev: if this is a Wireless U SB device, link to the WU SB
419 *      specific data for the device.
420 * @slot_id: Slot ID assigned by xHCI
421 *
422 * Notes:
423 * U sbcore drivers shou ld not set u sbdev->state directly.  Instead u se
424 * u sb_set_device_state().
425 */
426 stru ct usb_device {
427          int             devnu m;
428          char            devpath[16];
429          u 32              rou te;
430          enu m usb_device _state    state ;
431          enu m usb_device _speed    speed ;
432
433          stru ct u sb_tt    *tt;
434          int             ttport;
435
436          u nsigned int toggle [2];
437
438          stru ct usb_device *parent ;
439          stru ct u sb_bu s *bu s ;
440          stru ct u sb_host_endpoint ep0;
441
442          stru ct device dev ;
443
444          stru ct usb_device _descriptor descriptor ;
445          stru ct u sb_host_config *config ;
446
447          stru ct u sb_host_config *actconfig;
448          stru ct u sb_host_endpoint *ep_in[16];
449          stru ct u sb_host_endpoint *ep_ou t[16];
450
451          char **rawdescriptors;
452
453          u nsigned short bu s_mA;
454          u 8 portnu m;
455          u 8 level;
456
457          u nsigned can_su bmit:1;
458          u nsigned persist_enabled:1;
459          u nsigned have_langid:1;
460          u nsigned au thorized:1;
461          u nsigned au thenticated:1;
462          u nsigned wu sb:1;
463          int string_langid;
464
465          /* static strings from the device */
466          char *produ ct ;
467          char *manu factu rer ;
468          char *serial ;
469
470          stru ct list_head filelist;
471 #ifdef CONFIG_USB_DEVICE _CLASS
472          stru ct device *u sb_classdev;
473 #endif
474 #ifdef CONFIG_USB_DEVICE FS
475          stru ct dentry *u sbfs_dentry;
476 #endif
477
478          int maxchild;
479          stru ct usb_device *children[U SB_MAXCHILDREN ];
480
481          u 32 qu irks ;
482          atomic_t u rbnu m;
483
484          u nsigned long active_du ration;
485
486 #ifdef CONFIG_PM
487          u nsigned long connect_time;
488
489          u nsigned do_remote_wakeu p:1;
490          u nsigned reset_resu me:1;
491 #endif
492          stru ct wu sb_dev *wu sb_dev ;
493          int slot_id;
494 };
495 #define to_usb_device (d ) container_of (d , stru ct usb_device , dev )
496
497 static inline stru ct usb_device *interface_to_u sbdev (stru ct u sb_interface *intf )
498 {
499          retu rn to_usb_device (intf ->dev .parent );
500 }
501

 

以上三个结构体分别是usb_driver,usb_bus,usb_device设备结构体。

 

 

 

usb_interface结构体:

 

struct usb_interface {
160          /* array of alternate settings for this interface,
161          * stored in no particular order */
162          struct usb_host_interface *altsetting ;
163
164          struct usb_host_interface *cur_altsetting;      /* the currently
165                                          * active alternate setting */
166          unsigned num_altsetting;        /* number of alternate settings */
167
168          /* If there is an interface association descriptor then it will list
169          * the associated interfaces */
170          struct usb_interface_assoc_descriptor *intf_assoc;
171
172          int minor ;                      /* minor number this interface is
173                                          * bound to */
174          enum usb_interface_condition condition;         /* state of binding */
175          unsigned sysfs_files_created:1; /* the sysfs attributes exist */
176          unsigned ep_devs_created:1;     /* endpoint "devices" exist */
177          unsigned unregistering:1;       /* unregistration is in progress */
178          unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
179          unsigned needs_altsetting0:1;   /* switch to altsetting 0 is pending */
180          unsigned needs_binding:1;       /* needs delayed unbind/rebind */
181          unsigned reset_running:1;
182          unsigned resetting_device:1;    /* true: bandwidth alloc after reset */
183
184          struct device dev ;              /* interface specific device info */
185          struct device *usb_dev ;
186          atomic_t pm_usage_cnt;          /* usage counter for autosuspend */
187          struct work_struct reset_ws;    /* for resets in atomic context */
188 };

 struct usb_host_interface *altsetting包含了usb interface的所有可选设置。

 struct usb_host _interface *cur_altsetting是usb interface的当前可选设置。

 

下面看一个struct usb_host_interface

 

 

/* host-side wrapper for one interface setting's parsed descriptors */
77 stru ct usb_host_interface {
78          stru ct u sb_interface_descriptor desc ;
79
80          /* array of desc.bNu mEndpoint endpoints associated with this
81          * interface setting.  these will be in no particu lar order.
82          */
83          stru ct u sb_host_endpoint *endpoint ;
84
85          char *string ;           /* iInterface string, if present */
86          u nsigned char *extra;   /* Extra descriptors */
87          int extralen;
88 };

 

其中struct usb_interface_descriptor即是usb接口描述符。

struct usb_host_endpoint代表的是设备端点。

可以在desc中改变接口包含的端点数。

 

接下来看一下usb_host_endpoint这个结构体:

 

/**
50 * stru ct usb_host_endpoint - host-side endpoint descriptor and qu eu e
51 * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder
52 * @ss_ep_comp: Su perSpeed companion descriptor for this endpoint
53 * @u rb_list: u rbs qu eu ed to this endpoint; maintained by u sbcore
54 * @hcpriv: for u se by HCD; typically holds hardware dma qu eu e head (QH)
55 *      with one or more transfer descriptors (TDs) per u rb
56 * @ep_dev: ep_device for sysfs info
57 * @extra: descriptors following this endpoint in the configu ration
58 * @extralen: how many bytes of "extra" are valid
59 * @enabled: U RBs may be su bmitted to this endpoint
60 *
61 * U SB requ ests are always qu eu ed to a given endpoint, identified by a
62 * descriptor within an active interface in a given U SB configu ration.
63 */
64 stru ct usb_host_endpoint {
65          stru ct u sb_endpoint_descriptor           desc ;
66          stru ct u sb_ss_ep_comp_descriptor        ss_ep_comp;
67          stru ct list_head               u rb_list ;
68          void                            *hcpriv;
69          stru ct ep_device              *ep_dev;        /* For sysfs info */
70
71          u nsigned char *extra;   /* Extra descriptors */
72          int extralen;
73          int enabled ;
74 };

 

 

其中struct usb_endpoint_descriptor是端点描述符。

 

 

urb(usb reqeust block):

urb主要用于Linux host与设备进行数据传输.

 

urb的生命周期:

(1)由usb设备驱动创建

(2)分配到usb设备的指定端点

(3)由Usb设备驱动提交到usb core

(4)由Usb core提交到usb 主机控制器

(5)由Usb主机控制器控制设备进行数据传输

(6)当urb完成的时候,usb主机控制器驱动通知usb 设备驱动

 

 

 

 

/**
1006 * stru ct urb - U SB Requ est Block
1007 * @urb _list: For u se by cu rrent owner of the URB .
1008 * @anchor_list: membership in the list of an anchor
1009 * @anchor: to anchor URB s to a common mooring
1010 * @ep: Points to the endpoint's data stru ctu re.  Will eventu ally
1011 *      replace @pipe.
1012 * @pipe: Holds endpoint nu mber, direction, type, and more.
1013 *      Create these valu es with the eight macros available;
1014 *      u sb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is "ctrl"
1015 *      (control), "bu lk", "int" (interru pt), or "iso" (isochronou s).
1016 *      For example u sb_sndbu lkpipe() or u sb_rcvintpipe().  Endpoint
1017 *      nu mbers range from zero to fifteen.  Note that "in" endpoint two
1018 *      is a different endpoint (and pipe) from "ou t" endpoint two.
1019 *      The cu rrent configu ration controls the existence, type, and
1020 *      maximu m packet size of any given endpoint.
1021 * @stream_id: the endpoint's stream ID for bu lk streams
1022 * @dev: Identifies the U SB device to perform the requ est.
1023 * @statu s: This is read in non-iso completion fu nctions to get the
1024 *      statu s of the particu lar requ est.  ISO requ ests only u se it
1025 *      to tell whether the URB was u nlinked; detailed statu s for
1026 *      each frame is in the fields of the iso_frame-desc.
1027 * @transfer_flags: A variety of flags may be u sed to affect how URB
1028 *      su bmission, u nlinking, or operation are handled.  Different
1029 *      kinds of URB can u se different flags.
1030 * @transfer_bu ffer:  This identifies the bu ffer to (or from) which the I/O
1031 *      requ est will be performed u nless URB _NO_TRANSFER_DMA_MAP is set
1032 *      (however, do not leave garbage in transfer_bu ffer even then).
1033 *      This bu ffer mu st be su itable for DMA; allocate it with
1034 *      kmalloc() or equ ivalent.  For transfers to "in" endpoints, contents
1035 *      of this bu ffer will be modified.  This bu ffer is u sed for the data
1036 *      stage of control transfers.
1037 * @transfer_dma: When transfer_flags inclu des URB _NO_TRANSFER_DMA_MAP,
1038 *      the device driver is saying that it provided this DMA address,
1039 *      which the host controller driver shou ld u se in preference to the
1040 *      transfer_bu ffer.
1041 * @sg: scatter gather bu ffer list
1042 * @nu m_sgs: nu mber of entries in the sg list
1043 * @transfer_bu ffer_length: How big is transfer_bu ffer.  The transfer may
1044 *      be broken u p into chu nks according to the cu rrent maximu m packet
1045 *      size for the endpoint, which is a fu nction of the configu ration
1046 *      and is encoded in the pipe.  When the length is zero, neither
1047 *      transfer_bu ffer nor transfer_dma is u sed.
1048 * @actu al_length: This is read in non-iso completion fu nctions, and
1049 *      it tells how many bytes (ou t of transfer_bu ffer_length) were
1050 *      transferred.  It will normally be the same as requ ested, u nless
1051 *      either an error was reported or a short read was performed.
1052 *      The URB _SHORT_NOT_OK transfer flag may be u sed to make su ch
1053 *      short reads be reported as errors.
1054 * @setu p_packet: Only u sed for control transfers, this points to eight bytes
1055 *      of setu p data.  Control transfers always start by sending this data
1056 *      to the device.  Then transfer_bu ffer is read or written, if needed.
1057 * @setu p_dma: DMA pointer for the setu p packet.  The caller mu st not u se
1058 *      this field; setu p_packet mu st point to a valid bu ffer.
1059 * @start_frame: Retu rns the initial frame for isochronou s transfers.
1060 * @nu mber_of_packets: Lists the nu mber of ISO transfer bu ffers.
1061 * @interval: Specifies the polling interval for interru pt or isochronou s
1062 *      transfers.  The u nits are frames (milliseconds) for fu ll and low
1063 *      speed devices, and microframes (1/8 millisecond) for highspeed
1064 *      and Su perSpeed devices.
1065 * @error_cou nt: Retu rns the nu mber of ISO transfers that reported errors.
1066 * @context: For u se in completion fu nctions.  This normally points to
1067 *      requ est-specific driver context.
1068 * @complete: Completion handler. This URB is passed as the parameter to the
1069 *      completion fu nction.  The completion fu nction may then do what
1070 *      it likes with the URB , inclu ding resu bmitting or freeing it.
1071 * @iso_frame_desc: U sed to provide arrays of ISO transfer bu ffers and to
1072 *      collect the transfer statu s for each bu ffer.
1073 *
1074 * This stru ctu re identifies U SB transfer requ ests.  URB s mu st be allocated by
1075 * calling u sb_alloc_urb () and freed with a call to u sb_free_urb ().
1076 * Initialization may be done u sing variou s u sb_fill_*_urb () fu nctions.  URB s
1077 * are su bmitted u sing u sb_su bmit_urb (), and pending requ ests may be canceled
1078 * u sing u sb_u nlink_urb () or u sb_kill_urb ().
1079 *
1080 * Data Transfer Bu ffers:
1081 *
1082 * Normally drivers provide I/O bu ffers allocated with kmalloc() or otherwise
1083 * taken from the general page pool.  That is provided by transfer_bu ffer
1084 * (control requ ests also u se setu p_packet), and host controller drivers
1085 * perform a dma mapping (and u nmapping) for each bu ffer transferred.  Those
1086 * mapping operations can be expensive on some platforms (perhaps u sing a dma
1087 * bou nce bu ffer or talking to an IOMMU ),
1088 * althou gh they're cheap on commodity x86 and ppc hardware.
1089 *
1090 * Alternatively, drivers may pass the URB _NO_TRANSFER_DMA_MAP transfer flag,
1091 * which tells the host controller driver that no su ch mapping is needed for
1092 * the transfer_bu ffer since
1093 * the device driver is DMA-aware.  For example, a device driver might
1094 * allocate a DMA bu ffer with u sb_alloc_coherent() or call u sb_bu ffer_map().
1095 * When this transfer flag is provided, host controller drivers will
1096 * attempt to u se the dma address fou nd in the transfer_dma
1097 * field rather than determining a dma address themselves.
1098 *
1099 * Note that transfer_bu ffer mu st still be set if the controller
1100 * does not su pport DMA (as indicated by bu s.u ses_dma) and when talking
1101 * to root hu b. If you have to trasfer between highmem zone and the device
1102 * on su ch controller, create a bou nce bu ffer or bail ou t with an error.
1103 * If transfer_bu ffer cannot be set (is in highmem) and the controller is DMA
1104 * capable, assign NU LL to it, so that u sbmon knows not to u se the valu e.
1105 * The setu p_packet mu st always be set, so it cannot be located in highmem.
1106 *
1107 * Initialization:
1108 *
1109 * All URB s su bmitted mu st initialize the dev, pipe, transfer_flags (may be
1110 * zero), and complete fields.  All URB s mu st also initialize
1111 * transfer_bu ffer and transfer_bu ffer_length.  They may provide the
1112 * URB _SHORT_NOT_OK transfer flag, indicating that short reads are
1113 * to be treated as errors; that flag is invalid for write requ ests.
1114 *
1115 * Bu lk URB s may
1116 * u se the URB _ZERO_PACKET transfer flag, indicating that bu lk OU T transfers
1117 * shou ld always terminate with a short packet, even if it means adding an
1118 * extra zero length packet.
1119 *
1120 * Control URB s mu st provide a valid pointer in the setu p_packet field.
1121 * U nlike the transfer_bu ffer, the setu p_packet may not be mapped for DMA
1122 * beforehand.
1123 *
1124 * Interru pt URB s mu st provide an interval, saying how often (in milliseconds
1125 * or, for highspeed devices, 125 microsecond u nits)
1126 * to poll for transfers.  After the URB has been su bmitted, the interval
1127 * field reflects how the transfer was actu ally schedu led.
1128 * The polling interval may be more frequ ent than requ ested.
1129 * For example, some controllers have a maximu m interval of 32 milliseconds,
1130 * while others su pport intervals of u p to 1024 milliseconds.
1131 * Isochronou s URB s also have transfer intervals.  (Note that for isochronou s
1132 * endpoints, as well as high speed interru pt endpoints, the encoding of
1133 * the transfer interval in the endpoint descriptor is logarithmic.
1134 * Device drivers mu st convert that valu e to linear u nits themselves.)
1135 *
1136 * Isochronou s URB s normally u se the URB _ISO_ASAP transfer flag, telling
1137 * the host controller to schedu le the transfer as soon as bandwidth
1138 * u tilization allows, and then set start_frame to reflect the actu al frame
1139 * selected du ring su bmission.  Otherwise drivers mu st specify the start_frame
1140 * and handle the case where the transfer can't begin then.  However, drivers
1141 * won't know how bandwidth is cu rrently allocated, and while they can
1142 * find the cu rrent frame u sing u sb_get_cu rrent_frame_nu mber () they can't
1143 * know the range for that frame nu mber.  (Ranges for frame cou nter valu es
1144 * are HC-specific, and can go from 256 to 65536 frames from "now".)
1145 *
1146 * Isochronou s URB s have a different data transfer model, in part becau se
1147 * the qu ality of service is only "best effort".  Callers provide specially
1148 * allocated URB s, with nu mber_of_packets worth of iso_frame_desc stru ctu res
1149 * at the end.  Each su ch packet is an individu al ISO transfer.  Isochronou s
1150 * URB s are normally qu eu ed, su bmitted by drivers to arrange that
1151 * transfers are at least dou ble bu ffered, and then explicitly resu bmitted
1152 * in completion handlers, so
1153 * that data (su ch as au dio or video) streams at as constant a rate as the
1154 * host controller schedu ler can su pport.
1155 *
1156 * Completion Callbacks:
1157 *
1158 * The completion callback is made in_interru pt(), and one of the first
1159 * things that a completion handler shou ld do is check the statu s field.
1160 * The statu s field is provided for all URB s.  It is u sed to report
1161 * u nlinked URB s, and statu s for all non-ISO transfers.  It shou ld not
1162 * be examined before the URB is retu rned to the completion handler.
1163 *
1164 * The context field is normally u sed to link URB s back to the relevant
1165 * driver or requ est state.
1166 *
1167 * When the completion callback is invoked for non-isochronou s URB s, the
1168 * actu al_length field tells how many bytes were transferred.  This field
1169 * is u pdated even when the URB terminated with an error or was u nlinked.
1170 *
1171 * ISO transfer statu s is reported in the statu s and actu al_length fields
1172 * of the iso_frame_desc array, and the nu mber of errors is reported in
1173 * error_cou nt.  Completion callbacks for ISO transfers will normally
1174 * (re)su bmit URB s to ensu re a constant transfer rate.
1175 *
1176 * Note that even fields marked "pu blic" shou ld not be tou ched by the driver
1177 * when the urb is owned by the hcd, that is, since the call to
1178 * u sb_su bmit_urb () till the entry into the completion rou tine.
1179 */
1180 stru ct urb {
1181          /* private: u sb core and host controller only fields in the urb */
1182          stru ct kref kref ;               /* reference cou nt of the URB */
1183          void *hcpriv;                   /* private data for host controller */
1184          atomic_t u se_cou nt ;             /* concu rrent su bmissions cou nter */
1185          atomic_t reject;                /* su bmissions will fail */
1186          int u nlinked;                   /* u nlink error code */
1187
1188          /* pu blic: docu mented fields in the urb that can be u sed by drivers */
1189          stru ct list_head urb _list ;      /* list head for u se by the urb 's
1190                                          * cu rrent owner */
1191          stru ct list_head anchor_list;   /* the URB may be anchored */
1192          stru ct u sb_anchor *anchor;
1193          stru ct u sb_device *dev ;         /* (in) pointer to associated device */
1194          stru ct u sb_host_endpoint *ep ;   /* (internal) pointer to endpoint */
1195          u nsigned int pipe ;              /* (in) pipe information */
1196          u nsigned int stream_id ;         /* (in) stream ID */
1197          int statu s ;                     /* (retu rn) non-ISO statu s */
1198          u nsigned int transfer_flags;    /* (in) URB _SHORT_NOT_OK | ...*/
1199          void *transfer_bu ffer;          /* (in) associated data bu ffer */
1200          dma_addr_t transfer_dma;        /* (in) dma addr for transfer_bu ffer */
1201          stru ct scatterlist *sg;         /* (in) scatter gather bu ffer list */
1202          int nu m_sgs;                    /* (in) nu mber of entries in the sg list */
1203          u 32 transfer_bu ffer_length;     /* (in) data bu ffer length */
1204          u 32 actu al_length;              /* (retu rn) actu al transfer length */
1205          u nsigned char *setu p_packet ;    /* (in) setu p packet (control only) */
1206          dma_addr_t setu p_dma ;           /* (in) dma addr for setu p_packet */
1207          int start_frame;                /* (modify) start frame (ISO) */
1208          int nu mber_of_packets;          /* (in) nu mber of ISO packets */
1209          int interval ;                   /* (modify) transfer interval
1210                                          * (INT/ISO) */
1211          int error_cou nt ;                /* (retu rn) nu mber of ISO errors */
1212          void *context ;                  /* (in) context for completion */
1213          u sb_complete_t complete ;        /* (in) completion rou tine */
1214          stru ct u sb_iso_packet_descriptor iso_frame_desc[0];
1215                                          /* (in) ISO ONLY */
1216 };
1217
1218 /* ----------------------------------------------------------------------- */

 

 

6. Linux usb 驱动的相关操作函数

 

 int usb_register(struct usb_driver *d);
void usb_deregister(struct usb_driver *d);
Functions used to register and unregister a USB driver from the USB core.

 

 这两个函数主要用来注册usb driver与解注册usb driver.

 

struct usb_device *interface_to_usbdev(struct usb_interface *intf);
Retrieves the controlling struct usb_device * out of a struct usb_interface *.

 

 

返回一个usb接口返回一个usb_device.

 

void usb_set_intfdata(struct usb_interface *intf, void *data);
void *usb_get_intfdata(struct usb_interface *intf);
Functions to set and get access to the private data pointer section within the
struct usb_interface.

 

 

设置private data和是返回private data.

 

int usb_register_dev(struct usb_interface *intf, struct usb_class_driver
*class_driver);
void usb_deregister_dev(struct usb_interface *intf, struct usb_class_driver
*class_driver);
Functions used to register and unregister a specific struct usb_interface * structure
with a struct usb_class_driver * structure.

 

注册usb接口驱动和解注册usb接口驱动,接口驱动也就是设备驱动。

 

 

 

struct urb *usb_alloc_urb(int iso_packets, int mem_flags);
void usb_free_urb(struct urb *urb);
Functions used to create and destroy a struct usb urb *.

 

分配和释放urb.

 

void usb_fill_int_urb(struct urb *urb, struct usb_device *dev, unsigned int
pipe, void *transfer_buffer, int buffer_length, usb_complete_t complete,
void *context, int interval);
void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev, unsigned int
pipe, void *transfer_buffer, int buffer_length, usb_complete_t complete,
void *context);
void usb_fill_control_urb(struct urb *urb, struct usb_device *dev, unsigned
int pipe, unsigned char *setup_packet, void *transfer_buffer, int
buffer_ length, usb_complete_t complete, void *context);
Functions used to initialize a struct urb before it is submitted to the USB core.

 

 

这三个函数是用来初始化urb.

 

参数:

struct urb* urb 要初始化的urb结构体。

struct usb_device *dev urb发送到的设备

unsigned int pipe  usb_sndintpipe和usb_rcvintpipe分别是usb发送端点管道和接收端点管道

void *transfer_buffer 接收或发送数据的缓冲区

int buffer_length 缓冲区的长度

usb_complete_t  urb完成时的回调函数

 

int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data,
int len, int *actual_length, int timeout);
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
__u8 requesttype, __u16 value, __u16 index, void *data, __u16 size,
int timeout);
Functions used to send or receive USB data without having to use a struct urb.

 

这两个函数的usb接收或发送数据没有使用urb结构体。

 

 

7. skelton程序

 

/*
 * USB Skeleton driver - 2.2
 *
 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License as
 *    published by the Free Software Foundation, version 2.
 *
 * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
 * but has been rewritten to be easier to read and use.
 *
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kref.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/mutex.h>


/* Define these values to match your devices */
#define USB_SKEL_VENDOR_ID    0xfff0
#define USB_SKEL_PRODUCT_ID    0xfff0

/* table of devices that work with this driver */
static struct usb_device_id skel_table [] = {
    { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
    { }                    /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, skel_table);


/* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE    192 //次设备号

/* our private defines. if this grows any larger, use your own .h file */
#define MAX_TRANSFER        (PAGE_SIZE - 512)
#define WRITES_IN_FLIGHT    8

/* Structure to hold all of our device specific stuff */
struct usb_skel {
      size_t udev;
    struct usb_device       *dev;            /* the usb device for this device */
    struct usb_interface    *interface;        /* the interface for this device */
    struct semaphore    limit_sem;        /* limiting the number of writes in progress */
    unsigned char           *bulk_in_buffer;    /* the buffer to receive data */
    size_t            bulk_in_size;        /* the size of the receive buffer */
    __u8            bulk_in_endpointAddr;    /* the address of the bulk in endpoint */
    __u8            bulk_out_endpointAddr;    /* the address of the bulk out endpoint */
    struct kref        kref;
    struct mutex        io_mutex;        /* synchronize I/O with disconnect */
};
#define to_skel_dev(d) container_of(d, struct usb_skel, kref)

static struct usb_driver skel_driver;

static void skel_delete(struct kref *kref)
{
    struct usb_skel *dev = to_skel_dev(kref);

    usb_put_dev(dev->udev);
    kfree(dev->bulk_in_buffer);
    kfree(dev);
}

static int skel_open(struct inode *inode, struct file *file)
{
    struct usb_skel *dev;
    struct usb_interface *interface;
    int subminor;
    int retval = 0;

    subminor = iminor(inode);

    interface = usb_find_interface(&skel_driver, subminor);
    if (!interface) {
        err ("%s - error, can't find device for minor %d",
             __FUNCTION__, subminor);
        retval = -ENODEV;
        goto exit;
    }

    dev = usb_get_intfdata(interface);
    if (!dev) {
        retval = -ENODEV;
        goto exit;
    }

    /* prevent the device from being autosuspended */
    retval = usb_autopm_get_interface(interface);
    if (retval)
        goto exit;

    /* increment our usage count for the device */
    kref_get(&dev->kref);

    /* save our object in the file's private structure */
    file->private_data = dev;

exit:
    return retval;
}

static int skel_release(struct inode *inode, struct file *file)
{
    struct usb_skel *dev;

    dev = (struct usb_skel *)file->private_data;
    if (dev == NULL)
        return -ENODEV;

    /* allow the device to be autosuspended */
    mutex_lock(&dev->io_mutex);
    if (dev->interface)
        usb_autopm_put_interface(dev->interface);
    mutex_unlock(&dev->io_mutex);

    /* decrement the count on our device */
    kref_put(&dev->kref, skel_delete);
    return 0;
}

static ssize_t skel_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
{
    struct usb_skel *dev;
    int retval;
    int bytes_read;

    dev = (struct usb_skel *)file->private_data;

    mutex_lock(&dev->io_mutex);
    if (!dev->interface) {        /* disconnect() was called */
        retval = -ENODEV;
        goto exit;
    }

    /* do a blocking bulk read to get data from the device */   //usb_bulk_msg没有使用urb
    retval = usb_bulk_msg(dev->udev,
                  usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
                  dev->bulk_in_buffer,
                  min(dev->bulk_in_size, count),
                  &bytes_read, 10000);

    /* if the read was successful, copy the data to userspace */
    if (!retval) {
        if (copy_to_user(buffer, dev->bulk_in_buffer, bytes_read)) //复制到用户空间
            retval = -EFAULT;
        else
            retval = bytes_read;
    }

exit:
    mutex_unlock(&dev->io_mutex);
    return retval;
}

static void skel_write_bulk_callback(struct urb *urb)
{
    struct usb_skel *dev;

    dev = (struct usb_skel *)urb->context;

    /* sync/async unlink faults aren't errors */
    if (urb->status &&
        !(urb->status == -ENOENT ||
          urb->status == -ECONNRESET ||
          urb->status == -ESHUTDOWN)) {
        err("%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);
    up(&dev->limit_sem);
}

//首先创建一个urb和buffer,初始化urb,然后提交urb.
static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
{


    struct usb_skel *dev;
    int retval = 0;
    struct urb *urb = NULL;
    char *buf = NULL;
    size_t writesize = min(count, (size_t)MAX_TRANSFER);

    dev = (struct usb_skel *)file->private_data;

    /* verify that we actually have some data to write */
    if (count == 0)
        goto exit;

    /* limit the number of URBs in flight to stop a user from using up all RAM */
    if (down_interruptible(&dev->limit_sem)) {
        retval = -ERESTARTSYS;
        goto exit;
    }

    mutex_lock(&dev->io_mutex);
    if (!dev->interface) {        /* disconnect() was called */
        retval = -ENODEV;
        goto error;
    }

    /* create a urb, and a buffer for it, and copy the data to the urb */
    urb = usb_alloc_urb(0, GFP_KERNEL);
    if (!urb) {
        retval = -ENOMEM;
        goto error;
    }

    buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma);
    if (!buf) {
        retval = -ENOMEM;
        goto error;
    }

    if (copy_from_user(buf, user_buffer, writesize)) {
        retval = -EFAULT;
        goto error;
    }

    /* initialize the urb properly */
    usb_fill_bulk_urb(urb, dev->udev,
              usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
              buf, writesize, skel_write_bulk_callback, dev);
    urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

    /* 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;
    }

    /* release our reference to this urb, the USB core will eventually free it entirely */
    usb_free_urb(urb);

    mutex_unlock(&dev->io_mutex);
    return writesize;

error:
    if (urb) {
        usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
        usb_free_urb(urb);
    }
    mutex_unlock(&dev->io_mutex);
    up(&dev->limit_sem);

exit:
    return retval;
}

static const struct file_operations skel_fops = {
    .owner =    THIS_MODULE,
    .read =        skel_read,
    .write =    skel_write,
    .open =        skel_open,
    .release =    skel_release,
};

/*
 * usb class driver info in order to get a minor number from the usb core,
 * and to have the device registered with the driver core
 */
static struct usb_class_driver skel_class = {
    .name =        "skel%d",
    .fops =        &skel_fops,
    .minor_base =    USB_SKEL_MINOR_BASE,
};

static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
    struct usb_skel *dev;
    struct usb_host_interface *iface_desc; //usb_host_interface包含usb interface的所有设置
    struct usb_endpoint_descriptor *endpoint; //这个结构体是usb端点描述符
    size_t buffer_size;
    int i;
    int retval = -ENOMEM;

    /* allocate memory for our device state and initialize it */
    dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    if (!dev) {
        err("Out of memory");
        goto error;
    }
    kref_init(&dev->kref);
    sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
    mutex_init(&dev->io_mutex);

    dev->udev = usb_get_dev(interface_to_usbdev(interface)); //增加使用计数
    dev->interface = interface;

    /* set up the endpoint information */
    /* use only the first bulk-in and bulk-out endpoints */
    iface_desc = interface->cur_altsetting;
    for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
        endpoint = &iface_desc->endpoint[i].desc;

        if (!dev->bulk_in_endpointAddr &&
            usb_endpoint_is_bulk_in(endpoint)) {
            /* we found a bulk in endpoint */
            buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
            dev->bulk_in_size = buffer_size;
            dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
            dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
            if (!dev->bulk_in_buffer) {
                err("Could not allocate bulk_in_buffer");
                goto error;
            }
        }

        if (!dev->bulk_out_endpointAddr &&
            usb_endpoint_is_bulk_out(endpoint)) {
            /* we found a bulk out endpoint */
            dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
        }
    }
    if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
        err("Could not find both bulk-in and bulk-out endpoints");
        goto error;
    }

    /* save our data pointer in this interface device */
    usb_set_intfdata(interface, dev);

    /* we can register the device now, as it is ready */
    retval = usb_register_dev(interface, &skel_class);  //注册usb设备
    if (retval) {
        /* something prevented us from registering this driver */
        err("Not able to get a minor for this device.");
        usb_set_intfdata(interface, NULL);
        goto error;
    }

    /* let the user know what node this device is now attached to */
    info("USB Skeleton device now attached to USBSkel-%d", interface->minor);
    return 0;

error:
    if (dev)
        kref_put(&dev->kref, skel_delete);
    return retval;
}

static void skel_disconnect(struct usb_interface *interface)
{
    struct usb_skel *dev;
    int minor = interface->minor;

    /* prevent skel_open() from racing skel_disconnect() */
    lock_kernel();

    dev = usb_get_intfdata(interface);
    usb_set_intfdata(interface, NULL);

    /* give back our minor */
    usb_deregister_dev(interface, &skel_class);

    /* prevent more I/O from starting */
    mutex_lock(&dev->io_mutex);
    dev->interface = NULL;
    mutex_unlock(&dev->io_mutex);

    unlock_kernel();

    /* decrement our usage count */
    kref_put(&dev->kref, skel_delete);

    info("USB Skeleton #%d now disconnected", minor);
}

static struct usb_driver skel_driver = {
    .name =        "skeleton",
    .probe =    skel_probe,
    .disconnect =    skel_disconnect,
    .id_table =    skel_table,
};

static int __init usb_skel_init(void)
{
    int result;
  
    /* register this driver with the USB subsystem */
    result = usb_register(&skel_driver);
    if (result)
        err("usb_register failed. Error number %d", result);

    return result;
}

static void __exit usb_skel_exit(void)
{ //向usb子系统注册这个驱动
    /* deregister this driver with the USB subsystem */
    usb_deregister(&skel_driver);
}

module_init(usb_skel_init);
module_exit(usb_skel_exit);

MODULE_LICENSE("GPL");

 

 

分析:

skeleton.c 在/driver/usb/ 目录下,它是一个骨架驱动程序。

skeleton首先向usb子系统中注册驱动,然后注册设备。通常所说的usb驱动是指usb接口驱动。即完成一定的功能,数据处理。面 usb driver通过扫描确定usb设备是否在本驱动的设备列表中,即一个usb driver可能对应多个usb设备,它是用来辨别usb设备的。当usb设备移除时,调用disconnect函数。usb driver用于识别usb interface driver.

最后记住,一个接口对应一个设备驱动,主机与设备之间的数据传输是通过端点来实现的。urb是设备与主机之间数据交换的中介。

关于usb 主机驱动就介绍到这里了。

 

 

 

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 设备驱动开发详解 linuxdriver_code_tool |-- 03 | `-- 2.6内核升级工具 | |-- device-mapper-1.00.19-2.i386.rpm | |-- lvm2-2.00.25-1.01.i386.rpm | |-- mkinitrd-4.2.0.3.tar.tar | |-- module-init-tools-3.2.2.tar.bz2 | `-- modutils-2.4.5-1.src.rpm |-- 04 | |-- 内核模块参数范例 | | `-- book.c | |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem设备驱动 | `-- globalmem_two.c |-- 07 | `-- 含并发控制的globalmem驱动 | `-- globalmem_lock.c |-- 08 | |-- globalfifo驱动 | | `-- globalfifo.c | `-- poll应用程序范例 | `-- pollmonitor.c |-- 09 | |-- 异步通知应用程序范例 | | `-- asyncmonitor.c | `-- 支持异步通知的globalfifo | `-- globalfifo_async.c |-- 10 | |-- S3C2410实时钟驱动 | | `-- s3c2410-rtc.c | `-- 秒设备驱动与应用程序 | |-- second.c | `-- second_test.c |-- 11 | |-- DMA范例 | | |-- 3c505.c | | |-- 3c505.h | | `-- dma.h | `-- 静态映射范例 | `-- mach-smdk2440.c |-- 12 | |-- NVRAM驱动 | | `-- generic_nvram.c | |-- 触摸屏驱动 | | |-- 作为input设备 | | | |-- s3c2410_ts.c | | | `-- s3c2410_ts.h | | `-- 作为普通字符设备 | | `-- s3c2410-ts.c | |-- 看门狗驱动 | | `-- s3c2410_wdt.c | `-- 平台设备 | `-- devs.c |-- 13 | |-- IDE驱动 | | |-- ide-disk.c | | `-- ide-h8300.c | `-- RAMDISK驱动 | `-- rd.c |-- 14 | |-- S3C2410串口驱动 | | |-- regs-gpio.h | | |-- regs-serial.h | | `-- s3c2410.c | `-- 串口核心层 | |-- serial_core.c | `-- serial_core.h |-- 15 | |-- S3C2410 I2C主机驱动 | | |-- i2c-s3c2410.c | | |-- iic.h | | |-- regs-gpio.h | | `-- regs-iic.h | `-- SAA711x I2C设备驱动 | `-- saa711x.c |-- 16 | `-- CS8900以太网设备驱动 | |-- cs89x0.c | `-- cs89x0.h |-- 17 | |-- ALSA工具及库 | | |-- alsa-driver-1.0.15.tar.bz2 | | |-- alsa-firmware-1.0.15.tar.bz2 | | |-- alsa-lib-1.0.15.tar.bz2 | | |-- alsa-oss-1.0.15.tar.bz2 | | |-- alsa-tools-1.0.15.tar.bz2 | | |-- alsa-utils-1.0.13.tar.bz2 | | `-- pyalsa-1.0.15.tar.bz2 | |-- ALSA驱动范例 | | |-- sa11xx-uda1341.c | | `-- uda1341.h | |-- ALSA应用程序范例 | | |-- pcm.c | | `-- pcm_min.c | |-- OSS驱动范例 | | `-- s3c2410-uda1341.c | `-- OSS应用程序范例 | |-- mixer.c | `-- sound.c |-- 18 | |-- FRAMEBUFFER应用程序范例 | | `-- fb_display | | |-- fb_display.c | | |-- fb_display.h | | |-- Makefile | | |-- README | | `-- test.c | `-- S3C2410 LCD驱动 | |-- s3c2410fb.c | `-- s3c2410fb.h |-- 19 | |-- busybox源代码 | | `-- busybox-1.2.1.tar.bz2 | |-- MTD工具 | | `-- mtd-utils-1.0.0.tar.gz | |-- nand驱动范例 | | `-- s3c2410.c | |-- nor驱动范例 | | `-- s3c2410nor.c | `-- yaffs&yaffs2源代码 | |-- yaffs.tar.gz | `-- yaffs2.tar.gz |-- 20 | |-- USB串口驱动 | | |-- usb-serial.c | | `-- usb-serial.h | |-- USB工具 | | `-- usbview-1.0.tar.tar | |-- USB骨架程序 | | `-- usb-skeleton.c | |-- USB键盘驱动 | | |-- input.h | | |-- usb_input.h | | `-- usbkbd.c | `-- usb主机控制器驱动范例 | |-- ohci-s3c2410.c | `-- usb-control.h |-- 21 | |-- PCI骨架程序 | | `-- pci-skeleton.c | `-- PCI驱动范例 | `-- i810_audio.c `-- 22 |-- 范例代码 | |-- oops范例 | | |-- oops_example.asm | | `-- oops_example.c | `-- proc范例 | `-- sim_proc.c `-- 内核调试工具 |-- ddd-3.3.11.tar.gz |-- gdbmod-2.4.bz2 |-- kdb-v4.4-2.6.15-rc5-common-1.bz2 |-- kdb-v4.4-2.6.15-rc5-common-2.bz2 |-- kdb-v4.4-2.6.15-rc5-i386-1.bz2 `-- linux-2.6.15.5-kgdb-2.4.tar.tar 73 directories, 91 files
Linux设备驱动详解【第二版】,作者宋宝华,此版PDF是经过本人整理的文字版PDF,带目录、高清无水印版。 内容简介 《Linux设备驱动开发详解(第《Linux设备驱动开发详解(第2版)》内容全面,实例丰富,操作性强,语言通俗易懂,适合广大Linux开发人员、嵌入式工程师参考使用。 图书目录 第1篇 Linux设备驱动入门 第1章 Linux设备驱动概述及开发环境构建 2 第2章 驱动设计的硬件基础 21 第3章 Linux内核及内核编程 53 第2篇 Linux设备驱动核心理论 第4章 Linux内核模块 82 第5章 Linux文件系统与设备文件系统 92 第6章 字符设备驱动 118 第7章 Linux设备驱动中的并发控制 139 第8章 Linux设备驱动中的阻塞与非阻塞I/O 161 第9章 Linux设备驱动中的异步通知与异步I/O 176 第10章 中断与时钟 193 第11章 内存与I/O访问 213 第12章 工程中的Linux设备驱动 242 第3篇 Linux设备驱动实例 第13章 Linux设备驱动 272 第14章 Linux终端设备驱动 304 第15章 Linux的I2C核心、总线与设备驱动 333 第16章 Linux网络设备驱动 363 第17章 Linux音频设备驱动 388 第18章 LCD设备驱动 440 第19章 Flash设备驱动 479 第20章 USB主机与设备驱动 507 第21章 PCI设备驱动 547 第4篇 Linux设备驱动调试、移植 第22章 Linux设备驱动的调试 564 第23章 Linux设备驱动的移植 602

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值