USB驅動框架分析1

本文主要分析usb框架的主要數據結構,usb驅動框架的初始化,usb系統模型的建立過程。先貼一張網上找來的圖,很清晰很詳細。






上圖濃縮了usb設備模型的建立流程,再次感謝網上前輩的經驗總結。下面以文字總結這個過程:

(1). usb主機控制器驅動的probe過程,分配usb_hcd,然後添加到系統中,一個主控制器對應一條usb總線,一個主控制器綁定着一個root hub,一個root hub對應於一個usb_device,然後註冊此root  hub,主要是調用usb_new_device。每個usb設備(usb_device)有一種或多種配置,每種配置有一個或多個接口,一個接口有一種或多種設置,一種設置有一個或多個端點。爲了獲取並解析這些描述符,usb_new_device調用usb_configure_device,然後將設備添加到內核。每個usb設備都有一個控制端點。它通常用於配置設備,獲取設備信息,發送命令到設備,或者獲取設備的狀態報告,usb_new_device中調用了函數usb_create_ep_devs。


(2). 當root hub這個usb_device添加到系統中時,系統中也有一個usb_device_driver(注意,不是usb_driver),一個是對應usb設備,一個對應usb接口。匹配上之後就會調用generic_probe,在這個函數裏面調用usb_choose_configuration爲設備選擇一個合理的配置,到此就可以用選定配置下的所有描述符進行設備配置了。函數usb_set_configuration就是完成此項功能。在函數usb_set_configuration中將設備的所有接口都添加到內核device_add(&intf->dev)。這些接口設備的總線類型也是usb_bus_type,不過設備類型爲usb_if_device_type。


(3). 接口添加到系統中了,當然要匹配接口驅動。恰好系統中有一個usb_driver爲hub_driver,它是爲hub接口準備的。接口又分爲hub的接口和usb設備的接口。如果是設備的接口,如果匹配上了後就調用probe函數,做相應的初始化、設備模型建立等工作,例如usb storage驅動,後面會有介紹。如果是hub的接口,就調用hub_probe。

1. usb驅動框架的數據結構

  1. struct usb_device {  
  2.     int     devnum; //usb設備在一條usb總線上的編號  
  3.     char        devpath[16];    //路徑字符串  
  4.     u32     route;  
  5.     enum usb_device_state   state;  //狀態  
  6.     enum usb_device_speed   speed;  //速度  
  7.   
  8.     struct usb_tt   *tt;    //高低速之間的數據轉換  
  9.     int     ttport;  
  10.   
  11.     unsigned int toggle[2]; //每一位表示每個端點當前發送或接受的是DATA0還是DATA1  
  12.   
  13.     struct usb_device *parent;  //父usb設備  
  14.     struct usb_bus *bus;    //設備所在的那條總線  
  15.     struct usb_host_endpoint ep0;   //端點0,比較特殊  
  16.   
  17.     struct device dev;  //內嵌的device結構  
  18.   
  19.     struct usb_device_descriptor descriptor;    //設備描述符  
  20.     struct usb_host_config *config; //usb設備的配置數組  
  21.   
  22.     struct usb_host_config *actconfig;  //usb設備的當前激活配置  
  23.     struct usb_host_endpoint *ep_in[16];    //16個in端點  
  24.     struct usb_host_endpoint *ep_out[16];   //16個out端點  
  25.   
  26.     char **rawdescriptors;  //指針數組,指向GET_DESCRIPTOR請求獲得的配置描述符的結果  
  27.   
  28.     unsigned short bus_mA;  
  29.     u8 portnum; //端口號  
  30.     u8 level;   //層次  
  31.   
  32.     unsigned can_submit:1;  
  33.     unsigned persist_enabled:1;  
  34.     unsigned have_langid:1;  
  35.     unsigned authorized:1;  
  36.     unsigned authenticated:1;  
  37.     unsigned wusb:1;  
  38.     int string_langid;  
  39.   
  40.     /* static strings from the device */  
  41.     char *product;  
  42.     char *manufacturer;  
  43.     char *serial;  
  44.   
  45.     struct list_head filelist;  
  46. #ifdef CONFIG_USB_DEVICE_CLASS  
  47.     struct device *usb_classdev;    //類設備  
  48. #endif  
  49. #ifdef CONFIG_USB_DEVICEFS  
  50.     struct dentry *usbfs_dentry;    //usbfs相關的目錄項  
  51. #endif  
  52.   
  53.     int maxchild;   //Hub的端口數  
  54.     struct usb_device *children[USB_MAXCHILDREN];   //子usb設備  
  55.   
  56.     u32 quirks;  
  57.     atomic_t urbnum;  
  58.   
  59.     unsigned long active_duration;  
  60.   
  61. #ifdef CONFIG_PM  
  62.     unsigned long connect_time;  
  63.   
  64.     unsigned do_remote_wakeup:1;  
  65.     unsigned reset_resume:1;  
  66. #endif  
  67.     struct wusb_dev *wusb_dev;  
  68.     int slot_id;  
  69. };  
struct usb_device {
	int		devnum;	//usb設備在一條usb總線上的編號
	char		devpath[16];	//路徑字符串
	u32		route;
	enum usb_device_state	state;	//狀態
	enum usb_device_speed	speed;	//速度

	struct usb_tt	*tt;	//高低速之間的數據轉換
	int		ttport;

	unsigned int toggle[2];	//每一位表示每個端點當前發送或接受的是DATA0還是DATA1

	struct usb_device *parent;	//父usb設備
	struct usb_bus *bus;	//設備所在的那條總線
	struct usb_host_endpoint ep0;	//端點0,比較特殊

	struct device dev;	//內嵌的device結構

	struct usb_device_descriptor descriptor;	//設備描述符
	struct usb_host_config *config;	//usb設備的配置數組

	struct usb_host_config *actconfig;	//usb設備的當前激活配置
	struct usb_host_endpoint *ep_in[16];	//16個in端點
	struct usb_host_endpoint *ep_out[16];	//16個out端點

	char **rawdescriptors;	//指針數組,指向GET_DESCRIPTOR請求獲得的配置描述符的結果

	unsigned short bus_mA;
	u8 portnum;	//端口號
	u8 level;	//層次

	unsigned can_submit:1;
	unsigned persist_enabled:1;
	unsigned have_langid:1;
	unsigned authorized:1;
	unsigned authenticated:1;
	unsigned wusb:1;
	int string_langid;

	/* static strings from the device */
	char *product;
	char *manufacturer;
	char *serial;

	struct list_head filelist;
#ifdef CONFIG_USB_DEVICE_CLASS
	struct device *usb_classdev;	//類設備
#endif
#ifdef CONFIG_USB_DEVICEFS
	struct dentry *usbfs_dentry;	//usbfs相關的目錄項
#endif

	int maxchild;	//Hub的端口數
	struct usb_device *children[USB_MAXCHILDREN];	//子usb設備

	u32 quirks;
	atomic_t urbnum;

	unsigned long active_duration;

#ifdef CONFIG_PM
	unsigned long connect_time;

	unsigned do_remote_wakeup:1;
	unsigned reset_resume:1;
#endif
	struct wusb_dev *wusb_dev;
	int slot_id;
};
再來看下usb_device_descriptor

  1. struct usb_device_descriptor {  
  2.     __u8  bLength;  //長度  
  3.     __u8  bDescriptorType;  //描述符類型  
  4.   
  5.     __le16 bcdUSB;  //usb spec 的版本號  
  6.     __u8  bDeviceClass; //設備的類  
  7.     __u8  bDeviceSubClass;  //設備的子類  
  8.     __u8  bDeviceProtocol;  //設備的協議  
  9.     __u8  bMaxPacketSize0;  //端口0一次可以處理的最大字節數  
  10.     __le16 idVendor;    //廠商ID  
  11.     __le16 idProduct;   //產品ID  
  12.     __le16 bcdDevice;   //設備的版本號      
  13.     __u8  iManufacturer;    //廠商字符串對應的索引  
  14.     __u8  iProduct; //產品字符串對應的索引  
  15.     __u8  iSerialNumber;    //產品序列號對應的索引  
  16.     __u8  bNumConfigurations;   //當前速度下的配置個數  
  17. } __attribute__ ((packed));  
struct usb_device_descriptor {
	__u8  bLength;	//長度
	__u8  bDescriptorType;	//描述符類型

	__le16 bcdUSB;	//usb spec 的版本號
	__u8  bDeviceClass;	//設備的類
	__u8  bDeviceSubClass;	//設備的子類
	__u8  bDeviceProtocol;	//設備的協議
	__u8  bMaxPacketSize0;	//端口0一次可以處理的最大字節數
	__le16 idVendor;	//廠商ID
	__le16 idProduct;	//產品ID
	__le16 bcdDevice;	//設備的版本號	
	__u8  iManufacturer;	//廠商字符串對應的索引
	__u8  iProduct;	//產品字符串對應的索引
	__u8  iSerialNumber;	//產品序列號對應的索引
	__u8  bNumConfigurations;	//當前速度下的配置個數
} __attribute__ ((packed));
  1. struct usb_host_config {  
  2.     struct usb_config_descriptor    desc;   //usb配置描述符  
  3.   
  4.     char *string;       /* iConfiguration string, if present */  
  5.   
  6.     /* List of any Interface Association Descriptors in this 
  7.      * configuration. */  
  8.     struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];  
  9.   
  10.     /* the interfaces associated with this configuration, 
  11.      * stored in no particular order */  
  12.     struct usb_interface *interface[USB_MAXINTERFACES]; //該配置包含的接口  
  13.   
  14.     /* Interface information available even when this is not the 
  15.      * active configuration */  
  16.     struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];  
  17.   
  18.     unsigned char *extra;   /* Extra descriptors */  
  19.     int extralen;  
  20. };  
struct usb_host_config {
	struct usb_config_descriptor	desc;	//usb配置描述符

	char *string;		/* iConfiguration string, if present */

	/* List of any Interface Association Descriptors in this
	 * configuration. */
	struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];

	/* the interfaces associated with this configuration,
	 * stored in no particular order */
	struct usb_interface *interface[USB_MAXINTERFACES];	//該配置包含的接口

	/* Interface information available even when this is not the
	 * active configuration */
	struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];

	unsigned char *extra;   /* Extra descriptors */
	int extralen;
};
  1. struct usb_config_descriptor {  
  2.     __u8  bLength;  
  3.     __u8  bDescriptorType;  
  4.   
  5.     __le16 wTotalLength;  
  6.     __u8  bNumInterfaces;  
  7.     __u8  bConfigurationValue;  
  8.     __u8  iConfiguration;  
  9.     __u8  bmAttributes;  
  10.     __u8  bMaxPower;  
  11. } __attribute__ ((packed));  
struct usb_config_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__le16 wTotalLength;
	__u8  bNumInterfaces;
	__u8  bConfigurationValue;
	__u8  iConfiguration;
	__u8  bmAttributes;
	__u8  bMaxPower;
} __attribute__ ((packed));
  1. struct usb_interface {  
  2.     /* array of alternate settings for this interface, 
  3.      * stored in no particular order */  
  4.     struct usb_host_interface *altsetting;  //該接口的設置數組  
  5.   
  6.     struct usb_host_interface *cur_altsetting;  /* the currently 
  7.                      * active alternate setting */  //該接口的當前設置  
  8.     unsigned num_altsetting;    /* number of alternate settings */  
  9.   
  10.     /* If there is an interface association descriptor then it will list 
  11.      * the associated interfaces */  
  12.     struct usb_interface_assoc_descriptor *intf_assoc;  
  13.   
  14.     int minor;          /* minor number this interface is 
  15.                      * bound to */  
  16.     enum usb_interface_condition condition;     /* state of binding */  
  17.     unsigned sysfs_files_created:1; /* the sysfs attributes exist */  
  18.     unsigned ep_devs_created:1; /* endpoint "devices" exist */  
  19.     unsigned unregistering:1;   /* unregistration is in progress */  
  20.     unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */  
  21.     unsigned needs_altsetting0:1;   /* switch to altsetting 0 is pending */  
  22.     unsigned needs_binding:1;   /* needs delayed unbind/rebind */  
  23.     unsigned reset_running:1;  
  24.     unsigned resetting_device:1;    /* true: bandwidth alloc after reset */  
  25.   
  26.     struct device dev;      /* interface specific device info */  
  27.     struct device *usb_dev;  
  28.     atomic_t pm_usage_cnt;      /* usage counter for autosuspend */  
  29.     struct work_struct reset_ws;    /* for resets in atomic context */  
  30. };  
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 reset_running:1;
	unsigned resetting_device:1;	/* true: bandwidth alloc after reset */

	struct device dev;		/* interface specific device info */
	struct device *usb_dev;
	atomic_t pm_usage_cnt;		/* usage counter for autosuspend */
	struct work_struct reset_ws;	/* for resets in atomic context */
};
  1. struct usb_host_interface {  
  2.     struct usb_interface_descriptor desc;   //接口描述符  
  3.   
  4.     /* array of desc.bNumEndpoint endpoints associated with this 
  5.      * interface setting.  these will be in no particular order. 
  6.      */  
  7.     struct usb_host_endpoint *endpoint; //該設置用到的端點數組  
  8.   
  9.     char *string;       /* iInterface string, if present */  
  10.     unsigned char *extra;   /* Extra descriptors */  
  11.     int extralen;  
  12. };  
struct usb_host_interface {
	struct usb_interface_descriptor	desc;	//接口描述符

	/* array of desc.bNumEndpoint endpoints associated with this
	 * interface setting.  these will be in no particular order.
	 */
	struct usb_host_endpoint *endpoint;	//該設置用到的端點數組

	char *string;		/* iInterface string, if present */
	unsigned char *extra;   /* Extra descriptors */
	int extralen;
};
  1. struct usb_interface_descriptor {  
  2.     __u8  bLength;  
  3.     __u8  bDescriptorType;  
  4.   
  5.     __u8  bInterfaceNumber;  
  6.     __u8  bAlternateSetting;  
  7.     __u8  bNumEndpoints;  
  8.     __u8  bInterfaceClass;  
  9.     __u8  bInterfaceSubClass;  
  10.     __u8  bInterfaceProtocol;  
  11.     __u8  iInterface;  
  12. } __attribute__ ((packed));  
struct usb_interface_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__u8  bInterfaceNumber;
	__u8  bAlternateSetting;
	__u8  bNumEndpoints;
	__u8  bInterfaceClass;
	__u8  bInterfaceSubClass;
	__u8  bInterfaceProtocol;
	__u8  iInterface;
} __attribute__ ((packed));
  1. struct usb_host_endpoint {  
  2.     struct usb_endpoint_descriptor      desc;   //端點描述符  
  3.     struct usb_ss_ep_comp_descriptor    ss_ep_comp;  
  4.     struct list_head        urb_list;   //該端點的urb鏈表  
  5.     void                *hcpriv;  
  6.     struct ep_device        *ep_dev;    /* For sysfs info */    //端點設備  
  7.   
  8.     unsigned char *extra;   /* Extra descriptors */  
  9.     int extralen;  
  10.     int enabled;  
  11. };  
struct usb_host_endpoint {
	struct usb_endpoint_descriptor		desc;	//端點描述符
	struct usb_ss_ep_comp_descriptor	ss_ep_comp;
	struct list_head		urb_list;	//該端點的urb鏈表
	void				*hcpriv;
	struct ep_device		*ep_dev;	/* For sysfs info */	//端點設備

	unsigned char *extra;   /* Extra descriptors */
	int extralen;
	int enabled;
};
  1. struct usb_interface_descriptor {  
  2.     __u8  bLength;  
  3.     __u8  bDescriptorType;  
  4.   
  5.     __u8  bInterfaceNumber;  
  6.     __u8  bAlternateSetting;  
  7.     __u8  bNumEndpoints;  
  8.     __u8  bInterfaceClass;  
  9.     __u8  bInterfaceSubClass;  
  10.     __u8  bInterfaceProtocol;  
  11.     __u8  iInterface;  
  12. } __attribute__ ((packed));  
struct usb_interface_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__u8  bInterfaceNumber;
	__u8  bAlternateSetting;
	__u8  bNumEndpoints;
	__u8  bInterfaceClass;
	__u8  bInterfaceSubClass;
	__u8  bInterfaceProtocol;
	__u8  iInterface;
} __attribute__ ((packed));
總結:

一個struct usb_device包含一個設備描述符(usb_device_descriptor)和配置結構數組(struct usb_host_config *)。

一個struct usb_host_config包含一個配置描述符(usb_config_descriptor)和接口結構數組(struct usb_interface)

一個usb_interface包含設置結構數組(struct  usb_host_interface *),因爲一個接口可以有多個設置

一個usb_host_interface包含一個接口描述符和端點結構數組(struct usb_host_endpoint *)

一個usb_host_endpoint包含一個端點描述符。

  1. struct usb_driver {  
  2.     const char *name;   //驅動程序的名字  
  3.   
  4.     int (*probe) (struct usb_interface *intf,  
  5.               const struct usb_device_id *id);  
  6.   
  7.     void (*disconnect) (struct usb_interface *intf);  
  8.   
  9.     int (*unlocked_ioctl) (struct usb_interface *intf, unsigned int code,  
  10.             void *buf);  
  11.   
  12.     int (*suspend) (struct usb_interface *intf, pm_message_t message);  
  13.     int (*resume) (struct usb_interface *intf);  
  14.     int (*reset_resume)(struct usb_interface *intf);  
  15.   
  16.     int (*pre_reset)(struct usb_interface *intf);  
  17.     int (*post_reset)(struct usb_interface *intf);  
  18.   
  19.     const struct usb_device_id *id_table;   //驅動支持的設備列表  
  20.   
  21.     struct usb_dynids dynids;   //動態id  
  22.     struct usbdrv_wrap drvwrap;  
  23.     unsigned int no_dynamic_id:1;  
  24.     unsigned int supports_autosuspend:1;  
  25.     unsigned int soft_unbind:1;  
  26. };  
  27. struct usb_device_driver {  
  28.     const char *name;  
  29.   
  30.     int (*probe) (struct usb_device *udev);  
  31.     void (*disconnect) (struct usb_device *udev);  
  32.   
  33.     int (*suspend) (struct usb_device *udev, pm_message_t message);  
  34.     int (*resume) (struct usb_device *udev, pm_message_t message);  
  35.     struct usbdrv_wrap drvwrap;  
  36.     unsigned int supports_autosuspend:1;  
  37. };  
struct usb_driver {
	const char *name;	//驅動程序的名字

	int (*probe) (struct usb_interface *intf,
		      const struct usb_device_id *id);

	void (*disconnect) (struct usb_interface *intf);

	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);

	int (*pre_reset)(struct usb_interface *intf);
	int (*post_reset)(struct usb_interface *intf);

	const struct usb_device_id *id_table;	//驅動支持的設備列表

	struct usb_dynids dynids;	//動態id
	struct usbdrv_wrap drvwrap;
	unsigned int no_dynamic_id:1;
	unsigned int supports_autosuspend:1;
	unsigned int soft_unbind:1;
};
struct usb_device_driver {
	const char *name;

	int (*probe) (struct usb_device *udev);
	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);
	struct usbdrv_wrap drvwrap;
	unsigned int supports_autosuspend:1;
};
再次強調usb_driver是面向接口的,系統中有好多接口驅動,如hub_driver,usb_storage_driver。usb_device_driver是面向設備的,只有一個usb_generic_driver。

  1. struct usb_hcd {  
  2.   
  3.     /* 
  4.      * housekeeping 
  5.      */  
  6.     struct usb_bus      self;       /* hcd is-a bus */  //hcd是一個usb總線  
  7.     struct kref     kref;       /* reference counter */ //引用計數  
  8.   
  9.     const char      *product_desc;  /* product/vendor string */ //產品描述  
  10.     int         speed;      /* Speed for this roothub. 
  11.                          * May be different from 
  12.                          * hcd->driver->flags & HCD_MASK 
  13.                          */  
  14.     char            irq_descr[24];  /* driver + bus # */  
  15.   
  16.     struct timer_list   rh_timer;   /* drives root-hub polling */   //root hub輪詢定時器  
  17.     struct urb      *status_urb;    /* the current status urb */  
  18. #ifdef CONFIG_USB_SUSPEND  
  19.     struct work_struct  wakeup_work;    /* for remote wakeup */  
  20. #endif  
  21.   
  22.     /* 
  23.      * hardware info/state 
  24.      */  
  25.     const struct hc_driver  *driver;    /* hw-specific hooks */ //hc驅動  
  26.   
  27.     /* Flags that need to be manipulated atomically because they can 
  28.      * change while the host controller is running.  Always use 
  29.      * set_bit() or clear_bit() to change their values. 
  30.      */  
  31.     unsigned long       flags;  
  32. #define HCD_FLAG_HW_ACCESSIBLE      0   /* at full power */  
  33. #define HCD_FLAG_SAW_IRQ        1  
  34. #define HCD_FLAG_POLL_RH        2   /* poll for rh status? */  
  35. #define HCD_FLAG_POLL_PENDING       3   /* status has changed? */  
  36. #define HCD_FLAG_WAKEUP_PENDING     4   /* root hub is resuming? */  
  37. #define HCD_FLAG_RH_RUNNING     5   /* root hub is running? */  
  38. #define HCD_FLAG_DEAD           6   /* controller has died? */  
  39.   
  40.     /* The flags can be tested using these macros; they are likely to 
  41.      * be slightly faster than test_bit(). 
  42.      */  
  43. #define HCD_HW_ACCESSIBLE(hcd)  ((hcd)->flags & (1U << HCD_FLAG_HW_ACCESSIBLE))  
  44. #define HCD_SAW_IRQ(hcd)    ((hcd)->flags & (1U << HCD_FLAG_SAW_IRQ))  
  45. #define HCD_POLL_RH(hcd)    ((hcd)->flags & (1U << HCD_FLAG_POLL_RH))  
  46. #define HCD_POLL_PENDING(hcd)   ((hcd)->flags & (1U << HCD_FLAG_POLL_PENDING))  
  47. #define HCD_WAKEUP_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING))  
  48. #define HCD_RH_RUNNING(hcd) ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING))  
  49. #define HCD_DEAD(hcd)       ((hcd)->flags & (1U << HCD_FLAG_DEAD))  
  50.   
  51.     /* Flags that get set only during HCD registration or removal. */  
  52.     unsigned        rh_registered:1;/* is root hub registered? */  
  53.     unsigned        rh_pollable:1;  /* may we poll the root hub? */  
  54.     unsigned        msix_enabled:1; /* driver has MSI-X enabled? */  
  55.   
  56.     /* The next flag is a stopgap, to be removed when all the HCDs 
  57.      * support the new root-hub polling mechanism. */  
  58.     unsigned        uses_new_polling:1;  
  59.     unsigned        wireless:1; /* Wireless USB HCD */  
  60.     unsigned        authorized_default:1;  
  61.     unsigned        has_tt:1;   /* Integrated TT in root hub */  
  62.   
  63.     int         irq;        /* irq allocated */  
  64.     void __iomem        *regs;      /* device memory/io */  
  65.     u64         rsrc_start; /* memory/io resource start */  
  66.     u64         rsrc_len;   /* memory/io resource length */  
  67.     unsigned        power_budget;   /* in mA, 0 = no limit */  
  68.   
  69.     /* bandwidth_mutex should be taken before adding or removing 
  70.      * any new bus bandwidth constraints: 
  71.      *   1. Before adding a configuration for a new device. 
  72.      *   2. Before removing the configuration to put the device into 
  73.      *      the addressed state. 
  74.      *   3. Before selecting a different configuration. 
  75.      *   4. Before selecting an alternate interface setting. 
  76.      * 
  77.      * bandwidth_mutex should be dropped after a successful control message 
  78.      * to the device, or resetting the bandwidth after a failed attempt. 
  79.      */  
  80.     struct mutex        *bandwidth_mutex;  
  81.     struct usb_hcd      *shared_hcd;  
  82.     struct usb_hcd      *primary_hcd;  
  83.   
  84.   
  85. #define HCD_BUFFER_POOLS    4  
  86.     struct dma_pool     *pool[HCD_BUFFER_POOLS];  
  87.   
  88.     int         state;  
  89. #   define  __ACTIVE        0x01  
  90. #   define  __SUSPEND       0x04  
  91. #   define  __TRANSIENT     0x80  
  92.   
  93. #   define  HC_STATE_HALT       0  
  94. #   define  HC_STATE_RUNNING    (__ACTIVE)  
  95. #   define  HC_STATE_QUIESCING  (__SUSPEND|__TRANSIENT|__ACTIVE)  
  96. #   define  HC_STATE_RESUMING   (__SUSPEND|__TRANSIENT)  
  97. #   define  HC_STATE_SUSPENDED  (__SUSPEND)  
  98.   
  99. #define HC_IS_RUNNING(state) ((state) & __ACTIVE)  
  100. #define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)  
  101.   
  102.     /* more shared queuing code would be good; it should support 
  103.      * smarter scheduling, handle transaction translators, etc; 
  104.      * input size of periodic table to an interrupt scheduler. 
  105.      * (ohci 32, uhci 1024, ehci 256/512/1024). 
  106.      */  
  107.   
  108.     /* The HC driver's private data is stored at the end of 
  109.      * this structure. 
  110.      */  
  111.     unsigned long hcd_priv[0]  
  112.             __attribute__ ((aligned(sizeof(unsigned long))));  
  113. };  
struct usb_hcd {

	/*
	 * housekeeping
	 */
	struct usb_bus		self;		/* hcd is-a bus */	//hcd是一個usb總線
	struct kref		kref;		/* reference counter */	//引用計數

	const char		*product_desc;	/* product/vendor string */	//產品描述
	int			speed;		/* Speed for this roothub.
						 * May be different from
						 * hcd->driver->flags & HCD_MASK
						 */
	char			irq_descr[24];	/* driver + bus # */

	struct timer_list	rh_timer;	/* drives root-hub polling */	//root hub輪詢定時器
	struct urb		*status_urb;	/* the current status urb */
#ifdef CONFIG_USB_SUSPEND
	struct work_struct	wakeup_work;	/* for remote wakeup */
#endif

	/*
	 * hardware info/state
	 */
	const struct hc_driver	*driver;	/* hw-specific hooks */ //hc驅動

	/* Flags that need to be manipulated atomically because they can
	 * change while the host controller is running.  Always use
	 * set_bit() or clear_bit() to change their values.
	 */
	unsigned long		flags;
#define HCD_FLAG_HW_ACCESSIBLE		0	/* at full power */
#define HCD_FLAG_SAW_IRQ		1
#define HCD_FLAG_POLL_RH		2	/* poll for rh status? */
#define HCD_FLAG_POLL_PENDING		3	/* status has changed? */
#define HCD_FLAG_WAKEUP_PENDING		4	/* root hub is resuming? */
#define HCD_FLAG_RH_RUNNING		5	/* root hub is running? */
#define HCD_FLAG_DEAD			6	/* controller has died? */

	/* The flags can be tested using these macros; they are likely to
	 * be slightly faster than test_bit().
	 */
#define HCD_HW_ACCESSIBLE(hcd)	((hcd)->flags & (1U << HCD_FLAG_HW_ACCESSIBLE))
#define HCD_SAW_IRQ(hcd)	((hcd)->flags & (1U << HCD_FLAG_SAW_IRQ))
#define HCD_POLL_RH(hcd)	((hcd)->flags & (1U << HCD_FLAG_POLL_RH))
#define HCD_POLL_PENDING(hcd)	((hcd)->flags & (1U << HCD_FLAG_POLL_PENDING))
#define HCD_WAKEUP_PENDING(hcd)	((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING))
#define HCD_RH_RUNNING(hcd)	((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING))
#define HCD_DEAD(hcd)		((hcd)->flags & (1U << HCD_FLAG_DEAD))

	/* Flags that get set only during HCD registration or removal. */
	unsigned		rh_registered:1;/* is root hub registered? */
	unsigned		rh_pollable:1;	/* may we poll the root hub? */
	unsigned		msix_enabled:1;	/* driver has MSI-X enabled? */

	/* The next flag is a stopgap, to be removed when all the HCDs
	 * support the new root-hub polling mechanism. */
	unsigned		uses_new_polling:1;
	unsigned		wireless:1;	/* Wireless USB HCD */
	unsigned		authorized_default:1;
	unsigned		has_tt:1;	/* Integrated TT in root hub */

	int			irq;		/* irq allocated */
	void __iomem		*regs;		/* device memory/io */
	u64			rsrc_start;	/* memory/io resource start */
	u64			rsrc_len;	/* memory/io resource length */
	unsigned		power_budget;	/* in mA, 0 = no limit */

	/* 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		*bandwidth_mutex;
	struct usb_hcd		*shared_hcd;
	struct usb_hcd		*primary_hcd;


#define HCD_BUFFER_POOLS	4
	struct dma_pool		*pool[HCD_BUFFER_POOLS];

	int			state;
#	define	__ACTIVE		0x01
#	define	__SUSPEND		0x04
#	define	__TRANSIENT		0x80

#	define	HC_STATE_HALT		0
#	define	HC_STATE_RUNNING	(__ACTIVE)
#	define	HC_STATE_QUIESCING	(__SUSPEND|__TRANSIENT|__ACTIVE)
#	define	HC_STATE_RESUMING	(__SUSPEND|__TRANSIENT)
#	define	HC_STATE_SUSPENDED	(__SUSPEND)

#define	HC_IS_RUNNING(state) ((state) & __ACTIVE)
#define	HC_IS_SUSPENDED(state) ((state) & __SUSPEND)

	/* more shared queuing code would be good; it should support
	 * smarter scheduling, handle transaction translators, etc;
	 * input size of periodic table to an interrupt scheduler.
	 * (ohci 32, uhci 1024, ehci 256/512/1024).
	 */

	/* The HC driver's private data is stored at the end of
	 * this structure.
	 */
	unsigned long hcd_priv[0]
			__attribute__ ((aligned(sizeof(unsigned long))));
};
  1. struct hc_driver {  
  2.     const char  *description;   /* "ehci-hcd" etc */  
  3.     const char  *product_desc;  /* product/vendor string */  
  4.     size_t      hcd_priv_size;  /* size of private data */  
  5.   
  6.     /* irq handler */  
  7.     irqreturn_t (*irq) (struct usb_hcd *hcd);  
  8.   
  9.     int flags;  
  10. #define HCD_MEMORY  0x0001      /* HC regs use memory (else I/O) */  
  11. #define HCD_LOCAL_MEM   0x0002      /* HC needs local memory */  
  12. #define HCD_SHARED  0x0004      /* Two (or more) usb_hcds share HW */  
  13. #define HCD_USB11   0x0010      /* USB 1.1 */  
  14. #define HCD_USB2    0x0020      /* USB 2.0 */  
  15. #define HCD_USB3    0x0040      /* USB 3.0 */  
  16. #define HCD_MASK    0x0070  
  17.   
  18.     /* called to init HCD and root hub */  
  19.     int (*reset) (struct usb_hcd *hcd);  
  20.     int (*start) (struct usb_hcd *hcd);  
  21.   
  22.     /* NOTE:  these suspend/resume calls relate to the HC as 
  23.      * a whole, not just the root hub; they're for PCI bus glue. 
  24.      */  
  25.     /* called after suspending the hub, before entering D3 etc */  
  26.     int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup);  
  27.   
  28.     /* called after entering D0 (etc), before resuming the hub */  
  29.     int (*pci_resume)(struct usb_hcd *hcd, bool hibernated);  
  30.   
  31.     /* cleanly make HCD stop writing memory and doing I/O */  
  32.     void    (*stop) (struct usb_hcd *hcd);  
  33.   
  34.     /* shutdown HCD */  
  35.     void    (*shutdown) (struct usb_hcd *hcd);  
  36.   
  37.     /* return current frame number */  
  38.     int (*get_frame_number) (struct usb_hcd *hcd);  
  39.   
  40.     /* manage i/o requests, device state */  
  41.     int (*urb_enqueue)(struct usb_hcd *hcd,  
  42.                 struct urb *urb, gfp_t mem_flags);  
  43.     int (*urb_dequeue)(struct usb_hcd *hcd,  
  44.                 struct urb *urb, int status);  
  45.   
  46.     /* 
  47.      * (optional) these hooks allow an HCD to override the default DMA 
  48.      * mapping and unmapping routines.  In general, they shouldn't be 
  49.      * necessary unless the host controller has special DMA requirements, 
  50.      * such as alignment contraints.  If these are not specified, the 
  51.      * general usb_hcd_(un)?map_urb_for_dma functions will be used instead 
  52.      * (and it may be a good idea to call these functions in your HCD 
  53.      * implementation) 
  54.      */  
  55.     int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb,  
  56.                    gfp_t mem_flags);  
  57.     void    (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb);  
  58.   
  59.     /* hw synch, freeing endpoint resources that urb_dequeue can't */  
  60.     void    (*endpoint_disable)(struct usb_hcd *hcd,  
  61.             struct usb_host_endpoint *ep);  
  62.   
  63.     /* (optional) reset any endpoint state such as sequence number 
  64.        and current window */  
  65.     void    (*endpoint_reset)(struct usb_hcd *hcd,  
  66.             struct usb_host_endpoint *ep);  
  67.   
  68.     /* root hub support */  
  69.     int (*hub_status_data) (struct usb_hcd *hcd, char *buf);  
  70.     int (*hub_control) (struct usb_hcd *hcd,  
  71.                 u16 typeReq, u16 wValue, u16 wIndex,  
  72.                 char *buf, u16 wLength);  
  73.     int (*bus_suspend)(struct usb_hcd *);  
  74.     int (*bus_resume)(struct usb_hcd *);  
  75.     int (*start_port_reset)(struct usb_hcd *, unsigned port_num);  
  76.   
  77.         /* force handover of high-speed port to full-speed companion */  
  78.     void    (*relinquish_port)(struct usb_hcd *, int);  
  79.         /* has a port been handed over to a companion? */  
  80.     int (*port_handed_over)(struct usb_hcd *, int);  
  81.   
  82.         /* CLEAR_TT_BUFFER completion callback */  
  83.     void    (*clear_tt_buffer_complete)(struct usb_hcd *,  
  84.                 struct usb_host_endpoint *);  
  85.   
  86.     /* xHCI specific functions */  
  87.         /* Called by usb_alloc_dev to alloc HC device structures */  
  88.     int (*alloc_dev)(struct usb_hcd *, struct usb_device *);  
  89.         /* Called by usb_disconnect to free HC device structures */  
  90.     void    (*free_dev)(struct usb_hcd *, struct usb_device *);  
  91.     /* Change a group of bulk endpoints to support multiple stream IDs */  
  92.     int (*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev,  
  93.         struct usb_host_endpoint **eps, unsigned int num_eps,  
  94.         unsigned int num_streams, gfp_t mem_flags);  
  95.     /* Reverts a group of bulk endpoints back to not using stream IDs. 
  96.      * Can fail if we run out of memory. 
  97.      */  
  98.     int (*free_streams)(struct usb_hcd *hcd, struct usb_device *udev,  
  99.         struct usb_host_endpoint **eps, unsigned int num_eps,  
  100.         gfp_t mem_flags);  
  101.   
  102.     /* Bandwidth computation functions */  
  103.     /* Note that add_endpoint() can only be called once per endpoint before 
  104.      * check_bandwidth() or reset_bandwidth() must be called. 
  105.      * drop_endpoint() can only be called once per endpoint also. 
  106.      * A call to xhci_drop_endpoint() followed by a call to 
  107.      * xhci_add_endpoint() will add the endpoint to the schedule with 
  108.      * possibly new parameters denoted by a different endpoint descriptor 
  109.      * in usb_host_endpoint.  A call to xhci_add_endpoint() followed by a 
  110.      * call to xhci_drop_endpoint() is not allowed. 
  111.      */  
  112.         /* Allocate endpoint resources and add them to a new schedule */  
  113.     int (*add_endpoint)(struct usb_hcd *, struct usb_device *,  
  114.                 struct usb_host_endpoint *);  
  115.         /* Drop an endpoint from a new schedule */  
  116.     int (*drop_endpoint)(struct usb_hcd *, struct usb_device *,  
  117.                  struct usb_host_endpoint *);  
  118.         /* Check that a new hardware configuration, set using 
  119.          * endpoint_enable and endpoint_disable, does not exceed bus 
  120.          * bandwidth.  This must be called before any set configuration 
  121.          * or set interface requests are sent to the device. 
  122.          */  
  123.     int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);  
  124.         /* Reset the device schedule to the last known good schedule, 
  125.          * which was set from a previous successful call to 
  126.          * check_bandwidth().  This reverts any add_endpoint() and 
  127.          * drop_endpoint() calls since that last successful call. 
  128.          * Used for when a check_bandwidth() call fails due to resource 
  129.          * or bandwidth constraints. 
  130.          */  
  131.     void    (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);  
  132.         /* Returns the hardware-chosen device address */  
  133.     int (*address_device)(struct usb_hcd *, struct usb_device *udev);  
  134.         /* Notifies the HCD after a hub descriptor is fetched. 
  135.          * Will block. 
  136.          */  
  137.     int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev,  
  138.             struct usb_tt *tt, gfp_t mem_flags);  
  139.     int (*reset_device)(struct usb_hcd *, struct usb_device *);  
  140.         /* Notifies the HCD after a device is connected and its 
  141.          * address is set 
  142.          */  
  143.     int (*update_device)(struct usb_hcd *, struct usb_device *);  
  144. };  
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);

	int	flags;
#define	HCD_MEMORY	0x0001		/* HC regs use memory (else I/O) */
#define	HCD_LOCAL_MEM	0x0002		/* HC needs local memory */
#define	HCD_SHARED	0x0004		/* Two (or more) usb_hcds share HW */
#define	HCD_USB11	0x0010		/* USB 1.1 */
#define	HCD_USB2	0x0020		/* USB 2.0 */
#define	HCD_USB3	0x0040		/* USB 3.0 */
#define	HCD_MASK	0x0070

	/* 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; they're 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 shouldn't 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 can't */
	void	(*endpoint_disable)(struct usb_hcd *hcd,
			struct usb_host_endpoint *ep);

	/* (optional) reset any endpoint state such as sequence number
	   and 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);

		/* 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);
		/* 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 *);
};
  1. struct usb_bus {  
  2.     struct device *controller;  /* host/master side hardware */ //主機控制器端的device結構  
  3.     int busnum;         /* Bus number (in order of reg) */  //總線編號  
  4.     const char *bus_name;       /* stable id (PCI slot_name etc) */ //總線名字  
  5.     u8 uses_dma;            /* Does the host controller use DMA? */  
  6.     u8 uses_pio_for_control;    /* 
  7.                      * Does the host controller use PIO 
  8.                      * for control transfers? 
  9.                      */  
  10.     u8 otg_port;            /* 0, or number of OTG/HNP port */  
  11.     unsigned is_b_host:1;       /* true during some HNP roleswitches */  
  12.     unsigned b_hnp_enable:1;    /* OTG: did A-Host enable HNP? */  
  13.     unsigned sg_tablesize;      /* 0 or largest number of sg list entries */  
  14.   
  15.     int devnum_next;        /* Next open device number in 
  16.                      * round-robin allocation */  
  17.   
  18.     struct usb_devmap devmap;   /* device address allocation map */  
  19.     struct usb_device *root_hub;    /* Root hub */  //指向根hub  
  20.     struct usb_bus *hs_companion;   /* Companion EHCI bus, if any */  
  21.     struct list_head bus_list;  /* list of busses */    //鏈接到所有的ub總線的連接件  
  22.   
  23.     int bandwidth_allocated;    /* on this bus: how much of the time 
  24.                      * reserved for periodic (intr/iso) 
  25.                      * requests is used, on average? 
  26.                      * Units: microseconds/frame. 
  27.                      * Limits: Full/low speed reserve 90%, 
  28.                      * while high speed reserves 80%. 
  29.                      */  
  30.     int bandwidth_int_reqs;     /* number of Interrupt requests */  //中斷傳輸的數量  
  31.     int bandwidth_isoc_reqs;    /* number of Isoc. requests */  //等時傳輸的數量  
  32.   
  33. #ifdef CONFIG_USB_DEVICEFS  
  34.     struct dentry *usbfs_dentry;    /* usbfs dentry entry for the bus */  
  35. #endif  
  36.   
  37. #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)  
  38.     struct mon_bus *mon_bus;    /* non-null when associated */  
  39.     int monitored;          /* non-zero when monitored */  
  40. #endif  
  41. };  
struct usb_bus {
	struct device *controller;	/* host/master side hardware */	//主機控制器端的device結構
	int busnum;			/* Bus number (in order of reg) */	//總線編號
	const char *bus_name;		/* stable id (PCI slot_name etc) */	//總線名字
	u8 uses_dma;			/* Does the host controller use DMA? */
	u8 uses_pio_for_control;	/*
					 * Does the host controller use PIO
					 * for control transfers?
					 */
	u8 otg_port;			/* 0, or number of OTG/HNP port */
	unsigned is_b_host:1;		/* true during some HNP roleswitches */
	unsigned b_hnp_enable:1;	/* OTG: did A-Host enable HNP? */
	unsigned sg_tablesize;		/* 0 or largest number of sg list entries */

	int devnum_next;		/* Next open device number in
					 * round-robin allocation */

	struct usb_devmap devmap;	/* device address allocation map */
	struct usb_device *root_hub;	/* Root hub */	//指向根hub
	struct usb_bus *hs_companion;	/* Companion EHCI bus, if any */
	struct list_head bus_list;	/* list of busses */	//鏈接到所有的ub總線的連接件

	int bandwidth_allocated;	/* on this bus: how much of the time
					 * reserved for periodic (intr/iso)
					 * requests is used, on average?
					 * Units: microseconds/frame.
					 * Limits: Full/low speed reserve 90%,
					 * while high speed reserves 80%.
					 */
	int bandwidth_int_reqs;		/* number of Interrupt requests */	//中斷傳輸的數量
	int bandwidth_isoc_reqs;	/* number of Isoc. requests */	//等時傳輸的數量

#ifdef CONFIG_USB_DEVICEFS
	struct dentry *usbfs_dentry;	/* usbfs dentry entry for the bus */
#endif

#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
	struct mon_bus *mon_bus;	/* non-null when associated */
	int monitored;			/* non-zero when monitored */
#endif
};

2. usb框架的初始化

  1. static int __init usb_init(void)  
  2. {  
  3.     int retval;  
  4.     if (nousb) {  
  5.         pr_info("%s: USB support disabled\n", usbcore_name);  
  6.         return 0;  
  7.     }  
  8.   
  9.     retval = usb_debugfs_init();    //usb debugfs初始化  
  10.     if (retval)  
  11.         goto out;  
  12.   
  13.     retval = bus_register(&usb_bus_type);   //註冊usb 總線  
  14.     if (retval)  
  15.         goto bus_register_failed;  
  16.     retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb); //註冊usb總線的通知塊  
  17.     if (retval)  
  18.         goto bus_notifier_failed;  
  19.     retval = usb_major_init();  //註冊主設備號爲180的usb字符設備  
  20.     if (retval)  
  21.         goto major_init_failed;  
  22.     retval = usb_register(&usbfs_driver);   //註冊一個usb_driver usbfs_driver  
  23.     if (retval)  
  24.         goto driver_register_failed;  
  25.     retval = usb_devio_init();  //註冊主設備號爲189,次設備數爲64*128  
  26.     if (retval)  
  27.         goto usb_devio_init_failed;  
  28.     retval = usbfs_init();  //註冊usb_fs_type文件系統  
  29.     if (retval)  
  30.         goto fs_init_failed;  
  31.     retval = usb_hub_init();    //註冊hub_driver,創建khub內核線程  
  32.     if (retval)  
  33.         goto hub_init_failed;  
  34.     retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);  //註冊usb系統唯一的usb_device_driver usb_generic_driver  
  35.     if (!retval)  
  36.         goto out;  
  37.   
  38.     usb_hub_cleanup();  
  39. hub_init_failed:  
  40.     usbfs_cleanup();  
  41. fs_init_failed:  
  42.     usb_devio_cleanup();  
  43. usb_devio_init_failed:  
  44.     usb_deregister(&usbfs_driver);  
  45. driver_register_failed:  
  46.     usb_major_cleanup();  
  47. major_init_failed:  
  48.     bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);  
  49. bus_notifier_failed:  
  50.     bus_unregister(&usb_bus_type);  
  51. bus_register_failed:  
  52.     usb_debugfs_cleanup();  
  53. out:  
  54.     return retval;  
  55. }  
static int __init usb_init(void)
{
	int retval;
	if (nousb) {
		pr_info("%s: USB support disabled\n", usbcore_name);
		return 0;
	}

	retval = usb_debugfs_init();	//usb debugfs初始化
	if (retval)
		goto out;

	retval = bus_register(&usb_bus_type);	//註冊usb 總線
	if (retval)
		goto bus_register_failed;
	retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb);	//註冊usb總線的通知塊
	if (retval)
		goto bus_notifier_failed;
	retval = usb_major_init();	//註冊主設備號爲180的usb字符設備
	if (retval)
		goto major_init_failed;
	retval = usb_register(&usbfs_driver);	//註冊一個usb_driver usbfs_driver
	if (retval)
		goto driver_register_failed;
	retval = usb_devio_init();	//註冊主設備號爲189,次設備數爲64*128
	if (retval)
		goto usb_devio_init_failed;
	retval = usbfs_init();	//註冊usb_fs_type文件系統
	if (retval)
		goto fs_init_failed;
	retval = usb_hub_init();	//註冊hub_driver,創建khub內核線程
	if (retval)
		goto hub_init_failed;
	retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);	//註冊usb系統唯一的usb_device_driver usb_generic_driver
	if (!retval)
		goto out;

	usb_hub_cleanup();
hub_init_failed:
	usbfs_cleanup();
fs_init_failed:
	usb_devio_cleanup();
usb_devio_init_failed:
	usb_deregister(&usbfs_driver);
driver_register_failed:
	usb_major_cleanup();
major_init_failed:
	bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
bus_notifier_failed:
	bus_unregister(&usb_bus_type);
bus_register_failed:
	usb_debugfs_cleanup();
out:
	return retval;
}
  1. static int usb_debugfs_init(void)  
  2. {  
  3.     usb_debug_root = debugfs_create_dir("usb", NULL);  
  4.     if (!usb_debug_root)  
  5.         return -ENOENT;  
  6.   
  7.     usb_debug_devices = debugfs_create_file("devices", 0444,  
  8.                         usb_debug_root, NULL,  
  9.                         &usbfs_devices_fops);  
  10.     if (!usb_debug_devices) {  
  11.         debugfs_remove(usb_debug_root);  
  12.         usb_debug_root = NULL;  
  13.         return -ENOENT;  
  14.     }  
  15.   
  16.     return 0;  
  17. }  
static int usb_debugfs_init(void)
{
	usb_debug_root = debugfs_create_dir("usb", NULL);
	if (!usb_debug_root)
		return -ENOENT;

	usb_debug_devices = debugfs_create_file("devices", 0444,
						usb_debug_root, NULL,
						&usbfs_devices_fops);
	if (!usb_debug_devices) {
		debugfs_remove(usb_debug_root);
		usb_debug_root = NULL;
		return -ENOENT;
	}

	return 0;
}
  1. int usb_major_init(void)  
  2. {  
  3.     int error;  
  4.   
  5.     error = register_chrdev(USB_MAJOR, "usb", &usb_fops);  
  6.     if (error)  
  7.         printk(KERN_ERR "Unable to get major %d for usb devices\n",  
  8.                USB_MAJOR);  
  9.   
  10.     return error;  
  11. }  
int usb_major_init(void)
{
	int error;

	error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
	if (error)
		printk(KERN_ERR "Unable to get major %d for usb devices\n",
		       USB_MAJOR);

	return error;
}
  1. int __init usb_devio_init(void)  
  2. {  
  3.     int retval;  
  4.   
  5.     retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,  
  6.                     "usb_device");  
  7.     if (retval) {  
  8.         printk(KERN_ERR "Unable to register minors for usb_device\n");  
  9.         goto out;  
  10.     }  
  11.     cdev_init(&usb_device_cdev, &usbdev_file_operations);  
  12.     retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);  
  13.     if (retval) {  
  14.         printk(KERN_ERR "Unable to get usb_device major %d\n",  
  15.                USB_DEVICE_MAJOR);  
  16.         goto error_cdev;  
  17.     }  
  18. #ifdef CONFIG_USB_DEVICE_CLASS  
  19.     usb_classdev_class = class_create(THIS_MODULE, "usb_device");  
  20.     if (IS_ERR(usb_classdev_class)) {  
  21.         printk(KERN_ERR "Unable to register usb_device class\n");  
  22.         retval = PTR_ERR(usb_classdev_class);  
  23.         cdev_del(&usb_device_cdev);  
  24.         usb_classdev_class = NULL;  
  25.         goto out;  
  26.     }  
  27.     /* devices of this class shadow the major:minor of their parent 
  28.      * device, so clear ->dev_kobj to prevent adding duplicate entries 
  29.      * to /sys/dev 
  30.      */  
  31.     usb_classdev_class->dev_kobj = NULL;  
  32. #endif  
  33.     usb_register_notify(&usbdev_nb);  
  34. out:  
  35.     return retval;  
  36.   
  37. error_cdev:  
  38.     unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);  
  39.     goto out;  
  40. }  
int __init usb_devio_init(void)
{
	int retval;

	retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
					"usb_device");
	if (retval) {
		printk(KERN_ERR "Unable to register minors for usb_device\n");
		goto out;
	}
	cdev_init(&usb_device_cdev, &usbdev_file_operations);
	retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
	if (retval) {
		printk(KERN_ERR "Unable to get usb_device major %d\n",
		       USB_DEVICE_MAJOR);
		goto error_cdev;
	}
#ifdef CONFIG_USB_DEVICE_CLASS
	usb_classdev_class = class_create(THIS_MODULE, "usb_device");
	if (IS_ERR(usb_classdev_class)) {
		printk(KERN_ERR "Unable to register usb_device class\n");
		retval = PTR_ERR(usb_classdev_class);
		cdev_del(&usb_device_cdev);
		usb_classdev_class = NULL;
		goto out;
	}
	/* devices of this class shadow the major:minor of their parent
	 * device, so clear ->dev_kobj to prevent adding duplicate entries
	 * to /sys/dev
	 */
	usb_classdev_class->dev_kobj = NULL;
#endif
	usb_register_notify(&usbdev_nb);
out:
	return retval;

error_cdev:
	unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
	goto out;
}
  1. int usb_hub_init(void)  
  2. {  
  3.     if (usb_register(&hub_driver) < 0) {  
  4.         printk(KERN_ERR "%s: can't register hub driver\n",  
  5.             usbcore_name);  
  6.         return -1;  
  7.     }  
  8.   
  9.     khubd_task = kthread_run(hub_thread, NULL, "khubd");  
  10.     if (!IS_ERR(khubd_task))  
  11.         return 0;  
  12.   
  13.     /* Fall through if kernel_thread failed */  
  14.     usb_deregister(&hub_driver);  
  15.     printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);  
  16.   
  17.     return -1;  
  18. }  
int usb_hub_init(void)
{
	if (usb_register(&hub_driver) < 0) {
		printk(KERN_ERR "%s: can't register hub driver\n",
			usbcore_name);
		return -1;
	}

	khubd_task = kthread_run(hub_thread, NULL, "khubd");
	if (!IS_ERR(khubd_task))
		return 0;

	/* Fall through if kernel_thread failed */
	usb_deregister(&hub_driver);
	printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);

	return -1;
}
  1. int usb_register_device_driver(struct usb_device_driver *new_udriver,  
  2.         struct module *owner)  
  3. {  
  4.     int retval = 0;  
  5.   
  6.     if (usb_disabled())  
  7.         return -ENODEV;  
  8.   
  9.     new_udriver->drvwrap.for_devices = 1;  
  10.     new_udriver->drvwrap.driver.name = (char *) new_udriver->name;  
  11.     new_udriver->drvwrap.driver.bus = &usb_bus_type;  
  12.     new_udriver->drvwrap.driver.probe = usb_probe_device;  
  13.     new_udriver->drvwrap.driver.remove = usb_unbind_device;  
  14.     new_udriver->drvwrap.driver.owner = owner;  
  15.   
  16.     retval = driver_register(&new_udriver->drvwrap.driver);  
  17.   
  18.     if (!retval) {  
  19.         pr_info("%s: registered new device driver %s\n",  
  20.             usbcore_name, new_udriver->name);  
  21.         usbfs_update_special();  
  22.     } else {  
  23.         printk(KERN_ERR "%s: error %d registering device "  
  24.             "   driver %s\n",  
  25.             usbcore_name, retval, new_udriver->name);  
  26.     }  
  27.   
  28.     return retval;  
  29. }  
int usb_register_device_driver(struct usb_device_driver *new_udriver,
		struct module *owner)
{
	int retval = 0;

	if (usb_disabled())
		return -ENODEV;

	new_udriver->drvwrap.for_devices = 1;
	new_udriver->drvwrap.driver.name = (char *) new_udriver->name;
	new_udriver->drvwrap.driver.bus = &usb_bus_type;
	new_udriver->drvwrap.driver.probe = usb_probe_device;
	new_udriver->drvwrap.driver.remove = usb_unbind_device;
	new_udriver->drvwrap.driver.owner = owner;

	retval = driver_register(&new_udriver->drvwrap.driver);

	if (!retval) {
		pr_info("%s: registered new device driver %s\n",
			usbcore_name, new_udriver->name);
		usbfs_update_special();
	} else {
		printk(KERN_ERR "%s: error %d registering device "
			"	driver %s\n",
			usbcore_name, retval, new_udriver->name);
	}

	return retval;
}

發佈了3 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章