当前位置: 首页 > news >正文

广州建设网站哪个好二手网站专业做附近人的有吗

广州建设网站哪个好,二手网站专业做附近人的有吗,不花钱的网站建设,微信小程序开发教程从零开始1.概述 如下图所示#xff0c;Linux内核中USB主机体系结构由五部分组成#xff0c;分别为Application Software、USB Class Driver、USB Core(USB Driver)、USB Host Controller Driver、USB Host Controller。应用程序处于用户空间#xff0c;通过系统调用访问Class Drive…1.概述 如下图所示Linux内核中USB主机体系结构由五部分组成分别为Application Software、USB Class Driver、USB Core(USB Driver)、USB Host Controller Driver、USB Host Controller。应用程序处于用户空间通过系统调用访问Class Driver从而间接的访问USB设备如主机端的应用程序aplay、arecord可以访问USB音频设备。Class Driver是某一类设备驱动不同类设备会匹配不同的Class Driver如USB音频设备会匹配Audio驱动USB存储设备会匹配Mass Storage驱动鼠标和键盘会匹配HID驱动。USB Core(USB Driver)是内核设计的一个抽象层目的是将Class Driver和USB Host Controller Driver分隔开使两者都依赖一个稳定的中间层USB Core(USB Driver)向上提供通信接口向下统一管理USB设备同时完成USB设备和USB Class Driver的匹配工作。USB Host Controller目前有4种不同的硬件级接口标准分别为OHCI、UHCI、EHCI、xHCIOHCI和UHCI实现了USB1.1EHCI实现了USB2.0xHCI实现了USB3.2不同的接口标准都有对应的USB Host Controller Driver如xHCI对应于xhci-hcd驱动向下兼容OHCI和EHCI。最底层是USB Host Controller硬件。下面将分别介绍Linux内核中USB主机体系结构USB Class Driver、USB Core(USB Driver)、USB Host Controller Driver四个部分。 2.USB Class Driver Linux内核使用struct usb_driver数据结构描述USB Class Driver使用usb_register和usb_deregister注册、注销struct usb_driver。USB Class Driver可以使用module_usb_driver宏定义注册驱动。需要注意的是USB Class Driver是针对USB接口的如果一个设备是复合设备每个接口都有不同的功能则每个接口都有对应的USB Class Driver。主机枚举设备的时候会识别每个接口的功能同时匹配对应的struct usb_driver匹配成功后struct usb_driver的probe函数被调用。 [include/linux/usb.h] struct usb_driver {const char *name; /* USB Class Driver名称必须唯一且和模块名称一样 *//* 当USB设备的接口和驱动匹配成功后该函数被调用 */int (*probe) (struct usb_interface *intf,const struct usb_device_id *id);/* 断开USB设备或者卸载驱动模块时调用 */void (*disconnect) (struct usb_interface *intf);/* usbf接口用户空间可以通过该函数和驱动通信 */int (*unlocked_ioctl) (struct usb_interface *intf,unsigned int code, void *buf);/* 功耗管理相关函数 */int (*suspend) (struct usb_interface *intf, pm_message_t message);int (*resume) (struct usb_interface *intf);int (*reset_resume)(struct usb_interface *intf);/* Called by usb_reset_device() when the device is about to be* reset. This routine must not return until the driver has no active* URBs for the device, and no more URBs may be submitted until the* post_reset method is called. */int (*pre_reset)(struct usb_interface *intf);/* Called by usb_reset_device() after the device has been reset */int (*post_reset)(struct usb_interface *intf);/* 用于匹配USB Class Driver */const struct usb_device_id *id_table;const struct attribute_group **dev_groups;struct usb_dynids dynids;struct usbdrv_wrap drvwrap;unsigned int no_dynamic_id:1;/* if set to 0, the USB core will not allow autosuspend for* interfaces bound to this driver */unsigned int supports_autosuspend:1;/* if set to 1, the USB core will not allow hubs* to initiate lower power link state transitions when an idle timeout* occurs. Device-initiated USB 3.0 link PM will still be allowed.*/unsigned int disable_hub_initiated_lpm:1;/* if set to 1, the USB core will not kill URBs and disable* endpoints before calling the drivers disconnect method.*/unsigned int soft_unbind:1;...... }; /** use these in module_init()/module_exit()* and dont forget MODULE_DEVICE_TABLE(usb, ...)*/ extern int usb_register_driver(struct usb_driver *, struct module *,const char *);/* use a define to avoid include chaining to get THIS_MODULE friends */ #define usb_register(driver) \usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)extern void usb_deregister(struct usb_driver *); /*** module_usb_driver() - Helper macro for registering a USB driver* __usb_driver: usb_driver struct** Helper macro for USB drivers which do not do anything special in module* init/exit. This eliminates a lot of boilerplate. Each module may only* use this macro once, and calling it replaces module_init() and module_exit()*/ #define module_usb_driver(__usb_driver) \module_driver(__usb_driver, usb_register, usb_deregister)下面是USB Mass Storage的USB Class Driver定义使用module_usb_stor_driver宏进行注册。U盘、USB硬盘都使用下面的驱动。 [drivers/usb/storage/usb.c] #define DRV_NAME usb-storage static struct usb_driver usb_storage_driver {.name DRV_NAME,.probe storage_probe,.disconnect usb_stor_disconnect,.suspend usb_stor_suspend,.resume usb_stor_resume,.reset_resume usb_stor_reset_resume,.pre_reset usb_stor_pre_reset,.post_reset usb_stor_post_reset,.id_table usb_storage_usb_ids,.supports_autosuspend 1,.soft_unbind 1, }; module_usb_stor_driver(usb_storage_driver, usb_stor_host_template, DRV_NAME);[drivers/usb/storage/usb.h] #define module_usb_stor_driver(__driver, __sht, __name) \ static int __init __driver##_init(void) \ { \usb_stor_host_template_init((__sht), __name, THIS_MODULE); \return usb_register((__driver)); \ } \ module_init(__driver##_init); \ static void __exit __driver##_exit(void) \ { \usb_deregister((__driver)); \ } \ module_exit(__driver##_exit)3.USB Core(USB Driver) USB Core(USB Driver)有三个功能第一是向USB Class Driver提供通信接口第二是匹配驱动第三是管理USB Device。 3.1.通信接口 USB Core(USB Driver)层封装了USB Request Block数据结构即struct urb。USB Class Driver只需要分配并填充struct urb然后调用通信接口将struct urb提交到USB Core(USB Driver)层即可完成和USB设备的通信。 [include/linux/usb.h] struct urb {/* private: usb core and host controller only fields in the urb */struct kref kref; /* reference count of the URB */int unlinked; /* unlink error code */void *hcpriv; /* private data for host controller */atomic_t use_count; /* concurrent submissions counter */atomic_t reject; /* submissions will fail *//* public: documented fields in the urb that can be used by drivers */struct list_head urb_list; /* list head for use by the urbs current owner */struct list_head anchor_list; /* the URB may be anchored */struct usb_anchor *anchor;struct usb_device *dev; /* (in) pointer to associated device */struct usb_host_endpoint *ep; /* (internal) pointer to endpoint */unsigned int pipe; /* (in) pipe information */unsigned int stream_id; /* (in) stream ID */int status; /* (return) non-ISO status */unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/void *transfer_buffer; /* (in) associated data buffer */dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */struct scatterlist *sg; /* (in) scatter gather buffer list */int num_mapped_sgs; /* (internal) mapped sg entries */int num_sgs; /* (in) number of entries in the sg list */u32 transfer_buffer_length; /* (in) data buffer length */u32 actual_length; /* (return) actual transfer length */unsigned char *setup_packet; /* (in) setup packet (control only) */dma_addr_t setup_dma; /* (in) dma addr for setup_packet */int start_frame; /* (modify) start frame (ISO) */int number_of_packets; /* (in) number of ISO packets */int interval; /* (modify) transfer interval (INT/ISO) */int error_count; /* (return) number of ISO errors */void *context; /* (in) context for completion */usb_complete_t complete; /* (in) completion routine */...... };主要的通信接口定义如下包含分配、释放、填充、提交和取消URB。提交URB的接口包含了同步接口和异步接口异步接口经过封装得到同步接口。内核没有封装ISOC传输类型的同步接口因此ISOC传输只能使用异步接口。 /* initializes a control urb */ static inline 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_fn, void *context) {...... } /* macro to help initialize a bulk urb */ static inline 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_fn, void *context) {...... } /* macro to help initialize a interrupt urb */ static inline 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_fn, void *context, int interval) {...... } extern void usb_init_urb(struct urb *urb); extern struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags); extern void usb_free_urb(struct urb *urb);/* issue an asynchronous transfer request for an endpoint */ extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags); /* abort/cancel a transfer request for an endpoint */ extern int usb_unlink_urb(struct urb *urb);/* Builds a control urb, sends it off and waits for completion */ extern 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); /* Builds an interrupt urb, sends it off and waits for completion */ extern int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,void *data, int len, int *actual_length, int timeout); /* Builds a bulk urb, sends it off and waits for completion */ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,void *data, int len, int *actual_length, int timeout);通信的目的由pipe表示pipe的位定义如下所示其包含了USB设备地址、传输类型、传输方向、端点编号信息。内核提供了一系列定义pipe和解析pipe的宏定义驱动可以直接使用。 /** For various legacy reasons, Linux has a small cookie thats paired with* a struct usb_device to identify an endpoint queue. Queue characteristics* are defined by the endpoints descriptor. This cookie is called a pipe,* an unsigned int encoded as:** - direction: bit 7 (0 Host-to-Device [Out],* 1 Device-to-Host [In] ...* like endpoint bEndpointAddress)* - device address: bits 8-14 ... bit positions known to uhci-hcd* - endpoint: bits 15-18 ... bit positions known to uhci-hcd* - pipe type: bits 30-31 (00 isochronous, 01 interrupt,* 10 control, 11 bulk)** Given the device address and endpoint descriptor, pipes are redundant.*//* NOTE: these are not the standard USB_ENDPOINT_XFER_* values!! */ /* (yet ... theyre the values used by usbfs) */ #define PIPE_ISOCHRONOUS 0 #define PIPE_INTERRUPT 1 #define PIPE_CONTROL 2 #define PIPE_BULK 3#define usb_pipein(pipe) ((pipe) USB_DIR_IN) #define usb_pipeout(pipe) (!usb_pipein(pipe))#define usb_pipedevice(pipe) (((pipe) 8) 0x7f) #define usb_pipeendpoint(pipe) (((pipe) 15) 0xf)#define usb_pipetype(pipe) (((pipe) 30) 3) #define usb_pipeisoc(pipe) (usb_pipetype((pipe)) PIPE_ISOCHRONOUS) #define usb_pipeint(pipe) (usb_pipetype((pipe)) PIPE_INTERRUPT) #define usb_pipecontrol(pipe) (usb_pipetype((pipe)) PIPE_CONTROL) #define usb_pipebulk(pipe) (usb_pipetype((pipe)) PIPE_BULK)static inline unsigned int __create_pipe(struct usb_device *dev,unsigned int endpoint) {return (dev-devnum 8) | (endpoint 15); }/* Create various pipes... */ #define usb_sndctrlpipe(dev, endpoint) \((PIPE_CONTROL 30) | __create_pipe(dev, endpoint)) #define usb_rcvctrlpipe(dev, endpoint) \((PIPE_CONTROL 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) #define usb_sndisocpipe(dev, endpoint) \((PIPE_ISOCHRONOUS 30) | __create_pipe(dev, endpoint)) #define usb_rcvisocpipe(dev, endpoint) \((PIPE_ISOCHRONOUS 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) #define usb_sndbulkpipe(dev, endpoint) \((PIPE_BULK 30) | __create_pipe(dev, endpoint)) #define usb_rcvbulkpipe(dev, endpoint) \((PIPE_BULK 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) #define usb_sndintpipe(dev, endpoint) \((PIPE_INTERRUPT 30) | __create_pipe(dev, endpoint)) #define usb_rcvintpipe(dev, endpoint) \((PIPE_INTERRUPT 30) | __create_pipe(dev, endpoint) | USB_DIR_IN)创建pipe需要两个参数一个是struct usb_device和endpointendpoint为端点描述符中的bEndpointAddress。当USB Class Driver的probe函数被调用时内核会传入一个和该驱动匹配成功的接口的数据结构即struct usb_interface。驱动可以通过interface_to_usbdev函数从struct usb_interface获取struct usb_deviceendpoint通过usb_find_xx系列函数中获取(ISOC传输需要驱动自己从struct usb_host_interface数据结构中解析)。 [include/linux/usb.h] struct usb_interface {/* array of alternate settings for this interface,* stored in no particular order */struct usb_host_interface *altsetting;struct usb_host_interface *cur_altsetting; /* the currently* active alternate setting */unsigned num_altsetting; /* number of alternate settings *//* If there is an interface association descriptor then it will list* the associated interfaces */struct usb_interface_assoc_descriptor *intf_assoc;int minor; /* minor number this interface is bound to */enum usb_interface_condition condition; /* state of binding */unsigned sysfs_files_created:1; /* the sysfs attributes exist */unsigned ep_devs_created:1; /* endpoint devices exist */unsigned unregistering:1; /* unregistration is in progress */unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */unsigned needs_binding:1; /* needs delayed unbind/rebind */unsigned resetting_device:1; /* true: bandwidth alloc after reset */unsigned authorized:1; /* used for interface authorization */struct device dev; /* interface specific device info */struct device *usb_dev;struct work_struct reset_ws; /* for resets in atomic context */...... }; #define to_usb_device(d) container_of(d, struct usb_device, dev)static inline struct usb_device *interface_to_usbdev(struct usb_interface *intf) {return to_usb_device(intf-dev.parent); } int __must_check usb_find_common_endpoints(struct usb_host_interface *alt,struct usb_endpoint_descriptor **bulk_in,struct usb_endpoint_descriptor **bulk_out,struct usb_endpoint_descriptor **int_in,struct usb_endpoint_descriptor **int_out);int __must_check usb_find_common_endpoints_reverse(struct usb_host_interface *alt,struct usb_endpoint_descriptor **bulk_in,struct usb_endpoint_descriptor **bulk_out,struct usb_endpoint_descriptor **int_in,struct usb_endpoint_descriptor **int_out);static inline int __must_check usb_find_bulk_in_endpoint(struct usb_host_interface *alt,struct usb_endpoint_descriptor **bulk_in) {return usb_find_common_endpoints(alt, bulk_in, NULL, NULL, NULL); }static inline int __must_check usb_find_bulk_out_endpoint(struct usb_host_interface *alt,struct usb_endpoint_descriptor **bulk_out) {return usb_find_common_endpoints(alt, NULL, bulk_out, NULL, NULL); }static inline int __must_check usb_find_int_in_endpoint(struct usb_host_interface *alt,struct usb_endpoint_descriptor **int_in) {return usb_find_common_endpoints(alt, NULL, NULL, int_in, NULL); }static inline int __must_check usb_find_int_out_endpoint(struct usb_host_interface *alt,struct usb_endpoint_descriptor **int_out) {return usb_find_common_endpoints(alt, NULL, NULL, NULL, int_out); }static inline int __must_check usb_find_last_bulk_in_endpoint(struct usb_host_interface *alt,struct usb_endpoint_descriptor **bulk_in) {return usb_find_common_endpoints_reverse(alt, bulk_in, NULL, NULL, NULL); }static inline int __must_check usb_find_last_bulk_out_endpoint(struct usb_host_interface *alt,struct usb_endpoint_descriptor **bulk_out) {return usb_find_common_endpoints_reverse(alt, NULL, bulk_out, NULL, NULL); }static inline int __must_check usb_find_last_int_in_endpoint(struct usb_host_interface *alt,struct usb_endpoint_descriptor **int_in) {return usb_find_common_endpoints_reverse(alt, NULL, NULL, int_in, NULL); }static inline int __must_check usb_find_last_int_out_endpoint(struct usb_host_interface *alt,struct usb_endpoint_descriptor **int_out) {return usb_find_common_endpoints_reverse(alt, NULL, NULL, NULL, int_out); }3.2.匹配驱动和设备及接口 USB Class Driver和USB设备接口、USB设备和USB Core(USB Driver)都是通过struct usb_device_id中的信息进行匹配。struct usb_device_id定义了4中匹配方式第一种是产品信息匹配通常情况使用VID和PID第二种是根据设备类信息进行匹配第三种根据接口的类信息进行匹配第四种根据厂家自定义的接口进行匹配。具体使用那种匹配方式由match_flags决定内核定义了USB_DEVICE_ID_xx开头的宏用来设置match_flags。USB Class Driver和USB设备接口、USB设备和USB Core(USB Driver)的匹配工作由usb_bus_type中的usb_device_match函数完成该函数会进一步调用usb_match_id进行匹配。 [include/linux/mod_devicetable.h] struct usb_device_id {/* which fields to match against? */__u16 match_flags;/* Used for product specific matches; range is inclusive */__u16 idVendor;__u16 idProduct;__u16 bcdDevice_lo;__u16 bcdDevice_hi;/* Used for device class matches */__u8 bDeviceClass;__u8 bDeviceSubClass;__u8 bDeviceProtocol;/* Used for interface class matches */__u8 bInterfaceClass;__u8 bInterfaceSubClass;__u8 bInterfaceProtocol;/* Used for vendor-specific interface matches */__u8 bInterfaceNumber;/* not matched against */kernel_ulong_t driver_info__attribute__((aligned(sizeof(kernel_ulong_t)))); }; /* Some useful macros to use to create struct usb_device_id */ #define USB_DEVICE_ID_MATCH_VENDOR 0x0001 #define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 #define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 #define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 #define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 #define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 #define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 #define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 #define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400[include/linux/usb.h] #define USB_DEVICE_ID_MATCH_DEVICE \(USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT) #define USB_DEVICE_ID_MATCH_DEV_RANGE \(USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI) #define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION \(USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE) #define USB_DEVICE_ID_MATCH_DEV_INFO \(USB_DEVICE_ID_MATCH_DEV_CLASS | \USB_DEVICE_ID_MATCH_DEV_SUBCLASS | \USB_DEVICE_ID_MATCH_DEV_PROTOCOL) #define USB_DEVICE_ID_MATCH_INT_INFO \(USB_DEVICE_ID_MATCH_INT_CLASS | \USB_DEVICE_ID_MATCH_INT_SUBCLASS | \USB_DEVICE_ID_MATCH_INT_PROTOCOL)/*** USB_DEVICE - macro used to describe a specific usb device* vend: the 16 bit USB Vendor ID* prod: the 16 bit USB Product ID** This macro is used to create a struct usb_device_id that matches a* specific device.*/ #define USB_DEVICE(vend, prod) \.match_flags USB_DEVICE_ID_MATCH_DEVICE, \.idVendor (vend), \.idProduct (prod)/*** USB_INTERFACE_INFO - macro used to describe a class of usb interfaces* cl: bInterfaceClass value* sc: bInterfaceSubClass value* pr: bInterfaceProtocol value** This macro is used to create a struct usb_device_id that matches a* specific class of interfaces.*/ #define USB_INTERFACE_INFO(cl, sc, pr) \.match_flags USB_DEVICE_ID_MATCH_INT_INFO, \.bInterfaceClass (cl), \.bInterfaceSubClass (sc), \.bInterfaceProtocol (pr) ......const struct usb_device_id *usb_match_id(struct usb_interface *interface,const struct usb_device_id *id); extern struct bus_type usb_bus_type;[drivers/usb/core/driver.c] struct bus_type usb_bus_type {.name usb,.match usb_device_match,.uevent usb_uevent,.need_parent_lock true, };struct usb_driver定义的USB Class Driver驱动和USB设备的接口匹配而struct usb_device_driver定义的驱动和USB设备匹配使用usb_register_device_driver和usb_deregister_device_driver函数注册和注销struct usb_device_driver。内核提供了通用的struct usb_device_driver即usb_generic_driver在USB子系统初始化的时候注册到系统中通常情况下USB Class Driver无需再提供struct usb_device_driver。 [include/linux/usb.h] struct usb_device_driver {const char *name;/* If set, used for better device/driver matching. */bool (*match) (struct usb_device *udev);/* Called to see if the driver is willing to manage a particular* device. If it is, probe returns zero and uses dev_set_drvdata()* to associate driver-specific data with the device. If unwilling* to manage the device, return a negative errno value. */int (*probe) (struct usb_device *udev);/* Called when the device is no longer accessible, usually* because it has been (or is being) disconnected or the drivers* module is being unloaded.*/void (*disconnect) (struct usb_device *udev);int (*suspend) (struct usb_device *udev, pm_message_t message);int (*resume) (struct usb_device *udev, pm_message_t message);const struct attribute_group **dev_groups;struct usbdrv_wrap drvwrap;/* used with match() to select better matching driver at probe() time.*/const struct usb_device_id *id_table;unsigned int supports_autosuspend:1;unsigned int generic_subclass:1; };extern int usb_register_device_driver(struct usb_device_driver *,struct module *); extern void usb_deregister_device_driver(struct usb_device_driver *); extern struct usb_device_driver usb_generic_driver;[drivers/usb/core/generic.c] struct usb_device_driver usb_generic_driver {.name usb,.match usb_generic_driver_match,.probe usb_generic_driver_probe,.disconnect usb_generic_driver_disconnect, #ifdef CONFIG_PM.suspend usb_generic_driver_suspend,.resume usb_generic_driver_resume, #endif.supports_autosuspend 1, };3.3.管理设备 USB Core(USB Driver)使用struct usb_device数据结构描述USB设备。该数据结构在系统枚举USB设备的时候由usb_alloc_dev函数分配和usb_new_device初始化。 [include/linux/usb.h] struct usb_device {/* device number; address on a USB bus */int devnum;/* device ID string for use in messages (e.g., /port/...) */char devpath[16];/* tree topology hex string for use with xHCI */u32 route;/* device state: configured, not attached, etc. */enum usb_device_state state;/* device speed: high/full/low (or error) */enum usb_device_speed speed;/* number of rx lanes in use, USB 3.2 adds dual-lane support */unsigned int rx_lanes;/* number of tx lanes in use, USB 3.2 adds dual-lane support */unsigned int tx_lanes;/* Transaction Translator info; used with low/full speed dev,* highspeed hub */struct usb_tt *tt;int ttport; /* device port on that tt hub *//* one bit for each endpoint, with ([0] IN, [1] OUT) endpoints */unsigned int toggle[2];/* our hub, unless were the root */struct usb_device *parent;struct usb_bus *bus; /* bus were part of *//* endpoint 0 data (default control pipe) */struct usb_host_endpoint ep0;struct device dev; /* generic device interface *//* USB device descriptor */struct usb_device_descriptor descriptor;struct usb_host_bos *bos;/* all of the devices configs */struct usb_host_config *config;/* the active configuration */struct usb_host_config *actconfig;struct usb_host_endpoint *ep_in[16]; /* array of IN endpoints */struct usb_host_endpoint *ep_out[16]; /* array of OUT endpoints */char **rawdescriptors; /* raw descriptors for each config *//* Current available from the bus */unsigned short bus_mA;u8 portnum; /* parent port number (origin 1) */u8 level; /* number of USB hub ancestors *//* device address, XHCI: assigned by HW, others: same as devnum */u8 devaddr;....../* ask driver core to reprobe using the generic driver */unsigned use_generic_driver:1;...... };[include/linux/usb/hcd.h] /* Enumeration is only for the hub driver, or HCD virtual root hubs */ /* usb device constructor (usbcore-internal) */ extern struct usb_device *usb_alloc_dev(struct usb_device *parent,struct usb_bus *, unsigned port); /* perform initial device setup (usbcore-internal) */ extern int usb_new_device(struct usb_device *dev); /* disconnect a device (usbcore-internal) */ void usb_disconnect(struct usb_device **pdev);4. USB Host Controller Driver Linux内核使用struct usb_hcd数据结构描述USB Host Controller Driver使用struct hc_driver描述USB Host Controller的操作方法比如通信接口usb_submit_urb最终会调用到urb_enqueue函数不同接口协议的USB Host Controller需要提供不同的struct hc_driver。使用usb_create_hcd和__usb_create_hcd函数创建struct usb_hcd使用usb_add_hcd函数添加struct usb_hcd使用usb_remove_hcd移除struct usb_hcd。 [include/linux/usb/hcd.h] struct usb_hcd {struct usb_bus self; /* hcd is-a bus */struct kref kref; /* reference counter */const char *product_desc; /* product/vendor string */int speed; /* Speed for this roothub. */char irq_descr[24]; /* driver bus # */struct timer_list rh_timer; /* drives root-hub polling */struct urb *status_urb; /* the current status urb */ #ifdef CONFIG_PMstruct work_struct wakeup_work; /* for remote wakeup */ #endifstruct work_struct died_work; /* for when the device dies *//* hardware info/state */const struct hc_driver *driver; /* hw-specific hooks *//* OTG and some Host controllers need software interaction with phys;* other external phys should be software-transparent*/struct usb_phy *usb_phy;struct usb_phy_roothub *phy_roothub;....../* bandwidth_mutex should be taken before adding or removing* any new bus bandwidth constraints:* 1. Before adding a configuration for a new device.* 2. Before removing the configuration to put the device into* the addressed state.* 3. Before selecting a different configuration.* 4. Before selecting an alternate interface setting.** bandwidth_mutex should be dropped after a successful control message* to the device, or resetting the bandwidth after a failed attempt.*/struct mutex *address0_mutex;struct mutex *bandwidth_mutex;struct usb_hcd *shared_hcd;struct usb_hcd *primary_hcd;...... };struct hc_driver {const char *description; /* ehci-hcd etc */const char *product_desc; /* product/vendor string */size_t hcd_priv_size; /* size of private data *//* irq handler */irqreturn_t (*irq) (struct usb_hcd *hcd);....../* called to init HCD and root hub */int (*reset) (struct usb_hcd *hcd);int (*start) (struct usb_hcd *hcd);/* NOTE: these suspend/resume calls relate to the HC as* a whole, not just the root hub; theyre for PCI bus glue.*//* called after suspending the hub, before entering D3 etc */int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup);/* called after entering D0 (etc), before resuming the hub */int (*pci_resume)(struct usb_hcd *hcd, bool hibernated);/* cleanly make HCD stop writing memory and doing I/O */void (*stop) (struct usb_hcd *hcd);/* shutdown HCD */void (*shutdown) (struct usb_hcd *hcd);/* return current frame number */int (*get_frame_number) (struct usb_hcd *hcd);/* manage i/o requests, device state */int (*urb_enqueue)(struct usb_hcd *hcd,struct urb *urb, gfp_t mem_flags);int (*urb_dequeue)(struct usb_hcd *hcd,struct urb *urb, int status);/** (optional) these hooks allow an HCD to override the default DMA* mapping and unmapping routines. In general, they shouldnt be* necessary unless the host controller has special DMA requirements,* such as alignment contraints. If these are not specified, the* general usb_hcd_(un)?map_urb_for_dma functions will be used instead* (and it may be a good idea to call these functions in your HCD* implementation)*/int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb,gfp_t mem_flags);void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb);/* hw synch, freeing endpoint resources that urb_dequeue cant */void (*endpoint_disable)(struct usb_hcd *hcd,struct usb_host_endpoint *ep);/* (optional) reset any endpoint state such as sequence numberand current window */void (*endpoint_reset)(struct usb_hcd *hcd,struct usb_host_endpoint *ep);/* root hub support */int (*hub_status_data) (struct usb_hcd *hcd, char *buf);int (*hub_control) (struct usb_hcd *hcd,u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength);int (*bus_suspend)(struct usb_hcd *);int (*bus_resume)(struct usb_hcd *);int (*start_port_reset)(struct usb_hcd *, unsigned port_num);unsigned long (*get_resuming_ports)(struct usb_hcd *);/* force handover of high-speed port to full-speed companion */void (*relinquish_port)(struct usb_hcd *, int);/* has a port been handed over to a companion? */int (*port_handed_over)(struct usb_hcd *, int);/* CLEAR_TT_BUFFER completion callback */void (*clear_tt_buffer_complete)(struct usb_hcd *,struct usb_host_endpoint *);/* xHCI specific functions *//* Called by usb_alloc_dev to alloc HC device structures */int (*alloc_dev)(struct usb_hcd *, struct usb_device *);/* Called by usb_disconnect to free HC device structures */void (*free_dev)(struct usb_hcd *, struct usb_device *);/* Change a group of bulk endpoints to support multiple stream IDs */int (*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev,struct usb_host_endpoint **eps, unsigned int num_eps,unsigned int num_streams, gfp_t mem_flags);/* Reverts a group of bulk endpoints back to not using stream IDs.* Can fail if we run out of memory.*/int (*free_streams)(struct usb_hcd *hcd, struct usb_device *udev,struct usb_host_endpoint **eps, unsigned int num_eps,gfp_t mem_flags);/* Bandwidth computation functions *//* Note that add_endpoint() can only be called once per endpoint before* check_bandwidth() or reset_bandwidth() must be called.* drop_endpoint() can only be called once per endpoint also.* A call to xhci_drop_endpoint() followed by a call to* xhci_add_endpoint() will add the endpoint to the schedule with* possibly new parameters denoted by a different endpoint descriptor* in usb_host_endpoint. A call to xhci_add_endpoint() followed by a* call to xhci_drop_endpoint() is not allowed.*//* Allocate endpoint resources and add them to a new schedule */int (*add_endpoint)(struct usb_hcd *, struct usb_device *,struct usb_host_endpoint *);/* Drop an endpoint from a new schedule */int (*drop_endpoint)(struct usb_hcd *, struct usb_device *,struct usb_host_endpoint *);/* Check that a new hardware configuration, set using* endpoint_enable and endpoint_disable, does not exceed bus* bandwidth. This must be called before any set configuration* or set interface requests are sent to the device.*/int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);/* Reset the device schedule to the last known good schedule,* which was set from a previous successful call to* check_bandwidth(). This reverts any add_endpoint() and* drop_endpoint() calls since that last successful call.* Used for when a check_bandwidth() call fails due to resource* or bandwidth constraints.*/void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);/* Returns the hardware-chosen device address */int (*address_device)(struct usb_hcd *, struct usb_device *udev);/* prepares the hardware to send commands to the device */int (*enable_device)(struct usb_hcd *, struct usb_device *udev);/* Notifies the HCD after a hub descriptor is fetched.* Will block.*/int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev,struct usb_tt *tt, gfp_t mem_flags);int (*reset_device)(struct usb_hcd *, struct usb_device *);/* Notifies the HCD after a device is connected and its* address is set*/int (*update_device)(struct usb_hcd *, struct usb_device *);int (*set_usb2_hw_lpm)(struct usb_hcd *, struct usb_device *, int);/* USB 3.0 Link Power Management *//* Returns the USB3 hub-encoded value for the U1/U2 timeout. */int (*enable_usb3_lpm_timeout)(struct usb_hcd *,struct usb_device *, enum usb3_link_state state);/* The xHCI host controller can still fail the command to* disable the LPM timeouts, so this can return an error code.*/int (*disable_usb3_lpm_timeout)(struct usb_hcd *,struct usb_device *, enum usb3_link_state state);int (*find_raw_port_number)(struct usb_hcd *, int);/* Call for power on/off the port if necessary */int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);...... };struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,struct device *sysdev, struct device *dev, const char *bus_name,struct usb_hcd *primary_hcd); /* create and initialize an HCD structure */ extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,struct device *dev, const char *bus_name); /* finish generic HCD structure initialization and register */ extern int usb_add_hcd(struct usb_hcd *hcd,unsigned int irqnum, unsigned long irqflags); /* shutdown processing for generic HCDs */ extern void usb_remove_hcd(struct usb_hcd *hcd);xHCI、EHCI、OHCI三种接口协议标准的USB Host Controller Driver的struct hc_driver定义如下。 [drivers/usb/host/xhci.c] static const struct hc_driver xhci_hc_driver {.description xhci-hcd,.product_desc xHCI Host Controller,.hcd_priv_size sizeof(struct xhci_hcd),/* generic hardware linkage */.irq xhci_irq,.flags HCD_MEMORY | HCD_DMA | HCD_USB3 | HCD_SHARED | HCD_BH,/* basic lifecycle operations */.reset NULL, /* xhci_plat_setup */.start xhci_run, /* xhci_plat_start */.stop xhci_stop,.shutdown xhci_shutdown,/* managing i/o requests and associated device resources */.map_urb_for_dma xhci_map_urb_for_dma,.urb_enqueue xhci_urb_enqueue,.urb_dequeue xhci_urb_dequeue,.alloc_dev xhci_alloc_dev,.free_dev xhci_free_dev,.alloc_streams xhci_alloc_streams,.free_streams xhci_free_streams,.add_endpoint xhci_add_endpoint,.drop_endpoint xhci_drop_endpoint,.endpoint_disable xhci_endpoint_disable,.endpoint_reset xhci_endpoint_reset,.check_bandwidth xhci_check_bandwidth,.reset_bandwidth xhci_reset_bandwidth,.address_device xhci_address_device,.enable_device xhci_enable_device,.update_hub_device xhci_update_hub_device,.reset_device xhci_discover_or_reset_device,/* scheduling support */.get_frame_number xhci_get_frame,/* root hub support */.hub_control xhci_hub_control,.hub_status_data xhci_hub_status_data,.bus_suspend xhci_bus_suspend,.bus_resume xhci_bus_resume,.get_resuming_ports xhci_get_resuming_ports,/* call back when device connected and addressed */.update_device xhci_update_device,.set_usb2_hw_lpm xhci_set_usb2_hardware_lpm,.enable_usb3_lpm_timeout xhci_enable_usb3_lpm_timeout,.disable_usb3_lpm_timeout xhci_disable_usb3_lpm_timeout,.find_raw_port_number xhci_find_raw_port_number,.clear_tt_buffer_complete xhci_clear_tt_buffer_complete, };[drivers/usb/host/ehci-hcd.c] static const struct hc_driver ehci_hc_driver {.description hcd_name,.product_desc EHCI Host Controller,.hcd_priv_size sizeof(struct ehci_hcd),/* generic hardware linkage */.irq ehci_irq,.flags HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,/* basic lifecycle operations */.reset ehci_setup,.start ehci_run,.stop ehci_stop,.shutdown ehci_shutdown,/* managing i/o requests and associated device resources */.urb_enqueue ehci_urb_enqueue,.urb_dequeue ehci_urb_dequeue,.endpoint_disable ehci_endpoint_disable,.endpoint_reset ehci_endpoint_reset,.clear_tt_buffer_complete ehci_clear_tt_buffer_complete,/* scheduling support */.get_frame_number ehci_get_frame,/* root hub support */.hub_status_data ehci_hub_status_data,.hub_control ehci_hub_control,.bus_suspend ehci_bus_suspend,.bus_resume ehci_bus_resume,.relinquish_port ehci_relinquish_port,.port_handed_over ehci_port_handed_over,.get_resuming_ports ehci_get_resuming_ports,/* device support */.free_dev ehci_remove_device, };[drivers/usb/host/ohci-hcd.c] static const struct hc_driver ohci_hc_driver {.description hcd_name,.product_desc OHCI Host Controller,.hcd_priv_size sizeof(struct ohci_hcd),/* generic hardware linkage */.irq ohci_irq,.flags HCD_MEMORY | HCD_DMA | HCD_USB11,/* basic lifecycle operations */.reset ohci_setup,.start ohci_start,.stop ohci_stop,.shutdown ohci_shutdown,/* managing i/o requests and associated device resources */.urb_enqueue ohci_urb_enqueue,.urb_dequeue ohci_urb_dequeue,.endpoint_disable ohci_endpoint_disable,/* scheduling support */.get_frame_number ohci_get_frame,/* root hub support */.hub_status_data ohci_hub_status_data,.hub_control ohci_hub_control, #ifdef CONFIG_PM.bus_suspend ohci_bus_suspend,.bus_resume ohci_bus_resume, #endif.start_port_reset ohci_start_port_reset, };5. USB子系统 Linux内核主机USB子系统的初始化入口如下所示注册了usb_bus_type、usbfs_driver、usb_generic_driver初始化了USB设备的设备号、hub等。 [drivers\usb\core\usb.c] static int __init usb_init(void) {......retval bus_register(usb_bus_type);if (retval)goto bus_register_failed;retval bus_register_notifier(usb_bus_type, usb_bus_nb);if (retval)goto bus_notifier_failed;retval usb_major_init();if (retval)goto major_init_failed;retval usb_register(usbfs_driver);if (retval)goto driver_register_failed;retval usb_devio_init();if (retval)goto usb_devio_init_failed;retval usb_hub_init();if (retval)goto hub_init_failed;retval usb_register_device_driver(usb_generic_driver, THIS_MODULE);if (!retval)goto out;...... } static void __exit usb_exit(void) {......usb_release_quirk_list();usb_deregister_device_driver(usb_generic_driver);usb_major_cleanup();usb_deregister(usbfs_driver);usb_devio_cleanup();usb_hub_cleanup();bus_unregister_notifier(usb_bus_type, usb_bus_nb);bus_unregister(usb_bus_type);usb_acpi_unregister();usb_debugfs_cleanup();idr_destroy(usb_bus_idr); } subsys_initcall(usb_init); module_exit(usb_exit);参考资料 eXtensible Host Controller Interface for Universal Serial BusLinux kernel 5.10Linux驱动开发实例Linux设备驱动开发详解
http://www.sadfv.cn/news/16958/

相关文章:

  • 什么店是做网站制作的创意型网站建设
  • 设计师网站有哪些网站如何做问卷调查
  • 衡水网站建设找谁网站后台用什么开发
  • 泉企业网站建设wordpress图片数据库
  • 机机票网站建设wordpress 使用jquery
  • 白云区手机版网站建设网站服务器建设费用
  • 运动网站模板西安网站设计哪家好
  • 建设旅游网站电子商务公司招聘
  • 制作销售网站有哪些问题某些网站dns解析失败
  • 微网站模板建设的选择百度首页百度
  • 南京网站设计公司济南兴田德润简介图片山东监理工程师考试最新消息
  • 5g天天奭5g天天运动网站代码渝快办官网
  • 做网站优惠seo诊断专家
  • 网站建设方案功能描述网站建设东莞
  • 建设装修公司网站单页加盟网站模板
  • 天津手机网站公司wordpress如何备份 网站
  • 购物网站的功能wordpress生成分类目录
  • 书店网站模板凡科网站建设价格
  • 怎么做带后台的网站h5页面设计是什么意思
  • 阿坝网站设计网站建设公司华网天下买2年送2年
  • 2021建站公司东莞建设网官
  • 专业平台建设网站关了吗给公司做网站多钱
  • 如何建设好高校网站郑州模板建站定制网站
  • 品牌网站的建设网站建设需要的技术手段
  • 垂直行业门户网站wordpress 设置网站目录权限
  • 企业网站seo策略做推广的注册什么公司好
  • 网站建设算什么服务类型简单网页设计模板代码
  • 江门网站建设推荐学做效果图网站有哪些
  • 北京建公司网站价格免费行情软件网站直播
  • 网站要有可留言功能 怎么做便宜的网站设计企业