USB驅動框架分析2

本文先分析OHCI的usb主機驅動控制器驅動,root hub這個usb_device的創建過程,讀取配置描述符過程,設置配置,然後添加接口到系統。

1. 先看下數據結構

  1. struct ohci_hcd {  
  2.     spinlock_t      lock;  
  3.   
  4.     /* 
  5.      * I/O memory used to communicate with the HC (dma-consistent) 
  6.      */  
  7.     struct ohci_regs __iomem *regs; //與主機控制器通信的IO內存  
  8.   
  9.     /* 
  10.      * main memory used to communicate with the HC (dma-consistent). 
  11.      * hcd adds to schedule for a live hc any time, but removals finish 
  12.      * only at the start of the next frame. 
  13.      */  
  14.     struct ohci_hcca    *hcca;  
  15.     dma_addr_t      hcca_dma;  
  16.   
  17.     struct ed       *ed_rm_list;        /* to be removed */ //指向被移除的OHCI端點  
  18.   
  19.     struct ed       *ed_bulktail;       /* last in bulk list */ //批量隊列尾  
  20.     struct ed       *ed_controltail;    /* last in ctrl list */ //控制隊列尾  
  21.     struct ed       *periodic [NUM_INTS];   /* shadow int_table */  
  22.   
  23.     /* 
  24.      * OTG controllers and transceivers need software interaction; 
  25.      * other external transceivers should be software-transparent 
  26.      */  
  27.     struct otg_transceiver  *transceiver;  
  28.     void (*start_hnp)(struct ohci_hcd *ohci);  
  29.   
  30.     /* 
  31.      * memory management for queue data structures 
  32.      */  
  33.     struct dma_pool     *td_cache;    
  34.     struct dma_pool     *ed_cache;  
  35.     struct td       *td_hash [TD_HASH_SIZE];  
  36.     struct list_head    pending;  
  37.   
  38.     /* 
  39.      * driver state 
  40.      */  
  41.     int         num_ports;  
  42.     int         load [NUM_INTS];  
  43.     u32         hc_control; /* copy of hc control reg */  
  44.     unsigned long       next_statechange;   /* suspend/resume */  
  45.     u32         fminterval;     /* saved register */  
  46.     unsigned        autostop:1; /* rh auto stopping/stopped */  
  47.   
  48.     unsigned long       flags;      /* for HC bugs */  
  49. #define OHCI_QUIRK_AMD756   0x01            /* erratum #4 */  
  50. #define OHCI_QUIRK_SUPERIO  0x02            /* natsemi */  
  51. #define OHCI_QUIRK_INITRESET    0x04            /* SiS, OPTi, ... */  
  52. #define OHCI_QUIRK_BE_DESC  0x08            /* BE descriptors */  
  53. #define OHCI_QUIRK_BE_MMIO  0x10            /* BE registers */  
  54. #define OHCI_QUIRK_ZFMICRO  0x20            /* Compaq ZFMicro chipset*/  
  55. #define OHCI_QUIRK_NEC      0x40            /* lost interrupts */  
  56. #define OHCI_QUIRK_FRAME_NO 0x80            /* no big endian frame_no shift */  
  57. #define OHCI_QUIRK_HUB_POWER    0x100           /* distrust firmware power/oc setup */  
  58. #define OHCI_QUIRK_AMD_PLL  0x200           /* AMD PLL quirk*/  
  59. #define OHCI_QUIRK_AMD_PREFETCH 0x400           /* pre-fetch for ISO transfer */  
  60. #define OHCI_QUIRK_SHUTDOWN 0x800           /* nVidia power bug */  
  61.     // there are also chip quirks/bugs in init logic  
  62.   
  63.     struct work_struct  nec_work;   /* Worker for NEC quirk */  
  64.   
  65.     /* Needed for ZF Micro quirk */  
  66.     struct timer_list   unlink_watchdog;  
  67.     unsigned        eds_scheduled;  
  68.     struct ed       *ed_to_check;  
  69.     unsigned        zf_delay;  
  70.   
  71. #ifdef DEBUG  
  72.     struct dentry       *debug_dir;  
  73.     struct dentry       *debug_async;  
  74.     struct dentry       *debug_periodic;  
  75.     struct dentry       *debug_registers;  
  76. #endif  
  77. };  
struct ohci_hcd {
	spinlock_t		lock;

	/*
	 * I/O memory used to communicate with the HC (dma-consistent)
	 */
	struct ohci_regs __iomem *regs;	//與主機控制器通信的IO內存

	/*
	 * main memory used to communicate with the HC (dma-consistent).
	 * hcd adds to schedule for a live hc any time, but removals finish
	 * only at the start of the next frame.
	 */
	struct ohci_hcca	*hcca;
	dma_addr_t		hcca_dma;

	struct ed		*ed_rm_list;		/* to be removed */	//指向被移除的OHCI端點

	struct ed		*ed_bulktail;		/* last in bulk list */	//批量隊列尾
	struct ed		*ed_controltail;	/* last in ctrl list */	//控制隊列尾
	struct ed		*periodic [NUM_INTS];	/* shadow int_table */

	/*
	 * OTG controllers and transceivers need software interaction;
	 * other external transceivers should be software-transparent
	 */
	struct otg_transceiver	*transceiver;
	void (*start_hnp)(struct ohci_hcd *ohci);

	/*
	 * memory management for queue data structures
	 */
	struct dma_pool		*td_cache;	
	struct dma_pool		*ed_cache;
	struct td		*td_hash [TD_HASH_SIZE];
	struct list_head	pending;

	/*
	 * driver state
	 */
	int			num_ports;
	int			load [NUM_INTS];
	u32			hc_control;	/* copy of hc control reg */
	unsigned long		next_statechange;	/* suspend/resume */
	u32			fminterval;		/* saved register */
	unsigned		autostop:1;	/* rh auto stopping/stopped */

	unsigned long		flags;		/* for HC bugs */
#define	OHCI_QUIRK_AMD756	0x01			/* erratum #4 */
#define	OHCI_QUIRK_SUPERIO	0x02			/* natsemi */
#define	OHCI_QUIRK_INITRESET	0x04			/* SiS, OPTi, ... */
#define	OHCI_QUIRK_BE_DESC	0x08			/* BE descriptors */
#define	OHCI_QUIRK_BE_MMIO	0x10			/* BE registers */
#define	OHCI_QUIRK_ZFMICRO	0x20			/* Compaq ZFMicro chipset*/
#define	OHCI_QUIRK_NEC		0x40			/* lost interrupts */
#define	OHCI_QUIRK_FRAME_NO	0x80			/* no big endian frame_no shift */
#define	OHCI_QUIRK_HUB_POWER	0x100			/* distrust firmware power/oc setup */
#define	OHCI_QUIRK_AMD_PLL	0x200			/* AMD PLL quirk*/
#define	OHCI_QUIRK_AMD_PREFETCH	0x400			/* pre-fetch for ISO transfer */
#define	OHCI_QUIRK_SHUTDOWN	0x800			/* nVidia power bug */
	// there are also chip quirks/bugs in init logic

	struct work_struct	nec_work;	/* Worker for NEC quirk */

	/* Needed for ZF Micro quirk */
	struct timer_list	unlink_watchdog;
	unsigned		eds_scheduled;
	struct ed		*ed_to_check;
	unsigned		zf_delay;

#ifdef DEBUG
	struct dentry		*debug_dir;
	struct dentry		*debug_async;
	struct dentry		*debug_periodic;
	struct dentry		*debug_registers;
#endif
};
直接看ohci_hcd_s3c2410_drv_probe

  1. static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,  
  2.                   struct platform_device *dev)  
  3. {  
  4.     struct usb_hcd *hcd = NULL;  
  5.     int retval;  
  6.   
  7.     s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); //配置端口1電源  
  8.     s3c2410_usb_set_power(dev->dev.platform_data, 2, 1); //配置端口2電源  
  9.   
  10.     hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");      //創建主機控制器  
  11.     if (hcd == NULL)  
  12.         return -ENOMEM;  
  13.   
  14.     hcd->rsrc_start = dev->resource[0].start; //io資源的開始地址  
  15.     hcd->rsrc_len    = resource_size(&dev->resource[0]);  //io資源的長度  
  16.   
  17.     if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {  
  18.         dev_err(&dev->dev, "request_mem_region failed\n");  
  19.         retval = -EBUSY;  
  20.         goto err_put;  
  21.     }  
  22.   
  23.     clk = clk_get(&dev->dev, "usb-host");    //獲取時鐘信息  
  24.     if (IS_ERR(clk)) {  
  25.         dev_err(&dev->dev, "cannot get usb-host clock\n");  
  26.         retval = PTR_ERR(clk);  
  27.         goto err_mem;  
  28.     }  
  29.   
  30.     usb_clk = clk_get(&dev->dev, "usb-bus-host");  
  31.     if (IS_ERR(usb_clk)) {  
  32.         dev_err(&dev->dev, "cannot get usb-bus-host clock\n");  
  33.         retval = PTR_ERR(usb_clk);  
  34.         goto err_clk;  
  35.     }  
  36.   
  37.     s3c2410_start_hc(dev, hcd);  
  38.     //將IO地址空間映射到內存的虛擬地址空間  
  39.     hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);  
  40.     if (!hcd->regs) {  
  41.         dev_err(&dev->dev, "ioremap failed\n");  
  42.         retval = -ENOMEM;  
  43.         goto err_ioremap;  
  44.     }  
  45.   
  46.     ohci_hcd_init(hcd_to_ohci(hcd));    //初始化主機控制器  
  47.   
  48.     retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);    //主機控制器的註冊  
  49.     if (retval != 0)  
  50.         goto err_ioremap;  
  51.   
  52.     return 0;  
  53.   
  54.  err_ioremap:  
  55.     s3c2410_stop_hc(dev);  
  56.     iounmap(hcd->regs);  
  57.     clk_put(usb_clk);  
  58.   
  59.  err_clk:  
  60.     clk_put(clk);  
  61.   
  62.  err_mem:  
  63.     release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  
  64.   
  65.  err_put:  
  66.     usb_put_hcd(hcd);  
  67.     return retval;  
  68. }  
static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
				  struct platform_device *dev)
{
	struct usb_hcd *hcd = NULL;
	int retval;

	s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);	//配置端口1電源
	s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);	//配置端口2電源

	hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");		//創建主機控制器
	if (hcd == NULL)
		return -ENOMEM;

	hcd->rsrc_start = dev->resource[0].start;	//io資源的開始地址
	hcd->rsrc_len	= resource_size(&dev->resource[0]);	//io資源的長度

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_err(&dev->dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err_put;
	}

	clk = clk_get(&dev->dev, "usb-host");	//獲取時鐘信息
	if (IS_ERR(clk)) {
		dev_err(&dev->dev, "cannot get usb-host clock\n");
		retval = PTR_ERR(clk);
		goto err_mem;
	}

	usb_clk = clk_get(&dev->dev, "usb-bus-host");
	if (IS_ERR(usb_clk)) {
		dev_err(&dev->dev, "cannot get usb-bus-host clock\n");
		retval = PTR_ERR(usb_clk);
		goto err_clk;
	}

	s3c2410_start_hc(dev, hcd);
	//將IO地址空間映射到內存的虛擬地址空間
	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&dev->dev, "ioremap failed\n");
		retval = -ENOMEM;
		goto err_ioremap;
	}

	ohci_hcd_init(hcd_to_ohci(hcd));	//初始化主機控制器

	retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);	//主機控制器的註冊
	if (retval != 0)
		goto err_ioremap;

	return 0;

 err_ioremap:
	s3c2410_stop_hc(dev);
	iounmap(hcd->regs);
	clk_put(usb_clk);

 err_clk:
	clk_put(clk);

 err_mem:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);

 err_put:
	usb_put_hcd(hcd);
	return retval;
}
可以看到主要有兩個core層的api接口usb_create_hcd和usb_add_hcd

  1. struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,  
  2.         struct device *dev, const char *bus_name,  
  3.         struct usb_hcd *primary_hcd)  
  4. {  
  5.     struct usb_hcd *hcd;  
  6.   
  7.     hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);  
  8.     if (!hcd) {  
  9.         dev_dbg (dev, "hcd alloc failed\n");  
  10.         return NULL;  
  11.     }  
  12.     if (primary_hcd == NULL) {  
  13.         hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),  
  14.                 GFP_KERNEL);  
  15.         if (!hcd->bandwidth_mutex) {  
  16.             kfree(hcd);  
  17.             dev_dbg(dev, "hcd bandwidth mutex alloc failed\n");  
  18.             return NULL;  
  19.         }  
  20.         mutex_init(hcd->bandwidth_mutex);  
  21.         dev_set_drvdata(dev, hcd);  
  22.     } else {  
  23.         hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex;  
  24.         hcd->primary_hcd = primary_hcd;  
  25.         primary_hcd->primary_hcd = primary_hcd;  
  26.         hcd->shared_hcd = primary_hcd;  
  27.         primary_hcd->shared_hcd = hcd;  
  28.     }  
  29.   
  30.     kref_init(&hcd->kref);  
  31.   
  32.     usb_bus_init(&hcd->self);  
  33.     hcd->self.controller = dev;  
  34.     hcd->self.bus_name = bus_name;  
  35.     hcd->self.uses_dma = (dev->dma_mask != NULL);  
  36.   
  37.     init_timer(&hcd->rh_timer);  
  38.     hcd->rh_timer.function = rh_timer_func;  
  39.     hcd->rh_timer.data = (unsigned long) hcd;  
  40. #ifdef CONFIG_USB_SUSPEND  
  41.     INIT_WORK(&hcd->wakeup_work, hcd_resume_work);  
  42. #endif  
  43.   
  44.     hcd->driver = driver;  
  45.     hcd->speed = driver->flags & HCD_MASK;  
  46.     hcd->product_desc = (driver->product_desc) ? driver->product_desc :  
  47.             "USB Host Controller";  
  48.     return hcd;  
  49. }  
struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
		struct device *dev, const char *bus_name,
		struct usb_hcd *primary_hcd)
{
	struct usb_hcd *hcd;

	hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);
	if (!hcd) {
		dev_dbg (dev, "hcd alloc failed\n");
		return NULL;
	}
	if (primary_hcd == NULL) {
		hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),
				GFP_KERNEL);
		if (!hcd->bandwidth_mutex) {
			kfree(hcd);
			dev_dbg(dev, "hcd bandwidth mutex alloc failed\n");
			return NULL;
		}
		mutex_init(hcd->bandwidth_mutex);
		dev_set_drvdata(dev, hcd);
	} else {
		hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex;
		hcd->primary_hcd = primary_hcd;
		primary_hcd->primary_hcd = primary_hcd;
		hcd->shared_hcd = primary_hcd;
		primary_hcd->shared_hcd = hcd;
	}

	kref_init(&hcd->kref);

	usb_bus_init(&hcd->self);
	hcd->self.controller = dev;
	hcd->self.bus_name = bus_name;
	hcd->self.uses_dma = (dev->dma_mask != NULL);

	init_timer(&hcd->rh_timer);
	hcd->rh_timer.function = rh_timer_func;
	hcd->rh_timer.data = (unsigned long) hcd;
#ifdef CONFIG_USB_SUSPEND
	INIT_WORK(&hcd->wakeup_work, hcd_resume_work);
#endif

	hcd->driver = driver;
	hcd->speed = driver->flags & HCD_MASK;
	hcd->product_desc = (driver->product_desc) ? driver->product_desc :
			"USB Host Controller";
	return hcd;
}
  1. int usb_add_hcd(struct usb_hcd *hcd,  
  2.         unsigned int irqnum, unsigned long irqflags)  
  3. {  
  4.     int retval;  
  5.     struct usb_device *rhdev;  
  6.   
  7.     dev_info(hcd->self.controller, "%s\n", hcd->product_desc);  
  8.   
  9.     /* Keep old behaviour if authorized_default is not in [0, 1]. */  
  10.     if (authorized_default < 0 || authorized_default > 1)  
  11.         hcd->authorized_default = hcd->wireless? 0 : 1;  
  12.     else  
  13.         hcd->authorized_default = authorized_default;  
  14.     set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);  
  15.   
  16.     /* HC is in reset state, but accessible.  Now do the one-time init, 
  17.      * bottom up so that hcds can customize the root hubs before khubd 
  18.      * starts talking to them.  (Note, bus id is assigned early too.) 
  19.      */  
  20.     if ((retval = hcd_buffer_create(hcd)) != 0) {   //初始化一個buffer池  
  21.         dev_dbg(hcd->self.controller, "pool alloc failed\n");  
  22.         return retval;  
  23.     }  
  24.   
  25.     if ((retval = usb_register_bus(&hcd->self)) < 0)  //註冊此總線  
  26.         goto err_register_bus;  
  27.   
  28.     if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {      //分配usb_device結構  
  29.         dev_err(hcd->self.controller, "unable to allocate root hub\n");  
  30.         retval = -ENOMEM;  
  31.         goto err_allocate_root_hub;  
  32.     }  
  33.     hcd->self.root_hub = rhdev;  
  34.   
  35.     switch (hcd->speed) {  
  36.     case HCD_USB11:  
  37.         rhdev->speed = USB_SPEED_FULL;  
  38.         break;  
  39.     case HCD_USB2:  
  40.         rhdev->speed = USB_SPEED_HIGH;  
  41.         break;  
  42.     case HCD_USB3:  
  43.         rhdev->speed = USB_SPEED_SUPER;  
  44.         break;  
  45.     default:  
  46.         retval = -EINVAL;  
  47.         goto err_set_rh_speed;  
  48.     }  
  49.   
  50.     /* wakeup flag init defaults to "everything works" for root hubs, 
  51.      * but drivers can override it in reset() if needed, along with 
  52.      * recording the overall controller's system wakeup capability. 
  53.      */  
  54.     device_init_wakeup(&rhdev->dev, 1);  
  55.   
  56.     /* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is 
  57.      * registered.  But since the controller can die at any time, 
  58.      * let's initialize the flag before touching the hardware. 
  59.      */  
  60.     set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);  
  61.   
  62.     /* "reset" is misnamed; its role is now one-time init. the controller 
  63.      * should already have been reset (and boot firmware kicked off etc). 
  64.      */  
  65.     //如果有reset函數就調用  
  66.     if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {  
  67.         dev_err(hcd->self.controller, "can't setup\n");  
  68.         goto err_hcd_driver_setup;  
  69.     }  
  70.     hcd->rh_pollable = 1;  
  71.   
  72.     /* NOTE: root hub and controller capabilities may not be the same */  
  73.     if (device_can_wakeup(hcd->self.controller)  
  74.             && device_can_wakeup(&hcd->self.root_hub->dev))  
  75.         dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");  
  76.   
  77.     /* enable irqs just before we start the controller */  
  78.     if (usb_hcd_is_primary_hcd(hcd)) {  
  79.         retval = usb_hcd_request_irqs(hcd, irqnum, irqflags);  
  80.         if (retval)  
  81.             goto err_request_irq;  
  82.     }  
  83.   
  84.     hcd->state = HC_STATE_RUNNING;  
  85.     retval = hcd->driver->start(hcd);  
  86.     if (retval < 0) {  
  87.         dev_err(hcd->self.controller, "startup error %d\n", retval);  
  88.         goto err_hcd_driver_start;  
  89.     }  
  90.   
  91.     /* starting here, usbcore will pay attention to this root hub */  
  92.     rhdev->bus_mA = min(500u, hcd->power_budget);  
  93.     if ((retval = register_root_hub(hcd)) != 0)     //註冊此root  hub  
  94.         goto err_register_root_hub;  
  95.   
  96.     retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);  
  97.     if (retval < 0) {  
  98.         printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",  
  99.                retval);  
  100.         goto error_create_attr_group;  
  101.     }  
  102.     if (hcd->uses_new_polling && HCD_POLL_RH(hcd))  
  103.         usb_hcd_poll_rh_status(hcd);  
  104.     return retval;  
  105.   
  106. error_create_attr_group:  
  107.     clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);  
  108.     if (HC_IS_RUNNING(hcd->state))  
  109.         hcd->state = HC_STATE_QUIESCING;  
  110.     spin_lock_irq(&hcd_root_hub_lock);  
  111.     hcd->rh_registered = 0;  
  112.     spin_unlock_irq(&hcd_root_hub_lock);  
  113.   
  114. #ifdef CONFIG_USB_SUSPEND  
  115.     cancel_work_sync(&hcd->wakeup_work);  
  116. #endif  
  117.     mutex_lock(&usb_bus_list_lock);  
  118.     usb_disconnect(&rhdev);     /* Sets rhdev to NULL */  
  119.     mutex_unlock(&usb_bus_list_lock);  
  120. err_register_root_hub:  
  121.     hcd->rh_pollable = 0;  
  122.     clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);  
  123.     del_timer_sync(&hcd->rh_timer);  
  124.     hcd->driver->stop(hcd);  
  125.     hcd->state = HC_STATE_HALT;  
  126.     clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);  
  127.     del_timer_sync(&hcd->rh_timer);  
  128. err_hcd_driver_start:  
  129.     if (usb_hcd_is_primary_hcd(hcd) && hcd->irq >= 0)  
  130.         free_irq(irqnum, hcd);  
  131. err_request_irq:  
  132. err_hcd_driver_setup:  
  133. err_set_rh_speed:  
  134.     usb_put_dev(hcd->self.root_hub);  
  135. err_allocate_root_hub:  
  136.     usb_deregister_bus(&hcd->self);  
  137. err_register_bus:  
  138.     hcd_buffer_destroy(hcd);  
  139.     return retval;  
  140. }   
int usb_add_hcd(struct usb_hcd *hcd,
		unsigned int irqnum, unsigned long irqflags)
{
	int retval;
	struct usb_device *rhdev;

	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);

	/* Keep old behaviour if authorized_default is not in [0, 1]. */
	if (authorized_default < 0 || authorized_default > 1)
		hcd->authorized_default = hcd->wireless? 0 : 1;
	else
		hcd->authorized_default = authorized_default;
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

	/* HC is in reset state, but accessible.  Now do the one-time init,
	 * bottom up so that hcds can customize the root hubs before khubd
	 * starts talking to them.  (Note, bus id is assigned early too.)
	 */
	if ((retval = hcd_buffer_create(hcd)) != 0) {	//初始化一個buffer池
		dev_dbg(hcd->self.controller, "pool alloc failed\n");
		return retval;
	}

	if ((retval = usb_register_bus(&hcd->self)) < 0)	//註冊此總線
		goto err_register_bus;

	if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {		//分配usb_device結構
		dev_err(hcd->self.controller, "unable to allocate root hub\n");
		retval = -ENOMEM;
		goto err_allocate_root_hub;
	}
	hcd->self.root_hub = rhdev;

	switch (hcd->speed) {
	case HCD_USB11:
		rhdev->speed = USB_SPEED_FULL;
		break;
	case HCD_USB2:
		rhdev->speed = USB_SPEED_HIGH;
		break;
	case HCD_USB3:
		rhdev->speed = USB_SPEED_SUPER;
		break;
	default:
		retval = -EINVAL;
		goto err_set_rh_speed;
	}

	/* wakeup flag init defaults to "everything works" for root hubs,
	 * but drivers can override it in reset() if needed, along with
	 * recording the overall controller's system wakeup capability.
	 */
	device_init_wakeup(&rhdev->dev, 1);

	/* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is
	 * registered.  But since the controller can die at any time,
	 * let's initialize the flag before touching the hardware.
	 */
	set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);

	/* "reset" is misnamed; its role is now one-time init. the controller
	 * should already have been reset (and boot firmware kicked off etc).
	 */
	//如果有reset函數就調用
	if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
		dev_err(hcd->self.controller, "can't setup\n");
		goto err_hcd_driver_setup;
	}
	hcd->rh_pollable = 1;

	/* NOTE: root hub and controller capabilities may not be the same */
	if (device_can_wakeup(hcd->self.controller)
			&& device_can_wakeup(&hcd->self.root_hub->dev))
		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");

	/* enable irqs just before we start the controller */
	if (usb_hcd_is_primary_hcd(hcd)) {
		retval = usb_hcd_request_irqs(hcd, irqnum, irqflags);
		if (retval)
			goto err_request_irq;
	}

	hcd->state = HC_STATE_RUNNING;
	retval = hcd->driver->start(hcd);
	if (retval < 0) {
		dev_err(hcd->self.controller, "startup error %d\n", retval);
		goto err_hcd_driver_start;
	}

	/* starting here, usbcore will pay attention to this root hub */
	rhdev->bus_mA = min(500u, hcd->power_budget);
	if ((retval = register_root_hub(hcd)) != 0)		//註冊此root  hub
		goto err_register_root_hub;

	retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
	if (retval < 0) {
		printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",
		       retval);
		goto error_create_attr_group;
	}
	if (hcd->uses_new_polling && HCD_POLL_RH(hcd))
		usb_hcd_poll_rh_status(hcd);
	return retval;

error_create_attr_group:
	clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
	if (HC_IS_RUNNING(hcd->state))
		hcd->state = HC_STATE_QUIESCING;
	spin_lock_irq(&hcd_root_hub_lock);
	hcd->rh_registered = 0;
	spin_unlock_irq(&hcd_root_hub_lock);

#ifdef CONFIG_USB_SUSPEND
	cancel_work_sync(&hcd->wakeup_work);
#endif
	mutex_lock(&usb_bus_list_lock);
	usb_disconnect(&rhdev);		/* Sets rhdev to NULL */
	mutex_unlock(&usb_bus_list_lock);
err_register_root_hub:
	hcd->rh_pollable = 0;
	clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
	del_timer_sync(&hcd->rh_timer);
	hcd->driver->stop(hcd);
	hcd->state = HC_STATE_HALT;
	clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
	del_timer_sync(&hcd->rh_timer);
err_hcd_driver_start:
	if (usb_hcd_is_primary_hcd(hcd) && hcd->irq >= 0)
		free_irq(irqnum, hcd);
err_request_irq:
err_hcd_driver_setup:
err_set_rh_speed:
	usb_put_dev(hcd->self.root_hub);
err_allocate_root_hub:
	usb_deregister_bus(&hcd->self);
err_register_bus:
	hcd_buffer_destroy(hcd);
	return retval;
} 
  1. static int register_root_hub(struct usb_hcd *hcd)  
  2. {  
  3.     struct device *parent_dev = hcd->self.controller;  
  4.     struct usb_device *usb_dev = hcd->self.root_hub;  
  5.     const int devnum = 1;  
  6.     int retval;  
  7.   
  8.     usb_dev->devnum = devnum;  
  9.     usb_dev->bus->devnum_next = devnum + 1;  
  10.     memset (&usb_dev->bus->devmap.devicemap, 0,  
  11.             sizeof usb_dev->bus->devmap.devicemap);  
  12.     set_bit (devnum, usb_dev->bus->devmap.devicemap);  
  13.     usb_set_device_state(usb_dev, USB_STATE_ADDRESS);   //設置usb_device的狀態  
  14.   
  15.     mutex_lock(&usb_bus_list_lock);  
  16.   
  17.     usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);  
  18.     retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);    //獲取設備描述符  
  19.     if (retval != sizeof usb_dev->descriptor) {  
  20.         mutex_unlock(&usb_bus_list_lock);  
  21.         dev_dbg (parent_dev, "can't read %s device descriptor %d\n",  
  22.                 dev_name(&usb_dev->dev), retval);  
  23.         return (retval < 0) ? retval : -EMSGSIZE;  
  24.     }  
  25.   
  26.     retval = usb_new_device (usb_dev);  //註冊此usb_device  
  27.     if (retval) {  
  28.         dev_err (parent_dev, "can't register root hub for %s, %d\n",  
  29.                 dev_name(&usb_dev->dev), retval);  
  30.     }  
  31.     mutex_unlock(&usb_bus_list_lock);  
  32.   
  33.     if (retval == 0) {  
  34.         spin_lock_irq (&hcd_root_hub_lock);  
  35.         hcd->rh_registered = 1;  
  36.         spin_unlock_irq (&hcd_root_hub_lock);  
  37.   
  38.         /* Did the HC die before the root hub was registered? */  
  39.         if (HCD_DEAD(hcd))  
  40.             usb_hc_died (hcd);  /* This time clean up */  
  41.     }  
  42.   
  43.     return retval;  
  44. }  
static int register_root_hub(struct usb_hcd *hcd)
{
	struct device *parent_dev = hcd->self.controller;
	struct usb_device *usb_dev = hcd->self.root_hub;
	const int devnum = 1;
	int retval;

	usb_dev->devnum = devnum;
	usb_dev->bus->devnum_next = devnum + 1;
	memset (&usb_dev->bus->devmap.devicemap, 0,
			sizeof usb_dev->bus->devmap.devicemap);
	set_bit (devnum, usb_dev->bus->devmap.devicemap);
	usb_set_device_state(usb_dev, USB_STATE_ADDRESS);	//設置usb_device的狀態

	mutex_lock(&usb_bus_list_lock);

	usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
	retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);	//獲取設備描述符
	if (retval != sizeof usb_dev->descriptor) {
		mutex_unlock(&usb_bus_list_lock);
		dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
				dev_name(&usb_dev->dev), retval);
		return (retval < 0) ? retval : -EMSGSIZE;
	}

	retval = usb_new_device (usb_dev);	//註冊此usb_device
	if (retval) {
		dev_err (parent_dev, "can't register root hub for %s, %d\n",
				dev_name(&usb_dev->dev), retval);
	}
	mutex_unlock(&usb_bus_list_lock);

	if (retval == 0) {
		spin_lock_irq (&hcd_root_hub_lock);
		hcd->rh_registered = 1;
		spin_unlock_irq (&hcd_root_hub_lock);

		/* Did the HC die before the root hub was registered? */
		if (HCD_DEAD(hcd))
			usb_hc_died (hcd);	/* This time clean up */
	}

	return retval;
}
  1. int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)  
  2. {  
  3.     struct usb_device_descriptor *desc;  
  4.     int ret;  
  5.   
  6.     if (size > sizeof(*desc))  
  7.         return -EINVAL;  
  8.     desc = kmalloc(sizeof(*desc), GFP_NOIO);  
  9.     if (!desc)  
  10.         return -ENOMEM;  
  11.   
  12.     ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);  
  13.     if (ret >= 0)  
  14.         memcpy(&dev->descriptor, desc, size);  
  15.     kfree(desc);  
  16.     return ret;  
  17. }  
  18. int usb_get_descriptor(struct usb_device *dev, unsigned char type,  
  19.                unsigned char index, void *buf, int size)  
  20. {  
  21.     int i;  
  22.     int result;  
  23.   
  24.     memset(buf, 0, size);   /* Make sure we parse really received data */  
  25.   
  26.     for (i = 0; i < 3; ++i) {  
  27.         /* retry on length 0 or error; some devices are flakey */  
  28.         result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),  
  29.                 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,  
  30.                 (type << 8) + index, 0, buf, size,  
  31.                 USB_CTRL_GET_TIMEOUT);  
  32.         if (result <= 0 && result != -ETIMEDOUT)  
  33.             continue;  
  34.         if (result > 1 && ((u8 *)buf)[1] != type) {  
  35.             result = -ENODATA;  
  36.             continue;  
  37.         }  
  38.         break;  
  39.     }  
  40.     return result;  
  41. }  
int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
{
	struct usb_device_descriptor *desc;
	int ret;

	if (size > sizeof(*desc))
		return -EINVAL;
	desc = kmalloc(sizeof(*desc), GFP_NOIO);
	if (!desc)
		return -ENOMEM;

	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
	if (ret >= 0)
		memcpy(&dev->descriptor, desc, size);
	kfree(desc);
	return ret;
}
int usb_get_descriptor(struct usb_device *dev, unsigned char type,
		       unsigned char index, void *buf, int size)
{
	int i;
	int result;

	memset(buf, 0, size);	/* Make sure we parse really received data */

	for (i = 0; i < 3; ++i) {
		/* retry on length 0 or error; some devices are flakey */
		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
				(type << 8) + index, 0, buf, size,
				USB_CTRL_GET_TIMEOUT);
		if (result <= 0 && result != -ETIMEDOUT)
			continue;
		if (result > 1 && ((u8 *)buf)[1] != type) {
			result = -ENODATA;
			continue;
		}
		break;
	}
	return result;
}
再來看下如何才能獲取設備描述符

  1. int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,  
  2.             __u8 requesttype, __u16 value, __u16 index, void *data,  
  3.             __u16 size, int timeout)  
  4. {  
  5.     struct usb_ctrlrequest *dr;  
  6.     int ret;  
  7.   
  8.     dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);  
  9.     if (!dr)  
  10.         return -ENOMEM;  
  11.   
  12.     dr->bRequestType = requesttype;  
  13.     dr->bRequest = request;  
  14.     dr->wValue = cpu_to_le16(value);  
  15.     dr->wIndex = cpu_to_le16(index);  
  16.     dr->wLength = cpu_to_le16(size);  
  17.   
  18.     /* dbg("usb_control_msg"); */  
  19.   
  20.     ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);  
  21.   
  22.     kfree(dr);  
  23.   
  24.     return ret;  
  25. }  
  26. static int usb_internal_control_msg(struct usb_device *usb_dev,  
  27.                     unsigned int pipe,  
  28.                     struct usb_ctrlrequest *cmd,  
  29.                     void *data, int len, int timeout)  
  30. {  
  31.     struct urb *urb;  
  32.     int retv;  
  33.     int length;  
  34.   
  35.     urb = usb_alloc_urb(0, GFP_NOIO);  
  36.     if (!urb)  
  37.         return -ENOMEM;  
  38.   
  39.     usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,  
  40.                  len, usb_api_blocking_completion, NULL);  
  41.   
  42.     retv = usb_start_wait_urb(urb, timeout, &length);  
  43.     if (retv < 0)  
  44.         return retv;  
  45.     else  
  46.         return length;  
  47. }  
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)
{
	struct usb_ctrlrequest *dr;
	int ret;

	dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
	if (!dr)
		return -ENOMEM;

	dr->bRequestType = requesttype;
	dr->bRequest = request;
	dr->wValue = cpu_to_le16(value);
	dr->wIndex = cpu_to_le16(index);
	dr->wLength = cpu_to_le16(size);

	/* dbg("usb_control_msg"); */

	ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);

	kfree(dr);

	return ret;
}
static int usb_internal_control_msg(struct usb_device *usb_dev,
				    unsigned int pipe,
				    struct usb_ctrlrequest *cmd,
				    void *data, int len, int timeout)
{
	struct urb *urb;
	int retv;
	int length;

	urb = usb_alloc_urb(0, GFP_NOIO);
	if (!urb)
		return -ENOMEM;

	usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
			     len, usb_api_blocking_completion, NULL);

	retv = usb_start_wait_urb(urb, timeout, &length);
	if (retv < 0)
		return retv;
	else
		return length;
}
usb_internal_control_msg是一個比較重要的函數,此函數主要有3個過程

(1)分配urb結構

(2)填充此urb結構

(3)將urb結構提交到主機控制器。

usb_start_wait_urb

usb_submit_urb

usb_pipe_endpoint

usb_hcd_submit_urb

rh_urb_enqueue(hcd, urb) //root hub的urb處理

rh_call_control

hcd->driver->hub_control

ohci_s3c2410_hub_control

hcd->driver->urb_enqueue(hcd, urb, mem_flags) //非root  hub的urb處理

wait_for_completion_timeout

獲取到設備描述符後,就調用usb_new_device函數,此函數讀取並解析設備描述符後就調用device_add添加到Linux設備模型中,會觸發設備的匹配(usb_device_match)。因爲它是usb_device會匹配到唯一的usb_device_driver。generic_probe會被調用。

  1. int usb_new_device(struct usb_device *udev)  
  2. {  
  3.     int err;  
  4.   
  5.     if (udev->parent) {  
  6.         /* Initialize non-root-hub device wakeup to disabled; 
  7.          * device (un)configuration controls wakeup capable 
  8.          * sysfs power/wakeup controls wakeup enabled/disabled 
  9.          */  
  10.         device_init_wakeup(&udev->dev, 0);  
  11.     }  
  12.   
  13.     /* Tell the runtime-PM framework the device is active */  
  14.     pm_runtime_set_active(&udev->dev);  
  15.     pm_runtime_get_noresume(&udev->dev);  
  16.     pm_runtime_use_autosuspend(&udev->dev);  
  17.     pm_runtime_enable(&udev->dev);  
  18.   
  19.     /* By default, forbid autosuspend for all devices.  It will be 
  20.      * allowed for hubs during binding. 
  21.      */  
  22.     usb_disable_autosuspend(udev);  
  23.   
  24.     err = usb_enumerate_device(udev);   /* Read descriptors */  //讀取並解析設備描述符  
  25.     if (err < 0)  
  26.         goto fail;  
  27.     dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",  
  28.             udev->devnum, udev->bus->busnum,  
  29.             (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));  
  30.     /* export the usbdev device-node for libusb */  
  31.     udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,  
  32.             (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));  
  33.   
  34.     /* Tell the world! */  
  35.     announce_device(udev);  //把此usb_device結構的信息打印出來  
  36.   
  37.     device_enable_async_suspend(&udev->dev);  
  38.     /* Register the device.  The device driver is responsible 
  39.      * for configuring the device and invoking the add-device 
  40.      * notifier chain (used by usbfs and possibly others). 
  41.      */  
  42.     err = device_add(&udev->dev);    //添加到linux設備模型,會觸發匹配usb_device_match  
  43.     if (err) {  
  44.         dev_err(&udev->dev, "can't device_add, error %d\n", err);  
  45.         goto fail;  
  46.     }  
  47.   
  48.     (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);  //創建端點設備  
  49.     usb_mark_last_busy(udev);  
  50.     pm_runtime_put_sync_autosuspend(&udev->dev);  
  51.     return err;  
  52.   
  53. fail:  
  54.     usb_set_device_state(udev, USB_STATE_NOTATTACHED);  
  55.     pm_runtime_disable(&udev->dev);  
  56.     pm_runtime_set_suspended(&udev->dev);  
  57.     return err;  
  58. }  
int usb_new_device(struct usb_device *udev)
{
	int err;

	if (udev->parent) {
		/* Initialize non-root-hub device wakeup to disabled;
		 * device (un)configuration controls wakeup capable
		 * sysfs power/wakeup controls wakeup enabled/disabled
		 */
		device_init_wakeup(&udev->dev, 0);
	}

	/* Tell the runtime-PM framework the device is active */
	pm_runtime_set_active(&udev->dev);
	pm_runtime_get_noresume(&udev->dev);
	pm_runtime_use_autosuspend(&udev->dev);
	pm_runtime_enable(&udev->dev);

	/* By default, forbid autosuspend for all devices.  It will be
	 * allowed for hubs during binding.
	 */
	usb_disable_autosuspend(udev);

	err = usb_enumerate_device(udev);	/* Read descriptors */	//讀取並解析設備描述符
	if (err < 0)
		goto fail;
	dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",
			udev->devnum, udev->bus->busnum,
			(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
	/* export the usbdev device-node for libusb */
	udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
			(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));

	/* Tell the world! */
	announce_device(udev);	//把此usb_device結構的信息打印出來

	device_enable_async_suspend(&udev->dev);
	/* Register the device.  The device driver is responsible
	 * for configuring the device and invoking the add-device
	 * notifier chain (used by usbfs and possibly others).
	 */
	err = device_add(&udev->dev);	//添加到linux設備模型,會觸發匹配usb_device_match
	if (err) {
		dev_err(&udev->dev, "can't device_add, error %d\n", err);
		goto fail;
	}

	(void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);	//創建端點設備
	usb_mark_last_busy(udev);
	pm_runtime_put_sync_autosuspend(&udev->dev);
	return err;

fail:
	usb_set_device_state(udev, USB_STATE_NOTATTACHED);
	pm_runtime_disable(&udev->dev);
	pm_runtime_set_suspended(&udev->dev);
	return err;
}

  1. static int usb_device_match(struct device *dev, struct device_driver *drv)  
  2. {  
  3.     /* devices and interfaces are handled separately */  
  4.     if (is_usb_device(dev)) {   //針對usb設備  
  5.   
  6.         /* interface drivers never match devices */  
  7.         if (!is_usb_device_driver(drv))  
  8.             return 0;  
  9.   
  10.         /* TODO: Add real matching code */  
  11.         return 1;  
  12.   
  13.     } else if (is_usb_interface(dev)) {     //針對usb接口  
  14.         struct usb_interface *intf;  
  15.         struct usb_driver *usb_drv;  
  16.         const struct usb_device_id *id;  
  17.   
  18.         /* device drivers never match interfaces */  
  19.         if (is_usb_device_driver(drv))  
  20.             return 0;  
  21.   
  22.         intf = to_usb_interface(dev);  
  23.         usb_drv = to_usb_driver(drv);  
  24.   
  25.         id = usb_match_id(intf, usb_drv->id_table);  
  26.         if (id)  
  27.             return 1;  
  28.   
  29.         id = usb_match_dynamic_id(intf, usb_drv);  
  30.         if (id)  
  31.             return 1;  
  32.     }  
  33.   
  34.     return 0;  
  35. }  
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
	/* devices and interfaces are handled separately */
	if (is_usb_device(dev)) {	//針對usb設備

		/* interface drivers never match devices */
		if (!is_usb_device_driver(drv))
			return 0;

		/* TODO: Add real matching code */
		return 1;

	} else if (is_usb_interface(dev)) {		//針對usb接口
		struct usb_interface *intf;
		struct usb_driver *usb_drv;
		const struct usb_device_id *id;

		/* device drivers never match interfaces */
		if (is_usb_device_driver(drv))
			return 0;

		intf = to_usb_interface(dev);
		usb_drv = to_usb_driver(drv);

		id = usb_match_id(intf, usb_drv->id_table);
		if (id)
			return 1;

		id = usb_match_dynamic_id(intf, usb_drv);
		if (id)
			return 1;
	}

	return 0;
}

  1. static int generic_probe(struct usb_device *udev)  
  2. {  
  3.     int err, c;  
  4.   
  5.     /* Choose and set the configuration.  This registers the interfaces 
  6.      * with the driver core and lets interface drivers bind to them. 
  7.      */  
  8.     if (usb_device_is_owned(udev))  
  9.         ;       /* Don't configure if the device is owned */  
  10.     else if (udev->authorized == 0)  
  11.         dev_err(&udev->dev, "Device is not authorized for usage\n");  
  12.     else {  
  13.         c = usb_choose_configuration(udev); //選取一個配置  
  14.         if (c >= 0) {  
  15.             err = usb_set_configuration(udev, c);   //設置配置,並註冊interfrace  
  16.             if (err) {  
  17.                 dev_err(&udev->dev, "can't set config #%d, error %d\n",  
  18.                     c, err);  
  19.                 /* This need not be fatal.  The user can try to 
  20.                  * set other configurations. */  
  21.             }  
  22.         }  
  23.     }  
  24.     /* USB device state == configured ... usable */  
  25.     usb_notify_add_device(udev);  
  26.   
  27.     return 0;  
  28. }  
static int generic_probe(struct usb_device *udev)
{
	int err, c;

	/* Choose and set the configuration.  This registers the interfaces
	 * with the driver core and lets interface drivers bind to them.
	 */
	if (usb_device_is_owned(udev))
		;		/* Don't configure if the device is owned */
	else if (udev->authorized == 0)
		dev_err(&udev->dev, "Device is not authorized for usage\n");
	else {
		c = usb_choose_configuration(udev);	//選取一個配置
		if (c >= 0) {
			err = usb_set_configuration(udev, c);	//設置配置,並註冊interfrace
			if (err) {
				dev_err(&udev->dev, "can't set config #%d, error %d\n",
					c, err);
				/* This need not be fatal.  The user can try to
				 * set other configurations. */
			}
		}
	}
	/* USB device state == configured ... usable */
	usb_notify_add_device(udev);

	return 0;
}
  1. int usb_set_configuration(struct usb_device *dev, int configuration)  
  2. {  
  3.     int i, ret;  
  4.     struct usb_host_config *cp = NULL;  
  5.     struct usb_interface **new_interfaces = NULL;  
  6.     struct usb_hcd *hcd = bus_to_hcd(dev->bus);  
  7.     int n, nintf;  
  8.   
  9.     if (dev->authorized == 0 || configuration == -1)  
  10.         configuration = 0;  
  11.     else {  
  12.         for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {  
  13.             if (dev->config[i].desc.bConfigurationValue ==  
  14.                     configuration) {  
  15.                 cp = &dev->config[i];    //取得索引號爲configuration的配置結構體  
  16.                 break;  
  17.             }  
  18.         }  
  19.     }  
  20.     if ((!cp && configuration != 0))  
  21.         return -EINVAL;  
  22.   
  23.     /* The USB spec says configuration 0 means unconfigured. 
  24.      * But if a device includes a configuration numbered 0, 
  25.      * we will accept it as a correctly configured state. 
  26.      * Use -1 if you really want to unconfigure the device. 
  27.      */  
  28.     if (cp && configuration == 0)  
  29.         dev_warn(&dev->dev, "config 0 descriptor??\n");  
  30.   
  31.     /* Allocate memory for new interfaces before doing anything else, 
  32.      * so that if we run out then nothing will have changed. */  
  33.     n = nintf = 0;  
  34.     if (cp) {   //分配bNumInterfaces個接口結構  
  35.         nintf = cp->desc.bNumInterfaces;  
  36.         new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),  
  37.                 GFP_NOIO);  
  38.         if (!new_interfaces) {  
  39.             dev_err(&dev->dev, "Out of memory\n");  
  40.             return -ENOMEM;  
  41.         }  
  42.   
  43.         for (; n < nintf; ++n) {  
  44.             new_interfaces[n] = kzalloc(  
  45.                     sizeof(struct usb_interface),  
  46.                     GFP_NOIO);  
  47.             if (!new_interfaces[n]) {  
  48.                 dev_err(&dev->dev, "Out of memory\n");  
  49.                 ret = -ENOMEM;  
  50. free_interfaces:  
  51.                 while (--n >= 0)  
  52.                     kfree(new_interfaces[n]);  
  53.                 kfree(new_interfaces);  
  54.                 return ret;  
  55.             }  
  56.         }  
  57.   
  58.         i = dev->bus_mA - cp->desc.bMaxPower * 2;  
  59.         if (i < 0)  
  60.             dev_warn(&dev->dev, "new config #%d exceeds power "  
  61.                     "limit by %dmA\n",  
  62.                     configuration, -i);  
  63.     }  
  64.   
  65.     /* Wake up the device so we can send it the Set-Config request */  
  66.     ret = usb_autoresume_device(dev);  
  67.     if (ret)  
  68.         goto free_interfaces;  
  69.   
  70.     /* if it's already configured, clear out old state first. 
  71.      * getting rid of old interfaces means unbinding their drivers. 
  72.      */  
  73.     mutex_lock(hcd->bandwidth_mutex);  
  74.     if (dev->state != USB_STATE_ADDRESS)  
  75.         usb_disable_device(dev, 1); /* Skip ep0 */  
  76.   
  77.     /* Get rid of pending async Set-Config requests for this device */  
  78.     cancel_async_set_config(dev);  
  79.   
  80.     /* Make sure we have bandwidth (and available HCD resources) for this 
  81.      * configuration.  Remove endpoints from the schedule if we're dropping 
  82.      * this configuration to set configuration 0.  After this point, the 
  83.      * host controller will not allow submissions to dropped endpoints.  If 
  84.      * this call fails, the device state is unchanged. 
  85.      */  
  86.     ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);  
  87.     if (ret < 0) {  
  88.         mutex_unlock(hcd->bandwidth_mutex);  
  89.         usb_autosuspend_device(dev);  
  90.         goto free_interfaces;  
  91.     }  
  92.     //發送USB_REQ_SET_CONFIGURATION的urb信息來設置設備的配置  
  93.     ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),  
  94.                   USB_REQ_SET_CONFIGURATION, 0, configuration, 0,  
  95.                   NULL, 0, USB_CTRL_SET_TIMEOUT);  
  96.     if (ret < 0) {  
  97.         /* All the old state is gone, so what else can we do? 
  98.          * The device is probably useless now anyway. 
  99.          */  
  100.         cp = NULL;  
  101.     }  
  102.   
  103.     dev->actconfig = cp;  
  104.     if (!cp) {  
  105.         usb_set_device_state(dev, USB_STATE_ADDRESS);  
  106.         usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);  
  107.         mutex_unlock(hcd->bandwidth_mutex);  
  108.         usb_autosuspend_device(dev);  
  109.         goto free_interfaces;  
  110.     }  
  111.     mutex_unlock(hcd->bandwidth_mutex);  
  112.     usb_set_device_state(dev, USB_STATE_CONFIGURED);  
  113.   
  114.     /* Initialize the new interface structures and the 
  115.      * hc/hcd/usbcore interface/endpoint state. 
  116.      */  
  117.     //初始化各個usb_interface  
  118.     for (i = 0; i < nintf; ++i) {  
  119.         struct usb_interface_cache *intfc;  
  120.         struct usb_interface *intf;  
  121.         struct usb_host_interface *alt;  
  122.   
  123.         cp->interface[i] = intf = new_interfaces[i];  
  124.         intfc = cp->intf_cache[i];  
  125.         intf->altsetting = intfc->altsetting;  
  126.         intf->num_altsetting = intfc->num_altsetting;  
  127.         intf->intf_assoc = find_iad(dev, cp, i);  
  128.         kref_get(&intfc->ref);  
  129.   
  130.         alt = usb_altnum_to_altsetting(intf, 0);  
  131.   
  132.         /* No altsetting 0?  We'll assume the first altsetting. 
  133.          * We could use a GetInterface call, but if a device is 
  134.          * so non-compliant that it doesn't have altsetting 0 
  135.          * then I wouldn't trust its reply anyway. 
  136.          */  
  137.         if (!alt)  
  138.             alt = &intf->altsetting[0];  
  139.   
  140.         intf->cur_altsetting = alt;  
  141.         usb_enable_interface(dev, intf, true);  
  142.         intf->dev.parent = &dev->dev;  
  143.         intf->dev.driver = NULL;  
  144.         intf->dev.bus = &usb_bus_type;  
  145.         intf->dev.type = &usb_if_device_type;  
  146.         intf->dev.groups = usb_interface_groups;  
  147.         intf->dev.dma_mask = dev->dev.dma_mask;  
  148.         INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);  
  149.         intf->minor = -1;  
  150.         device_initialize(&intf->dev);  
  151.         pm_runtime_no_callbacks(&intf->dev);  
  152.         dev_set_name(&intf->dev, "%d-%s:%d.%d",  
  153.             dev->bus->busnum, dev->devpath,  
  154.             configuration, alt->desc.bInterfaceNumber);  
  155.     }  
  156.     kfree(new_interfaces);  
  157.   
  158.     if (cp->string == NULL &&  
  159.             !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))  
  160.         cp->string = usb_cache_string(dev, cp->desc.iConfiguration);  
  161.   
  162.     /* Now that all the interfaces are set up, register them 
  163.      * to trigger binding of drivers to interfaces.  probe() 
  164.      * routines may install different altsettings and may 
  165.      * claim() any interfaces not yet bound.  Many class drivers 
  166.      * need that: CDC, audio, video, etc. 
  167.      */  
  168.     for (i = 0; i < nintf; ++i) {  
  169.         struct usb_interface *intf = cp->interface[i];  
  170.   
  171.         dev_dbg(&dev->dev,  
  172.             "adding %s (config #%d, interface %d)\n",  
  173.             dev_name(&intf->dev), configuration,  
  174.             intf->cur_altsetting->desc.bInterfaceNumber);  
  175.         device_enable_async_suspend(&intf->dev);  
  176.         ret = device_add(&intf->dev);    //將接口的dev添加到系統,將觸發接口設備和接口驅動的match  
  177.         if (ret != 0) {  
  178.             dev_err(&dev->dev, "device_add(%s) --> %d\n",  
  179.                 dev_name(&intf->dev), ret);  
  180.             continue;  
  181.         }  
  182.         create_intf_ep_devs(intf);  
  183.     }  
  184.   
  185.     usb_autosuspend_device(dev);  
  186.     return 0;  
  187. }  
int usb_set_configuration(struct usb_device *dev, int configuration)
{
	int i, ret;
	struct usb_host_config *cp = NULL;
	struct usb_interface **new_interfaces = NULL;
	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
	int n, nintf;

	if (dev->authorized == 0 || configuration == -1)
		configuration = 0;
	else {
		for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
			if (dev->config[i].desc.bConfigurationValue ==
					configuration) {
				cp = &dev->config[i];	//取得索引號爲configuration的配置結構體
				break;
			}
		}
	}
	if ((!cp && configuration != 0))
		return -EINVAL;

	/* The USB spec says configuration 0 means unconfigured.
	 * But if a device includes a configuration numbered 0,
	 * we will accept it as a correctly configured state.
	 * Use -1 if you really want to unconfigure the device.
	 */
	if (cp && configuration == 0)
		dev_warn(&dev->dev, "config 0 descriptor??\n");

	/* Allocate memory for new interfaces before doing anything else,
	 * so that if we run out then nothing will have changed. */
	n = nintf = 0;
	if (cp) {	//分配bNumInterfaces個接口結構
		nintf = cp->desc.bNumInterfaces;
		new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
				GFP_NOIO);
		if (!new_interfaces) {
			dev_err(&dev->dev, "Out of memory\n");
			return -ENOMEM;
		}

		for (; n < nintf; ++n) {
			new_interfaces[n] = kzalloc(
					sizeof(struct usb_interface),
					GFP_NOIO);
			if (!new_interfaces[n]) {
				dev_err(&dev->dev, "Out of memory\n");
				ret = -ENOMEM;
free_interfaces:
				while (--n >= 0)
					kfree(new_interfaces[n]);
				kfree(new_interfaces);
				return ret;
			}
		}

		i = dev->bus_mA - cp->desc.bMaxPower * 2;
		if (i < 0)
			dev_warn(&dev->dev, "new config #%d exceeds power "
					"limit by %dmA\n",
					configuration, -i);
	}

	/* Wake up the device so we can send it the Set-Config request */
	ret = usb_autoresume_device(dev);
	if (ret)
		goto free_interfaces;

	/* if it's already configured, clear out old state first.
	 * getting rid of old interfaces means unbinding their drivers.
	 */
	mutex_lock(hcd->bandwidth_mutex);
	if (dev->state != USB_STATE_ADDRESS)
		usb_disable_device(dev, 1);	/* Skip ep0 */

	/* Get rid of pending async Set-Config requests for this device */
	cancel_async_set_config(dev);

	/* Make sure we have bandwidth (and available HCD resources) for this
	 * configuration.  Remove endpoints from the schedule if we're dropping
	 * this configuration to set configuration 0.  After this point, the
	 * host controller will not allow submissions to dropped endpoints.  If
	 * this call fails, the device state is unchanged.
	 */
	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
	if (ret < 0) {
		mutex_unlock(hcd->bandwidth_mutex);
		usb_autosuspend_device(dev);
		goto free_interfaces;
	}
	//發送USB_REQ_SET_CONFIGURATION的urb信息來設置設備的配置
	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
			      USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
			      NULL, 0, USB_CTRL_SET_TIMEOUT);
	if (ret < 0) {
		/* All the old state is gone, so what else can we do?
		 * The device is probably useless now anyway.
		 */
		cp = NULL;
	}

	dev->actconfig = cp;
	if (!cp) {
		usb_set_device_state(dev, USB_STATE_ADDRESS);
		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
		mutex_unlock(hcd->bandwidth_mutex);
		usb_autosuspend_device(dev);
		goto free_interfaces;
	}
	mutex_unlock(hcd->bandwidth_mutex);
	usb_set_device_state(dev, USB_STATE_CONFIGURED);

	/* Initialize the new interface structures and the
	 * hc/hcd/usbcore interface/endpoint state.
	 */
	//初始化各個usb_interface
	for (i = 0; i < nintf; ++i) {
		struct usb_interface_cache *intfc;
		struct usb_interface *intf;
		struct usb_host_interface *alt;

		cp->interface[i] = intf = new_interfaces[i];
		intfc = cp->intf_cache[i];
		intf->altsetting = intfc->altsetting;
		intf->num_altsetting = intfc->num_altsetting;
		intf->intf_assoc = find_iad(dev, cp, i);
		kref_get(&intfc->ref);

		alt = usb_altnum_to_altsetting(intf, 0);

		/* No altsetting 0?  We'll assume the first altsetting.
		 * We could use a GetInterface call, but if a device is
		 * so non-compliant that it doesn't have altsetting 0
		 * then I wouldn't trust its reply anyway.
		 */
		if (!alt)
			alt = &intf->altsetting[0];

		intf->cur_altsetting = alt;
		usb_enable_interface(dev, intf, true);
		intf->dev.parent = &dev->dev;
		intf->dev.driver = NULL;
		intf->dev.bus = &usb_bus_type;
		intf->dev.type = &usb_if_device_type;
		intf->dev.groups = usb_interface_groups;
		intf->dev.dma_mask = dev->dev.dma_mask;
		INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
		intf->minor = -1;
		device_initialize(&intf->dev);
		pm_runtime_no_callbacks(&intf->dev);
		dev_set_name(&intf->dev, "%d-%s:%d.%d",
			dev->bus->busnum, dev->devpath,
			configuration, alt->desc.bInterfaceNumber);
	}
	kfree(new_interfaces);

	if (cp->string == NULL &&
			!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
		cp->string = usb_cache_string(dev, cp->desc.iConfiguration);

	/* Now that all the interfaces are set up, register them
	 * to trigger binding of drivers to interfaces.  probe()
	 * routines may install different altsettings and may
	 * claim() any interfaces not yet bound.  Many class drivers
	 * need that: CDC, audio, video, etc.
	 */
	for (i = 0; i < nintf; ++i) {
		struct usb_interface *intf = cp->interface[i];

		dev_dbg(&dev->dev,
			"adding %s (config #%d, interface %d)\n",
			dev_name(&intf->dev), configuration,
			intf->cur_altsetting->desc.bInterfaceNumber);
		device_enable_async_suspend(&intf->dev);
		ret = device_add(&intf->dev);	//將接口的dev添加到系統,將觸發接口設備和接口驅動的match
		if (ret != 0) {
			dev_err(&dev->dev, "device_add(%s) --> %d\n",
				dev_name(&intf->dev), ret);
			continue;
		}
		create_intf_ep_devs(intf);
	}

	usb_autosuspend_device(dev);
	return 0;
}

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