Bootstrap

Linux设备驱动之usb设备驱动详解_usb数据什么驱动设备类型(1)

最全的Linux教程,Linux从入门到精通

======================

  1. linux从入门到精通(第2版)

  2. Linux系统移植

  3. Linux驱动开发入门与实战

  4. LINUX 系统移植 第2版

  5. Linux开源网络全栈详解 从DPDK到OpenFlow

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。

需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

_u8 bDescriptorType;//端点描述符类

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

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

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

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

_u8 bRefresh

_u8 bSynchAddress

}_attribute_ ((packed));

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

  1. 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 /* ----------------------------------------------------------------------- */

  1. 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结构体。

  1. skelton程序

/*
 * USB Skeleton driver - 2.2
 *
 * Copyright © 2001-2004 Greg Kroah-Hartman ([email protected])
 *
 *    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,
};

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以点击这里获取!

&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,
};

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-mk6rEiww-1715828685239)]
[外链图片转存中…(img-p6JTGMnK-1715828685240)]
[外链图片转存中…(img-fX6pfqey-1715828685240)]
[外链图片转存中…(img-GiM088M9-1715828685240)]
[外链图片转存中…(img-f1nM9fzT-1715828685241)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以点击这里获取!

;