当前位置:   article > 正文

Linux usb设备驱动_linux usb设备驱动程序

linux usb设备驱动程序

原文地址:http://blog.csdn.net/chenjin_zhong/article/details/6329316

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 ctusb_driver - identifiesU SB interface driver tou sbcore 
789* @name: The driver name shou ld beu niqu e amongU 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 andu ses
793*     u sb_set_intfdata() to associate driver-specific data with the
794*      interface.  It may alsou se u sb_set_interface() to specify the
795*      appropriate altsetting.  Ifu 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 beingu nloaded.
801* @u nlocked_ioctl:U sed for drivers that want to talk tou serspace throu gh
802*      the "u sbfs" filesystem.  This lets devices provide ways to
803*      expose information tou ser space regardless of where they
804*      do (or don't) showu 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 byu sb_reset_device() when the device
810*      is abou t to be reset.
811* @post_reset: Called byu 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, theU 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, theU SB core will not allow au tosu spend
822*      for interfaces bou nd to this driver.
823* @soft_u nbind: if set to 1, theU SB core will not killU 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 isu sed in hotplu gging.  It holds a set of descriptors,
830* and specialized data may be associated with each entry.  That table
831* isu 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* andu 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 (byu nlinking
839* them as necessary, and blockingu ntil the u nlinks complete).
840*/
841stru ctusb_driver{
842         const char *name;
843
844         int (*probe) (stru ct u sb_interface*intf,
845                       const stru ctu sb_device_id*id);
846
847         void (*disconnect) (stru ct u sb_interface*intf);
848
849         int (*u nlocked_ioctl) (stru ctu sb_interface*intf,u nsigned int code,
850                         void *bu f);
851
852         int (*su spend) (stru ct u sb_interface *intf,pm_message_tmessage);
853         int (*resu me) (stru ct u sb_interface *intf);
854         int (*reset_resu me)(stru ctu sb_interface*intf);
855
856         int (*pre_reset)(stru ct u sb_interface*intf);
857         int (*post_reset)(stru ctu sb_interface*intf);
858
859         const stru ctu sb_device_id*id_table;
860
861         stru ctu sb_dynidsdynids;
862         stru ctu sbdrv_wrapdrvwrap;
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*/
312stru ctu sb_bu s {
313         stru ctdevice *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 controlleru se DMA? */ 
317        u 8 u ses_pio_for_control;       /*
318                                         * Does the host controlleru 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 ctu sb_devmap  devmap;      /* device address allocation map */
330         stru ctusb_device * root_hu b;   /* Root hu b */
331         stru ctu sb_bu s *hs_companion;  /* Companion EHCI bu s, if any */
332         stru ctlist_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 isu 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 ctdentry *u sbfs_dentry;   /*u sbfs dentry entry for the bu s */
346#endif
347
348#ifdefined (CONFIG_U SB_MON) ||defined(CONFIG_U SB_MON_MODU LE)
349         stru ctmon_bu s *mon_bu s ;       /* non-nu ll when associated */
350         int monitored;                 /* non-zero when monitored */
351#endif
352};
353

 

 

** 
370* stru ctusb_device - kernel's representation of aU SB device
371* @devnu m: device nu mber; address on aU SB bu s
372* @devpath: device ID string foru se in messages (e.g., /port/...)
373* @rou te: tree topology hex string foru 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 ofU 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 canu se it;
396*      (u ser space) policy determines if we au thorize this device to be
397*     u sed or not. By defau lt, wiredU SB devices are au thorized.
398*      WU SB devices are not,u ntil we au thorize them fromu ser space.
399*      FIXME -- complete doc
400* @au thenticated: Crypto au thentication passed
401* @wu sb: device is WirelessU 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 foru sbfs device
408*      access fromu 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 ofU 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 WirelessU 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.  Insteadu se 
424*u sb_set_device_state(). 
425*/
426stru ctusb_device{
427         int             devnu m;
428         char            devpath[16];
429        u 32             rou te;
430         enu musb_device _state  state;
431         enu musb_device _speed  speed;
432
433         stru ctu sb_tt   *tt;
434         int             ttport;
435
436        u nsigned int toggle [2];
437
438         stru ctusb_device*parent;
439         stru ctu sb_bu s*bu s;
440         stru ctu sb_host_endpointep0;
441
442         stru ctdevicedev;
443
444         stru ctusb_device _descriptordescriptor;
445         stru ctu sb_host_config*config;
446
447         stru ctu sb_host_config*actconfig;
448         stru ctu sb_host_endpoint*ep_in[16];
449         stru ctu sb_host_endpoint*ep_ou t[16];
450
451         char **rawdescriptors;
452
453        u nsigned short bu s_mA;
454        u 8portnu m;
455        u 8level;
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 ctlist_headfilelist;
471#ifdef CONFIG_USB_DEVICE _CLASS
472         stru ctdevice*u sb_classdev;
473#endif
474#ifdef CONFIG_USB_DEVICE FS
475         stru ctdentry*u sbfs_dentry;
476#endif
477
478         int maxchild;
479         stru ctusb_device*children[U SB_MAXCHILDREN];
480
481        u 32qu irks;
482        atomic_tu rbnu m;
483
484        u nsigned long active_du ration;
485
486#ifdefCONFIG_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 ctwu sb_dev*wu sb_dev;
493         int slot_id;
494};
495#defineto_usb_device(d)container_of(d, stru ctusb_devicedev)
496
497static inline stru ctusb_device*interface_to_u sbdev(stru ctu sb_interface*intf)
498{
499         retu rnto_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         structusb_host_interface*altsetting;
163
164         structusb_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         structusb_interface_assoc_descriptor *intf_assoc;
171
172         intminor;                     /* minor number this interface is 
173                                         * bound to */
174         enumusb_interface_conditioncondition;        /* 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         structdevicedev;             /* interface specific device info */ 
185         structdevice*usb_dev;
186        atomic_tpm_usage_cnt;         /* usage counter for autosuspend */ 
187         structwork_structreset_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 */
77stru ctusb_host_interface {
78         stru ctu sb_interface_descriptordesc ;
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 ctu 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 ctusb_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 byu sbcore
54* @hcpriv: foru se by HCD; typically holds hardware dma qu eu e head (QH)
55*      with one or more transfer descriptors (TDs) peru 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 givenU SB configu ration.
63*/
64stru ctusb_host_endpoint {
65         stru ctu sb_endpoint_descriptor          desc ;
66         stru ctu sb_ss_ep_comp_descriptor        ss_ep_comp;
67         stru ctlist_head              u rb_list ;
68         void                            *hcpriv;
69         stru ctep_device              *ep_dev;       /* For sysfs info */
70
71        u nsigned char *extra;   /* Extra descriptors */
72         int extralen;
73         intenabled ;
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 cturb -U SB Requ est Block
1007* @urb _list: Foru se by cu rrent owner of the URB . 
1008* @anchor_list: membership in the list of an anchor
1009* @anchor: to anchorURB 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 exampleu sb_sndbu lkpipe() oru 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 theU 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 onlyu se it 
1025*      to tell whether theURB 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 beu sed to affect howURB
1028*      su bmission,u nlinking, or operation are handled.  Different
1029*      kinds ofURB canu se different flags.
1030* @transfer_bu ffer:  This identifies the bu ffer to (or from) which the I/O
1031*      requ est will be performedu nlessURB _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 isu sed for the data 
1036*      stage of control transfers.
1037* @transfer_dma: When transfer_flags inclu desURB _NO_TRANSFER_DMA_MAP, 
1038*      the device driver is saying that it provided this DMA address,
1039*      which the host controller driver shou ldu 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 brokenu 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 isu 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*      TheURB _SHORT_NOT_OK transfer flag may beu sed to make su ch
1053*      short reads be reported as errors.
1054* @setu p_packet: Onlyu 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 notu 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.  Theu 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: Foru se in completion fu nctions.  This normally points to
1067*      requ est-specific driver context.
1068* @complete: Completion handler. ThisURB is passed as the parameter to the
1069*      completion fu nction.  The completion fu nction may then do what
1070*      it likes with theURB , 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 identifiesU SB transfer requ ests. URB s mu st be allocated by
1075* callingu sb_alloc_urb () and freed with a call tou sb_free_urb ().
1076* Initialization may be doneu sing variou su sb_fill_*_urb () fu nctions. URB s
1077* are su bmittedu sing u sb_su bmit_urb (), and pending requ ests may be canceled
1078*u sing u sb_u nlink_urb () oru 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 alsou se setu p_packet), and host controller drivers
1085* perform a dma mapping (andu nmapping) for each bu ffer transferred.  Those
1086* mapping operations can be expensive on some platforms (perhapsu 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 theURB _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 withu sb_alloc_coherent() or callu sb_bu ffer_map().
1095* When this transfer flag is provided, host controller drivers will
1096* attempt tou 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 thatu sbmon knows not tou 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* AllURB s su bmitted mu st initialize the dev, pipe, transfer_flags (may be
1110* zero), and complete fields.  AllURB 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 lkURB 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* ControlURB 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 ptURB s mu st provide an interval, saying how often (in milliseconds
1125* or, for highspeed devices, 125 microsecondu nits)
1126* to poll for transfers.  After theURB 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 ofu p to 1024 milliseconds.
1131* Isochronou sURB 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 linearu nits themselves.)
1135*
1136* Isochronou sURB s normally u se theURB _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 frameu 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 sURB 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* allocatedURB 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 allURB 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 theURB is retu rned to the completion handler.
1163*
1164* The context field is normallyu 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 sURB s, the 
1168* actu al_length field tells how many bytes were transferred.  This field
1169* isu pdated even when the URB terminated with an error or wasu 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 bmitURB 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 theurb 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*/
1180stru cturb{
1181        /* private: u sb core and host controller only fields in theurb */
1182         stru ctkrefkref;              /* reference cou nt of the URB */ 
1183         void *hcpriv;                  /* private data for host controller */
1184        atomic_tu se_cou nt;            /* concu rrent su bmissions cou nter */
1185        atomic_treject;               /* su bmissions will fail */
1186         intu nlinked;                   /* u nlink error code */
1187
1188        /* pu blic: docu mented fields in theurb that can beu sed by drivers */
1189         stru ctlist_headurb _list;     /* list head for u se by the urb 's 
1190                                         * cu rrent owner */
1191         stru ctlist_headanchor_list;   /* theURB may be anchored */
1192         stru ctu sb_anchor*anchor;
1193         stru ctu sb_device*dev;        /* (in) pointer to associated device */ 
1194         stru ctu 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         intstatu 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_ttransfer_dma;       /* (in) dma addr for transfer_bu ffer */
1201         stru ctscatterlist*sg;         /* (in) scatter gather bu ffer list */
1202         int nu m_sgs;                   /* (in) nu mber of entries in the sg list */
1203        u 32transfer_bu ffer_length;    /* (in) data bu ffer length */
1204        u 32actu al_length;             /* (retu rn) actu al transfer length */
1205        u nsigned char *setu p_packet;   /* (in) setu p packet (control only) */ 
1206        dma_addr_tsetu 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         intinterval;                   /* (modify) transfer interval
1210                                         * (INT/ISO) */
1211         interror_cou nt;               /* (retu rn) nu mber of ISO errors */
1212         void *context;                 /* (in) context for completion */ 
1213        u sb_complete_tcomplete;       /* (in) completion rou tine */ 
1214         stru ctu 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 主机驱动就介绍到这里了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/263569
推荐阅读
相关标签
  

闽ICP备14008679号