五、从usb的插入开始

当usb设备插入接口,电压变化会通知到usb主控器,

触发主控器中断,如果主控器不支持中断,那么会使用rh_timer方法,轮询接口

其结果都是调用usb_hcd_poll_rh_status

  1. void usb_hcd_poll_rh_status(struct usb_hcd *hcd)  
  2. {  
  3.     struct urb  *urb;  
  4.     int     length;  
  5.     unsigned long   flags;  
  6.     char        buffer[6];  /* Any root hubs with > 31 ports? */  
  7.   
  8.     if (unlikely(!hcd->rh_pollable))  
  9.         return;  
  10.     if (!hcd->uses_new_polling && !hcd->status_urb)  
  11.         return;  
  12.   
  13.     length = hcd->driver->hub_status_data(hcd, buffer);   //获取urb数据长度   
  14.     if (length > 0) {  
  15.   
  16.         /* try to complete the status urb */  
  17.         spin_lock_irqsave(&hcd_root_hub_lock, flags);  
  18.         urb = hcd->status_urb;   //获取要处理的urb   
  19.         if (urb) {  
  20.             clear_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);   //清除urb主控器poll标志   
  21.             hcd->status_urb = NULL;  //清空待处理urb   
  22.             urb->actual_length = length; //获取urb数据长度   
  23.             memcpy(urb->transfer_buffer, buffer, length);    //复制urb缓冲区   
  24.   
  25.             usb_hcd_unlink_urb_from_ep(hcd, urb);   //从主控器的端点上解绑urb   
  26.             spin_unlock(&hcd_root_hub_lock);  
  27.             usb_hcd_giveback_urb(hcd, urb, 0);  //处理urb并回传urb给设备   
  28.             spin_lock(&hcd_root_hub_lock);  
  29.         } else {  
  30.             length = 0;  
  31.             set_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);  
  32.         }  
  33.         spin_unlock_irqrestore(&hcd_root_hub_lock, flags);  
  34.     }  
  35.     if (hcd->uses_new_polling ? HCD_POLL_RH(hcd) :  
  36.             (length == 0 && hcd->status_urb != NULL))  
  37.         mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4));  
  38. }  
void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
{
	struct urb	*urb;
	int		length;
	unsigned long	flags;
	char		buffer[6];	/* Any root hubs with > 31 ports? */

	if (unlikely(!hcd->rh_pollable))
		return;
	if (!hcd->uses_new_polling && !hcd->status_urb)
		return;

	length = hcd->driver->hub_status_data(hcd, buffer);	//获取urb数据长度
	if (length > 0) {

		/* try to complete the status urb */
		spin_lock_irqsave(&hcd_root_hub_lock, flags);
		urb = hcd->status_urb;	//获取要处理的urb
		if (urb) {
			clear_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);	//清除urb主控器poll标志
			hcd->status_urb = NULL;	//清空待处理urb
			urb->actual_length = length;	//获取urb数据长度
			memcpy(urb->transfer_buffer, buffer, length);	//复制urb缓冲区

			usb_hcd_unlink_urb_from_ep(hcd, urb);	//从主控器的端点上解绑urb
			spin_unlock(&hcd_root_hub_lock);
			usb_hcd_giveback_urb(hcd, urb, 0);	//处理urb并回传urb给设备
			spin_lock(&hcd_root_hub_lock);
		} else {
			length = 0;
			set_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);
		}
		spin_unlock_irqrestore(&hcd_root_hub_lock, flags);
	}
	if (hcd->uses_new_polling ? HCD_POLL_RH(hcd) :
			(length == 0 && hcd->status_urb != NULL))
		mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4));
}

usb_hcd_giveback_urb函数

  1. void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)  
  2. {  
  3.     urb->hcpriv = NULL;  
  4.     if (unlikely(urb->unlinked))  
  5.         status = urb->unlinked;  
  6.     else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&  
  7.             urb->actual_length < urb->transfer_buffer_length &&  
  8.             !status))  
  9.         status = -EREMOTEIO;  
  10.   
  11.     unmap_urb_for_dma(hcd, urb);  
  12.     usbmon_urb_complete(&hcd->self, urb, status);  
  13.     usb_unanchor_urb(urb);  
  14.   
  15.     /* pass ownership to the completion handler */  
  16.     urb->status = status;  
  17.     urb->complete (urb);     //执行urb回调函数,就是hub_irq   
  18.     atomic_dec (&urb->use_count);  
  19.     if (unlikely(atomic_read(&urb->reject)))  
  20.         wake_up (&usb_kill_urb_queue);  
  21.     usb_put_urb (urb);  
  22. }  
void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
{
	urb->hcpriv = NULL;
	if (unlikely(urb->unlinked))
		status = urb->unlinked;
	else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
			urb->actual_length < urb->transfer_buffer_length &&
			!status))
		status = -EREMOTEIO;

	unmap_urb_for_dma(hcd, urb);
	usbmon_urb_complete(&hcd->self, urb, status);
	usb_unanchor_urb(urb);

	/* pass ownership to the completion handler */
	urb->status = status;
	urb->complete (urb);		//执行urb回调函数,就是hub_irq
	atomic_dec (&urb->use_count);
	if (unlikely(atomic_read(&urb->reject)))
		wake_up (&usb_kill_urb_queue);
	usb_put_urb (urb);
}

hub_irq函数

  1. static void hub_irq(struct urb *urb)  
  2. {  
  3.     struct usb_hub *hub = urb->context;  
  4.     int status = urb->status;  
  5.     unsigned i;  
  6.     unsigned long bits;  
  7.   
  8.     switch (status) {  
  9.     case -ENOENT:  
  10.     case -ECONNRESET:  
  11.     case -ESHUTDOWN:  
  12.         return;  
  13.     default:    //错误   
  14.         dev_dbg (hub->intfdev, "transfer --> %d\n", status);  
  15.         if ((++hub->nerrors < 10) || hub->error)  
  16.             goto resubmit;  
  17.         hub->error = status;  
  18.     case 0: //端口状态有变化   
  19.         bits = 0;  
  20.         for (i = 0; i < urb->actual_length; ++i)  
  21.             bits |= ((unsigned long) ((*hub->buffer)[i]))<< (i*8);  
  22.         hub->event_bits[0] = bits;   //填充hub->event_bit数组   
  23.         break;  
  24.     }  
  25.   
  26.     hub->nerrors = 0;  
  27.     kick_khubd(hub);    //调用kick_khubd函数   
  28. resubmit:  
  29.     if (hub->quiescing)  
  30.         return;  
  31.     if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0&& status != -ENODEV && status != -EPERM)  
  32.         dev_err (hub->intfdev, "resubmit --> %d\n", status);  
  33. }  
static void hub_irq(struct urb *urb)
{
	struct usb_hub *hub = urb->context;
	int status = urb->status;
	unsigned i;
	unsigned long bits;

	switch (status) {
	case -ENOENT:
	case -ECONNRESET:
	case -ESHUTDOWN:
		return;
	default:	//错误
		dev_dbg (hub->intfdev, "transfer --> %d\n", status);
		if ((++hub->nerrors < 10) || hub->error)
			goto resubmit;
		hub->error = status;
	case 0:	//端口状态有变化
		bits = 0;
		for (i = 0; i < urb->actual_length; ++i)
			bits |= ((unsigned long) ((*hub->buffer)[i]))<< (i*8);
		hub->event_bits[0] = bits;	//填充hub->event_bit数组
		break;
	}

	hub->nerrors = 0;
	kick_khubd(hub);	//调用kick_khubd函数
resubmit:
	if (hub->quiescing)
		return;
	if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0&& status != -ENODEV && status != -EPERM)
		dev_err (hub->intfdev, "resubmit --> %d\n", status);
}

kick_khubd函数

  1. static void kick_khubd(struct usb_hub *hub)  
  2. {  
  3.     unsigned long   flags;  
  4.     spin_lock_irqsave(&hub_event_lock, flags);  
  5.     if (!hub->disconnected && list_empty(&hub->event_list)) {  
  6.         list_add_tail(&hub->event_list, &hub_event_list);  
  7.         usb_autopm_get_interface_no_resume(to_usb_interface(hub->intfdev));  
  8.         wake_up(&khubd_wait);   //唤醒khubd_wait相关的等待队列   
  9.     }  
  10.     spin_unlock_irqrestore(&hub_event_lock, flags);  
  11. }  
static void kick_khubd(struct usb_hub *hub)
{
	unsigned long	flags;
	spin_lock_irqsave(&hub_event_lock, flags);
	if (!hub->disconnected && list_empty(&hub->event_list)) {
		list_add_tail(&hub->event_list, &hub_event_list);
		usb_autopm_get_interface_no_resume(to_usb_interface(hub->intfdev));
		wake_up(&khubd_wait);	//唤醒khubd_wait相关的等待队列
	}
	spin_unlock_irqrestore(&hub_event_lock, flags);
}

这里会触发hub_events函数,原因如下

  1. do {  
  2.     hub_events();  
  3.     wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());  
  4. while (!kthread_should_stop() || !list_empty(&hub_event_list));  
	do {
		hub_events();
		wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());
	} while (!kthread_should_stop() || !list_empty(&hub_event_list));

hub_events函数

  1. static void hub_events(void)  
  2. {  
  3.     struct list_head *tmp;  
  4.     struct usb_device *hdev;  
  5.     struct usb_interface *intf;  
  6.     struct usb_hub *hub;  
  7.     struct device *hub_dev;  
  8.     u16 hubstatus;  
  9.     u16 hubchange;  
  10.     u16 portstatus;  
  11.     u16 portchange;  
  12.     int i, ret;  
  13.     int connect_change;  
  14.     //hcd usb主控器的状态由usb主控器的中断例程根据具体硬件状态去设置   
  15.     while (1) {  
  16.         spin_lock_irq(&hub_event_lock);  
  17.         //这次执行假设usb主控器已经注册   
  18.         if (list_empty(&hub_event_list)) {  //usb事件链表不为为空   
  19.             spin_unlock_irq(&hub_event_lock);  
  20.             break;    
  21.         }  
  22.         tmp = hub_event_list.next;  //拿出hub_event链表项       
  23.         list_del_init(tmp); //从hub_event_list删除其   
  24.         hub = list_entry(tmp, struct usb_hub, event_list);  //根据链表项获取usb_hub       
  25.         kref_get(&hub->kref);    //引用计数   
  26.         spin_unlock_irq(&hub_event_lock);  
  27.         hdev = hub->hdev;        //获取hub usb设备   
  28.         hub_dev = hub->intfdev;  //获取hub 设备文件   
  29.         intf = to_usb_interface(hub_dev);   //获取hub usb接口   
  30.         usb_lock_device(hdev);  
  31.         if (unlikely(hub->disconnected))  
  32.             goto loop_disconnected;  
  33.         if (hdev->state == USB_STATE_NOTATTACHED) {  //判断是否为USB_STATE_NOTATTACHED状态   
  34.             hub->error = -ENODEV;  
  35.             hub_quiesce(hub, HUB_DISCONNECT);  
  36.             goto loop;  
  37.         }  
  38.         ret = usb_autopm_get_interface(intf);  
  39.         if (ret) {  
  40.             dev_dbg(hub_dev, "Can't autoresume: %d\n", ret);  
  41.             goto loop;  
  42.         }  
  43.         if (hub->quiescing)  
  44.             goto loop_autopm;  
  45.         if (hub->error) {  
  46.             dev_dbg (hub_dev, "resetting for error %d\n",hub->error);  
  47.             ret = usb_reset_device(hdev);     
  48.             if (ret) {  
  49.                 dev_dbg (hub_dev,"error resetting hub: %d\n", ret);  
  50.                 goto loop_autopm;  
  51.             }  
  52.             hub->nerrors = 0;  
  53.             hub->error = 0;  
  54.         }  
  55.         for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {  
  56.             if (test_bit(i, hub->busy_bits))  
  57.                 continue;  
  58.             connect_change = test_bit(i, hub->change_bits);  //判断是否hub口状态变化   
  59.             if (!test_and_clear_bit(i, hub->event_bits) &&!connect_change)  
  60.                 continue;  
  61.             ret = hub_port_status(hub, i,&portstatus, &portchange);  
  62.             if (ret < 0)  
  63.                 continue;  
  64.             if (portchange & USB_PORT_STAT_C_CONNECTION) {  //hub口连接上设备   
  65.                 clear_port_feature(hdev, i,USB_PORT_FEAT_C_CONNECTION);  
  66.                 connect_change = 1;  
  67.             }  
  68.             if (portchange & USB_PORT_STAT_C_ENABLE) {  //hub口的设备使能   
  69.                 if (!connect_change)  
  70.                     dev_dbg (hub_dev,"port %d enable change,status %08x\n",i, portstatus);  
  71.                 clear_port_feature(hdev, i,USB_PORT_FEAT_C_ENABLE);  
  72.                 if (!(portstatus & USB_PORT_STAT_ENABLE)&& !connect_change&& hdev->children[i-1]) {  
  73.                     dev_err (hub_dev,"port %i disabled by hub (EMI?),re-enabling...\n",i);  
  74.                     connect_change = 1;  
  75.                 }  
  76.             }  
  77.             if (portchange & USB_PORT_STAT_C_SUSPEND) { //hub口的设备挂起   
  78.                 struct usb_device *udev;  
  79.                 clear_port_feature(hdev, i,USB_PORT_FEAT_C_SUSPEND);  
  80.                 udev = hdev->children[i-1];  
  81.                 if (udev) {  
  82.                     msleep(10);  
  83.                     usb_lock_device(udev);  
  84.                     ret = usb_remote_wakeup(hdev->children[i-1]);  
  85.                     usb_unlock_device(udev);  
  86.                     if (ret < 0)  
  87.                         connect_change = 1;  
  88.                 } else {  
  89.                     ret = -ENODEV;  
  90.                     hub_port_disable(hub, i, 1);  
  91.                 }  
  92.                 dev_dbg (hub_dev,"resume on port %d, status %d\n",i, ret);  
  93.             }  
  94.               
  95.             if (portchange & USB_PORT_STAT_C_OVERCURRENT) { //hub口设备过流   
  96.                 dev_err (hub_dev,"over-current change on port %d\n",i);  
  97.                 clear_port_feature(hdev, i,USB_PORT_FEAT_C_OVER_CURRENT);  
  98.                 hub_power_on(hub, true);  
  99.             }  
  100.             if (portchange & USB_PORT_STAT_C_RESET) {   //hub口设备重置   
  101.                 dev_dbg (hub_dev,"reset change on port %d\n",i);  
  102.                 clear_port_feature(hdev, i,USB_PORT_FEAT_C_RESET);  
  103.             }  
  104.   
  105.             if (connect_change) //hub口有变化(设备插入肯定有变化)   
  106.                 hub_port_connect_change(hub, i,portstatus, portchange); //hub口变化处理   
  107.         }  
  108.         if (test_and_clear_bit(0, hub->event_bits) == 0)  
  109.             ;             
  110.         else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)  
  111.             dev_err (hub_dev, "get_hub_status failed\n");  
  112.         else {  
  113.             if (hubchange & HUB_CHANGE_LOCAL_POWER) {  
  114.                 dev_dbg (hub_dev, "power change\n");  
  115.                 clear_hub_feature(hdev, C_HUB_LOCAL_POWER);  
  116.                 if (hubstatus & HUB_STATUS_LOCAL_POWER)  
  117.                     hub->limited_power = 1;  
  118.                 else  
  119.                     hub->limited_power = 0;  
  120.             }  
  121.             if (hubchange & HUB_CHANGE_OVERCURRENT) {  
  122.                 dev_dbg (hub_dev, "overcurrent change\n");  
  123.                 msleep(500);  
  124.                 clear_hub_feature(hdev, C_HUB_OVER_CURRENT);  
  125.                             hub_power_on(hub, true);  
  126.             }  
  127.         }  
  128.  loop_autopm:  
  129.         usb_autopm_put_interface_no_suspend(intf);  
  130.  loop:  
  131.         usb_autopm_put_interface(intf);  
  132.  loop_disconnected:  
  133.         usb_unlock_device(hdev);  
  134.         kref_put(&hub->kref, hub_release);  
  135.         }  
  136. }  
static void hub_events(void)
{
	struct list_head *tmp;
	struct usb_device *hdev;
	struct usb_interface *intf;
	struct usb_hub *hub;
	struct device *hub_dev;
	u16 hubstatus;
	u16 hubchange;
	u16 portstatus;
	u16 portchange;
	int i, ret;
	int connect_change;
	//hcd usb主控器的状态由usb主控器的中断例程根据具体硬件状态去设置
	while (1) {
		spin_lock_irq(&hub_event_lock);
		//这次执行假设usb主控器已经注册
		if (list_empty(&hub_event_list)) {	//usb事件链表不为为空
			spin_unlock_irq(&hub_event_lock);
			break;	
		}
		tmp = hub_event_list.next;	//拿出hub_event链表项	
		list_del_init(tmp);	//从hub_event_list删除其
		hub = list_entry(tmp, struct usb_hub, event_list);	//根据链表项获取usb_hub	
		kref_get(&hub->kref);	//引用计数
		spin_unlock_irq(&hub_event_lock);
		hdev = hub->hdev;		//获取hub usb设备
		hub_dev = hub->intfdev;	//获取hub 设备文件
		intf = to_usb_interface(hub_dev);	//获取hub usb接口
		usb_lock_device(hdev);
		if (unlikely(hub->disconnected))
			goto loop_disconnected;
		if (hdev->state == USB_STATE_NOTATTACHED) {	//判断是否为USB_STATE_NOTATTACHED状态
			hub->error = -ENODEV;
			hub_quiesce(hub, HUB_DISCONNECT);
			goto loop;
		}
		ret = usb_autopm_get_interface(intf);
		if (ret) {
			dev_dbg(hub_dev, "Can't autoresume: %d\n", ret);
			goto loop;
		}
		if (hub->quiescing)
			goto loop_autopm;
		if (hub->error) {
			dev_dbg (hub_dev, "resetting for error %d\n",hub->error);
			ret = usb_reset_device(hdev);	
			if (ret) {
				dev_dbg (hub_dev,"error resetting hub: %d\n", ret);
				goto loop_autopm;
			}
			hub->nerrors = 0;
			hub->error = 0;
		}
		for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {
			if (test_bit(i, hub->busy_bits))
				continue;
			connect_change = test_bit(i, hub->change_bits);	//判断是否hub口状态变化
			if (!test_and_clear_bit(i, hub->event_bits) &&!connect_change)
				continue;
			ret = hub_port_status(hub, i,&portstatus, &portchange);
			if (ret < 0)
				continue;
			if (portchange & USB_PORT_STAT_C_CONNECTION) {	//hub口连接上设备
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_CONNECTION);
				connect_change = 1;
			}
			if (portchange & USB_PORT_STAT_C_ENABLE) {	//hub口的设备使能
				if (!connect_change)
					dev_dbg (hub_dev,"port %d enable change,status %08x\n",i, portstatus);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_ENABLE);
				if (!(portstatus & USB_PORT_STAT_ENABLE)&& !connect_change&& hdev->children[i-1]) {
					dev_err (hub_dev,"port %i disabled by hub (EMI?),re-enabling...\n",i);
					connect_change = 1;
				}
			}
			if (portchange & USB_PORT_STAT_C_SUSPEND) {	//hub口的设备挂起
				struct usb_device *udev;
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_SUSPEND);
				udev = hdev->children[i-1];
				if (udev) {
					msleep(10);
					usb_lock_device(udev);
					ret = usb_remote_wakeup(hdev->children[i-1]);
					usb_unlock_device(udev);
					if (ret < 0)
						connect_change = 1;
				} else {
					ret = -ENODEV;
					hub_port_disable(hub, i, 1);
				}
				dev_dbg (hub_dev,"resume on port %d, status %d\n",i, ret);
			}
			
			if (portchange & USB_PORT_STAT_C_OVERCURRENT) {	//hub口设备过流
				dev_err (hub_dev,"over-current change on port %d\n",i);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_OVER_CURRENT);
				hub_power_on(hub, true);
			}
			if (portchange & USB_PORT_STAT_C_RESET) {	//hub口设备重置
				dev_dbg (hub_dev,"reset change on port %d\n",i);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_RESET);
			}

			if (connect_change)	//hub口有变化(设备插入肯定有变化)
				hub_port_connect_change(hub, i,portstatus, portchange);	//hub口变化处理
		}
		if (test_and_clear_bit(0, hub->event_bits) == 0)
			;			
		else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
			dev_err (hub_dev, "get_hub_status failed\n");
		else {
			if (hubchange & HUB_CHANGE_LOCAL_POWER) {
				dev_dbg (hub_dev, "power change\n");
				clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
				if (hubstatus & HUB_STATUS_LOCAL_POWER)
					hub->limited_power = 1;
				else
					hub->limited_power = 0;
			}
			if (hubchange & HUB_CHANGE_OVERCURRENT) {
				dev_dbg (hub_dev, "overcurrent change\n");
				msleep(500);
				clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
                        	hub_power_on(hub, true);
			}
		}
 loop_autopm:
		usb_autopm_put_interface_no_suspend(intf);
 loop:
		usb_autopm_put_interface(intf);
 loop_disconnected:
		usb_unlock_device(hdev);
		kref_put(&hub->kref, hub_release);
        }
}

hub口状态变化处理函数

  1. static void hub_port_connect_change(struct usb_hub *hub, int port1,u16 portstatus, u16 portchange)  
  2. {  
  3.     struct usb_device *hdev = hub->hdev;  
  4.     struct device *hub_dev = hub->intfdev;  
  5.     struct usb_hcd *hcd = bus_to_hcd(hdev->bus);  
  6.     unsigned wHubCharacteristics =le16_to_cpu(hub->descriptor->wHubCharacteristics);  
  7.     struct usb_device *udev;  
  8.     int status, i;  
  9.     dev_dbg (hub_dev,"port %d, status %04x, change %04x, %s\n",port1, portstatus, portchange, portspeed (portstatus));  
  10.     if (hub->has_indicators) {  
  11.         set_port_led(hub, port1, HUB_LED_AUTO);  
  12.         hub->indicator[port1-1] = INDICATOR_AUTO;  
  13.     }  
  14. #ifdef  CONFIG_USB_OTG   
  15.     if (hdev->bus->is_b_host)  
  16.         portchange &= ~(USB_PORT_STAT_C_CONNECTION |USB_PORT_STAT_C_ENABLE);  
  17. #endif   
  18.     udev = hdev->children[port1-1];  //获取usb_device   
  19.     if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&udev->state != USB_STATE_NOTATTACHED) {  
  20.         usb_lock_device(udev);  
  21.         if (portstatus & USB_PORT_STAT_ENABLE) {  
  22.             status = 0;  
  23. #ifdef CONFIG_USB_SUSPEND   
  24.         } else if (udev->state == USB_STATE_SUSPENDED &&udev->persist_enabled) {  
  25.             status = usb_remote_wakeup(udev);  
  26. #endif   
  27.         } else {  
  28.             status = -ENODEV;  
  29.         }  
  30.         usb_unlock_device(udev);  
  31.         if (status == 0) {  
  32.             clear_bit(port1, hub->change_bits);  
  33.             return;  
  34.         }  
  35.     }  
  36.     if (udev)  
  37.         usb_disconnect(&hdev->children[port1-1]);  
  38.     clear_bit(port1, hub->change_bits);  //清除标志位   
  39.     if (!(portstatus & USB_PORT_STAT_CONNECTION) ||(portchange & USB_PORT_STAT_C_CONNECTION))  
  40.         clear_bit(port1, hub->removed_bits);  
  41.     if (portchange & (USB_PORT_STAT_C_CONNECTION |USB_PORT_STAT_C_ENABLE)) {  
  42.         status = hub_port_debounce(hub, port1);  
  43.         if (status < 0) {  
  44.             if (printk_ratelimit())  
  45.                 dev_err(hub_dev, "connect-debounce failed,port %d disabled\n", port1);  
  46.             portstatus &= ~USB_PORT_STAT_CONNECTION;  
  47.         } else {  
  48.             portstatus = status;  
  49.         }  
  50.     }  
  51.     if (!(portstatus & USB_PORT_STAT_CONNECTION) ||test_bit(port1, hub->removed_bits)) {  
  52.         if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2&& !(portstatus & USB_PORT_STAT_POWER))  
  53.             set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);  
  54.         if (portstatus & USB_PORT_STAT_ENABLE)  
  55.             goto done;  
  56.         return;  
  57.     }  
  58.     for (i = 0; i < SET_CONFIG_TRIES; i++) { //配置usb设备   
  59.         udev = usb_alloc_dev(hdev, hdev->bus, port1);        //分配usb_device   
  60.         if (!udev) {  
  61.             dev_err (hub_dev,"couldn't allocate port %d usb_device\n",port1);  
  62.             goto done;  
  63.         }  
  64.         usb_set_device_state(udev, USB_STATE_POWERED);  //设置usb设备为得电态   
  65.         udev->bus_mA = hub->mA_per_port;  //指定其电流限额   
  66.         udev->level = hdev->level + 1;    //层数为所属的hub的层数+1   
  67.         udev->wusb = hub_is_wusb(hub);  
  68.         if (!(hcd->driver->flags & HCD_USB3)) //usb设备速度   
  69.             udev->speed = USB_SPEED_UNKNOWN;  
  70.         else if ((hdev->parent == NULL) &&(portstatus & USB_PORT_STAT_SUPER_SPEED))  
  71.             udev->speed = USB_SPEED_SUPER;  
  72.         else  
  73.             udev->speed = USB_SPEED_UNKNOWN;  
  74.         choose_address(udev);   //选择一个usb设备地址   
  75.         if (udev->devnum <= 0) {  
  76.             status = -ENOTCONN; /* Don't retry */  
  77.             goto loop;  
  78.         }  
  79.         status = hub_port_init(hub, udev, port1, i);    //初始化hub端口,枚举   
  80.         if (status < 0)  
  81.             goto loop;  
  82.         usb_detect_quirks(udev);  
  83.         if (udev->quirks & USB_QUIRK_DELAY_INIT)  
  84.             msleep(1000);  
  85.         if (udev->descriptor.bDeviceClass == USB_CLASS_HUB&& udev->bus_mA <= 100) {    //若插进来的也是hub   
  86.             u16 devstat;  
  87.             status = usb_get_status(udev, USB_RECIP_DEVICE, 0,&devstat);  
  88.             if (status < 2) {  
  89.                 dev_dbg(&udev->dev, "get status %d ?\n", status);  
  90.                 goto loop_disable;  
  91.             }  
  92.             le16_to_cpus(&devstat);  
  93.             if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {  
  94.                 dev_err(&udev->dev,"can't connect bus-powered hub to this port\n");  
  95.                 if (hub->has_indicators) {  
  96.                     hub->indicator[port1-1] =INDICATOR_AMBER_BLINK;  
  97.                     schedule_delayed_work (&hub->leds, 0);  
  98.                 }  
  99.                 status = -ENOTCONN;  
  100.                 goto loop_disable;  
  101.             }  
  102.         }  
  103.         if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200&& udev->speed == USB_SPEED_FULL&& highspeed_hubs != 0)  
  104.             check_highspeed (hub, udev, port1);  
  105.         status = 0;  
  106.         spin_lock_irq(&device_state_lock);  
  107.         if (hdev->state == USB_STATE_NOTATTACHED)  
  108.             status = -ENOTCONN;  
  109.         else  
  110.             hdev->children[port1-1] = udev;  //设置hub usb设备的子设备   
  111.         spin_unlock_irq(&device_state_lock);  
  112.         if (!status) {  
  113.             status = usb_new_device(udev);  //usb添加新设备   
  114.             if (status) {  
  115.                 spin_lock_irq(&device_state_lock);  
  116.                 hdev->children[port1-1] = NULL;  
  117.                 spin_unlock_irq(&device_state_lock);  
  118.             }  
  119.         }  
  120.         if (status)  
  121.             goto loop_disable;  
  122.         status = hub_power_remaining(hub);  
  123.         if (status)  
  124.             dev_dbg(hub_dev, "%dmA power budget left\n", status);  
  125.         return;  
  126. loop_disable:  
  127.         hub_port_disable(hub, port1, 1);  
  128. loop:  
  129.         usb_ep0_reinit(udev);  
  130.         release_address(udev);  
  131.         hub_free_dev(udev);  
  132.         usb_put_dev(udev);  
  133.         if ((status == -ENOTCONN) || (status == -ENOTSUPP))  
  134.             break;  
  135.     }  
  136.     if (hub->hdev->parent ||!hcd->driver->port_handed_over ||!(hcd->driver->port_handed_over)(hcd, port1))  
  137.         dev_err(hub_dev, "unable to enumerate USB device on port %d\n",port1);  
  138.  done:  
  139.     hub_port_disable(hub, port1, 1);  
  140.     if (hcd->driver->relinquish_port && !hub->hdev->parent)  
  141.         hcd->driver->relinquish_port(hcd, port1);  
  142. }  
static void hub_port_connect_change(struct usb_hub *hub, int port1,u16 portstatus, u16 portchange)
{
	struct usb_device *hdev = hub->hdev;
	struct device *hub_dev = hub->intfdev;
	struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
	unsigned wHubCharacteristics =le16_to_cpu(hub->descriptor->wHubCharacteristics);
	struct usb_device *udev;
	int status, i;
	dev_dbg (hub_dev,"port %d, status %04x, change %04x, %s\n",port1, portstatus, portchange, portspeed (portstatus));
	if (hub->has_indicators) {
		set_port_led(hub, port1, HUB_LED_AUTO);
		hub->indicator[port1-1] = INDICATOR_AUTO;
	}
#ifdef	CONFIG_USB_OTG
	if (hdev->bus->is_b_host)
		portchange &= ~(USB_PORT_STAT_C_CONNECTION |USB_PORT_STAT_C_ENABLE);
#endif
	udev = hdev->children[port1-1];	//获取usb_device
	if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&udev->state != USB_STATE_NOTATTACHED) {
		usb_lock_device(udev);
		if (portstatus & USB_PORT_STAT_ENABLE) {
			status = 0;
#ifdef CONFIG_USB_SUSPEND
		} else if (udev->state == USB_STATE_SUSPENDED &&udev->persist_enabled) {
			status = usb_remote_wakeup(udev);
#endif
		} else {
			status = -ENODEV;
		}
		usb_unlock_device(udev);
		if (status == 0) {
			clear_bit(port1, hub->change_bits);
			return;
		}
	}
	if (udev)
		usb_disconnect(&hdev->children[port1-1]);
	clear_bit(port1, hub->change_bits);	//清除标志位
	if (!(portstatus & USB_PORT_STAT_CONNECTION) ||(portchange & USB_PORT_STAT_C_CONNECTION))
		clear_bit(port1, hub->removed_bits);
	if (portchange & (USB_PORT_STAT_C_CONNECTION |USB_PORT_STAT_C_ENABLE)) {
		status = hub_port_debounce(hub, port1);
		if (status < 0) {
			if (printk_ratelimit())
				dev_err(hub_dev, "connect-debounce failed,port %d disabled\n", port1);
			portstatus &= ~USB_PORT_STAT_CONNECTION;
		} else {
			portstatus = status;
		}
	}
	if (!(portstatus & USB_PORT_STAT_CONNECTION) ||test_bit(port1, hub->removed_bits)) {
		if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2&& !(portstatus & USB_PORT_STAT_POWER))
			set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
		if (portstatus & USB_PORT_STAT_ENABLE)
  			goto done;
		return;
	}
	for (i = 0; i < SET_CONFIG_TRIES; i++) {	//配置usb设备
		udev = usb_alloc_dev(hdev, hdev->bus, port1);		//分配usb_device
		if (!udev) {
			dev_err (hub_dev,"couldn't allocate port %d usb_device\n",port1);
			goto done;
		}
		usb_set_device_state(udev, USB_STATE_POWERED);	//设置usb设备为得电态
 		udev->bus_mA = hub->mA_per_port;	//指定其电流限额
		udev->level = hdev->level + 1;	//层数为所属的hub的层数+1
		udev->wusb = hub_is_wusb(hub);
		if (!(hcd->driver->flags & HCD_USB3))	//usb设备速度
			udev->speed = USB_SPEED_UNKNOWN;
		else if ((hdev->parent == NULL) &&(portstatus & USB_PORT_STAT_SUPER_SPEED))
			udev->speed = USB_SPEED_SUPER;
		else
			udev->speed = USB_SPEED_UNKNOWN;
		choose_address(udev);	//选择一个usb设备地址
		if (udev->devnum <= 0) {
			status = -ENOTCONN;	/* Don't retry */
			goto loop;
		}
		status = hub_port_init(hub, udev, port1, i);	//初始化hub端口,枚举
		if (status < 0)
			goto loop;
		usb_detect_quirks(udev);
		if (udev->quirks & USB_QUIRK_DELAY_INIT)
			msleep(1000);
		if (udev->descriptor.bDeviceClass == USB_CLASS_HUB&& udev->bus_mA <= 100) {	//若插进来的也是hub
			u16	devstat;
			status = usb_get_status(udev, USB_RECIP_DEVICE, 0,&devstat);
			if (status < 2) {
				dev_dbg(&udev->dev, "get status %d ?\n", status);
				goto loop_disable;
			}
			le16_to_cpus(&devstat);
			if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
				dev_err(&udev->dev,"can't connect bus-powered hub to this port\n");
				if (hub->has_indicators) {
					hub->indicator[port1-1] =INDICATOR_AMBER_BLINK;
					schedule_delayed_work (&hub->leds, 0);
				}
				status = -ENOTCONN;
				goto loop_disable;
			}
		}
 		if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200&& udev->speed == USB_SPEED_FULL&& highspeed_hubs != 0)
			check_highspeed (hub, udev, port1);
		status = 0;
		spin_lock_irq(&device_state_lock);
		if (hdev->state == USB_STATE_NOTATTACHED)
			status = -ENOTCONN;
		else
			hdev->children[port1-1] = udev;	//设置hub usb设备的子设备
		spin_unlock_irq(&device_state_lock);
		if (!status) {
			status = usb_new_device(udev);	//usb添加新设备
			if (status) {
				spin_lock_irq(&device_state_lock);
				hdev->children[port1-1] = NULL;
				spin_unlock_irq(&device_state_lock);
			}
		}
		if (status)
			goto loop_disable;
		status = hub_power_remaining(hub);
		if (status)
			dev_dbg(hub_dev, "%dmA power budget left\n", status);
		return;
loop_disable:
		hub_port_disable(hub, port1, 1);
loop:
		usb_ep0_reinit(udev);
		release_address(udev);
		hub_free_dev(udev);
		usb_put_dev(udev);
		if ((status == -ENOTCONN) || (status == -ENOTSUPP))
			break;
	}
	if (hub->hdev->parent ||!hcd->driver->port_handed_over ||!(hcd->driver->port_handed_over)(hcd, port1))
		dev_err(hub_dev, "unable to enumerate USB device on port %d\n",port1);
 done:
	hub_port_disable(hub, port1, 1);
	if (hcd->driver->relinquish_port && !hub->hdev->parent)
		hcd->driver->relinquish_port(hcd, port1);
}

hub端口初始化

  1. static int hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,int retry_counter)  
  2. {  
  3.     static DEFINE_MUTEX(usb_address0_mutex);  
  4.     struct usb_device   *hdev = hub->hdev;  
  5.     struct usb_hcd *hcd = bus_to_hcd(hdev->bus);  
  6.     int i, j, retval;  
  7.     unsigned    delay = HUB_SHORT_RESET_TIME;  
  8.     enum usb_device_speed oldspeed = udev->speed;  
  9.     char *speed, *type;  
  10.     int devnum = udev->devnum;  
  11.     if (!hdev->parent) {  
  12.         delay = HUB_ROOT_RESET_TIME;  
  13.         if (port1 == hdev->bus->otg_port)  
  14.             hdev->bus->b_hnp_enable = 0;  
  15.     }  
  16.     if (oldspeed == USB_SPEED_LOW)  
  17.         delay = HUB_LONG_RESET_TIME;  
  18.     mutex_lock(&usb_address0_mutex);  
  19.     if (!udev->config && oldspeed == USB_SPEED_SUPER) {  
  20.         usb_set_device_state(udev, USB_STATE_DEFAULT);  
  21.     } else {  
  22.         retval = hub_port_reset(hub, port1, udev, delay);  
  23.         if (retval < 0)  
  24.             goto fail;  
  25.     }  
  26.     retval = -ENODEV;  
  27.     if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) {  
  28.         dev_dbg(&udev->dev, "device reset changed speed!\n");  
  29.         goto fail;  
  30.     }  
  31.     oldspeed = udev->speed;  
  32.     switch (udev->speed) {  
  33.     case USB_SPEED_SUPER:  
  34.     case USB_SPEED_WIRELESS:  
  35.         udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);  
  36.         break;  
  37.     case USB_SPEED_HIGH:  
  38.         udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);  
  39.         break;  
  40.     case USB_SPEED_FULL:  
  41.         udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);  
  42.         break;  
  43.     case USB_SPEED_LOW:  
  44.         udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);  
  45.         break;  
  46.     default:  
  47.         goto fail;  
  48.     }  
  49.     type = "";  
  50.     switch (udev->speed) {  
  51.     case USB_SPEED_LOW: speed = "low";  break;  
  52.     case USB_SPEED_FULL:    speed = "full"break;  
  53.     case USB_SPEED_HIGH:    speed = "high"break;  
  54.     case USB_SPEED_SUPER:   speed = "super";    break;  
  55.     case USB_SPEED_WIRELESS:    speed = "variable"; type = "Wireless "break;  
  56.     default:    speed = "?";    break;  
  57.     }  
  58.     if (udev->speed != USB_SPEED_SUPER)  
  59.         dev_info(&udev->dev,"%s %s speed %sUSB device using %s and address %d\n",  
  60.         (udev->config) ? "reset" : "new", speed, type,udev->bus->controller->driver->name, devnum);  
  61.     if (hdev->tt) {  
  62.         udev->tt = hdev->tt;  
  63.         udev->ttport = hdev->ttport;  
  64.     } else if (udev->speed != USB_SPEED_HIGH&& hdev->speed == USB_SPEED_HIGH) {  
  65.         udev->tt = &hub->tt;  
  66.         udev->ttport = port1;  
  67.     }  
  68.     for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {  
  69.         if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) {  
  70.             struct usb_device_descriptor *buf;  
  71.             int r = 0;  
  72. #define GET_DESCRIPTOR_BUFSIZE  64   
  73.             buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);  
  74.             if (!buf) {  
  75.                 retval = -ENOMEM;  
  76.                 continue;  
  77.             }  
  78.             for (j = 0; j < 3; ++j) {  
  79.                 buf->bMaxPacketSize0 = 0;  
  80.                 r = usb_control_msg(udev, usb_rcvaddr0pipe(),USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,  
  81.                     USB_DT_DEVICE << 8, 0,buf, GET_DESCRIPTOR_BUFSIZE,initial_descriptor_timeout);  
  82.                 //获取描述符   
  83.                 switch (buf->bMaxPacketSize0) {  
  84.                 case 8: case 16: case 32: case 64: case 255:  
  85.                     if (buf->bDescriptorType == USB_DT_DEVICE) {  
  86.                         r = 0;  
  87.                         break;  
  88.                     }  
  89.                 default:  
  90.                     if (r == 0)  
  91.                         r = -EPROTO;  
  92.                     break;  
  93.                 }  
  94.                 if (r == 0)  
  95.                     break;  
  96.             }  
  97.             udev->descriptor.bMaxPacketSize0 = buf->bMaxPacketSize0;  
  98.             kfree(buf);  
  99.             retval = hub_port_reset(hub, port1, udev, delay);  
  100.             if (retval < 0)  
  101.                 goto fail;  
  102.             if (oldspeed != udev->speed) {  
  103.                 dev_dbg(&udev->dev,"device reset changed speed!\n");  
  104.                 retval = -ENODEV;  
  105.                 goto fail;  
  106.             }  
  107.             if (r) {  
  108.                 dev_err(&udev->dev,"device descriptor read/64, error %d\n",r);  
  109.                 retval = -EMSGSIZE;  
  110.                 continue;  
  111.             }  
  112. #undef GET_DESCRIPTOR_BUFSIZE   
  113.         }  
  114.         if (udev->wusb == 0) {  
  115.             for (j = 0; j < SET_ADDRESS_TRIES; ++j) {  
  116.                 retval = hub_set_address(udev, devnum); //hub设置usb地址并告诉usb设备   
  117.                 if (retval >= 0)  
  118.                     break;  
  119.                 msleep(200);  
  120.             }  
  121.             if (retval < 0) {  
  122.                 dev_err(&udev->dev,"device not accepting address %d, error %d\n",devnum, retval);  
  123.                 goto fail;  
  124.             }  
  125.             if (udev->speed == USB_SPEED_SUPER) {  
  126.                 devnum = udev->devnum;  
  127.                 dev_info(&udev->dev,"%s SuperSpeed USB device using %s and address %d\n",  
  128.                 (udev->config) ? "reset" : "new",udev->bus->controller->driver->name, devnum);  
  129.             }  
  130.             msleep(10);  
  131.             if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3))  
  132.                 break;  
  133.         }  
  134.   
  135.         retval = usb_get_device_descriptor(udev, 8);    //获取设备描述符先读8字节   
  136.         if (retval < 8) {  
  137.             dev_err(&udev->dev,"device descriptor read/8, error %d\n",retval);  
  138.             if (retval >= 0)  
  139.                 retval = -EMSGSIZE;  
  140.         } else {  
  141.             retval = 0;  
  142.             break;  
  143.         }  
  144.     }  
  145.     if (retval)  
  146.         goto fail;  
  147.     if (udev->descriptor.bMaxPacketSize0 == 0xff ||  
  148.             udev->speed == USB_SPEED_SUPER)  
  149.         i = 512;  
  150.     else  
  151.         i = udev->descriptor.bMaxPacketSize0;  
  152.     if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {  
  153.         if (udev->speed == USB_SPEED_LOW ||!(i == 8 || i == 16 || i == 32 || i == 64)) {  
  154.             dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i);  
  155.             retval = -EMSGSIZE;  
  156.             goto fail;  
  157.         }  
  158.         if (udev->speed == USB_SPEED_FULL)  
  159.             dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);  
  160.         else  
  161.             dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);  
  162.         udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);  
  163.         usb_ep0_reinit(udev);  
  164.     }  
  165.     retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);   //再次获取设备描述符   
  166.     if (retval < (signed)sizeof(udev->descriptor)) {  
  167.         dev_err(&udev->dev, "device descriptor read/all, error %d\n",  
  168.             retval);  
  169.         if (retval >= 0)  
  170.             retval = -ENOMSG;  
  171.         goto fail;  
  172.     }  
  173.     retval = 0;  
  174.     if (hcd->driver->update_device)  
  175.         hcd->driver->update_device(hcd, udev);  
  176. fail:  
  177.     if (retval) {  
  178.         hub_port_disable(hub, port1, 0);  
  179.         update_address(udev, devnum);   /* for disconnect processing */  
  180.     }  
  181.     mutex_unlock(&usb_address0_mutex);  
  182.     return retval;  
  183. }  
static int hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,int retry_counter)
{
	static DEFINE_MUTEX(usb_address0_mutex);
	struct usb_device	*hdev = hub->hdev;
	struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
	int i, j, retval;
	unsigned	delay = HUB_SHORT_RESET_TIME;
	enum usb_device_speed oldspeed = udev->speed;
	char *speed, *type;
	int devnum = udev->devnum;
	if (!hdev->parent) {
		delay = HUB_ROOT_RESET_TIME;
		if (port1 == hdev->bus->otg_port)
			hdev->bus->b_hnp_enable = 0;
	}
	if (oldspeed == USB_SPEED_LOW)
		delay = HUB_LONG_RESET_TIME;
	mutex_lock(&usb_address0_mutex);
	if (!udev->config && oldspeed == USB_SPEED_SUPER) {
		usb_set_device_state(udev, USB_STATE_DEFAULT);
	} else {
		retval = hub_port_reset(hub, port1, udev, delay);
		if (retval < 0)
			goto fail;
	}
	retval = -ENODEV;
	if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) {
		dev_dbg(&udev->dev, "device reset changed speed!\n");
		goto fail;
	}
	oldspeed = udev->speed;
	switch (udev->speed) {
	case USB_SPEED_SUPER:
	case USB_SPEED_WIRELESS:
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
		break;
	case USB_SPEED_HIGH:
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
		break;
	case USB_SPEED_FULL:
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
		break;
	case USB_SPEED_LOW:
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
		break;
	default:
		goto fail;
	}
 	type = "";
	switch (udev->speed) {
	case USB_SPEED_LOW:	speed = "low";	break;
	case USB_SPEED_FULL:	speed = "full";	break;
	case USB_SPEED_HIGH:	speed = "high";	break;
	case USB_SPEED_SUPER:	speed = "super";	break;
	case USB_SPEED_WIRELESS:	speed = "variable";	type = "Wireless ";	break;
	default: 	speed = "?";	break;
	}
	if (udev->speed != USB_SPEED_SUPER)
		dev_info(&udev->dev,"%s %s speed %sUSB device using %s and address %d\n",
		(udev->config) ? "reset" : "new", speed, type,udev->bus->controller->driver->name, devnum);
	if (hdev->tt) {
		udev->tt = hdev->tt;
		udev->ttport = hdev->ttport;
	} else if (udev->speed != USB_SPEED_HIGH&& hdev->speed == USB_SPEED_HIGH) {
		udev->tt = &hub->tt;
		udev->ttport = port1;
	}
 	for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
		if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) {
			struct usb_device_descriptor *buf;
			int r = 0;
#define GET_DESCRIPTOR_BUFSIZE	64
			buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);
			if (!buf) {
				retval = -ENOMEM;
				continue;
			}
			for (j = 0; j < 3; ++j) {
				buf->bMaxPacketSize0 = 0;
				r = usb_control_msg(udev, usb_rcvaddr0pipe(),USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
					USB_DT_DEVICE << 8, 0,buf, GET_DESCRIPTOR_BUFSIZE,initial_descriptor_timeout);
				//获取描述符
				switch (buf->bMaxPacketSize0) {
				case 8: case 16: case 32: case 64: case 255:
					if (buf->bDescriptorType == USB_DT_DEVICE) {
						r = 0;
						break;
					}
				default:
					if (r == 0)
						r = -EPROTO;
					break;
				}
				if (r == 0)
					break;
			}
			udev->descriptor.bMaxPacketSize0 = buf->bMaxPacketSize0;
			kfree(buf);
			retval = hub_port_reset(hub, port1, udev, delay);
			if (retval < 0)
				goto fail;
			if (oldspeed != udev->speed) {
				dev_dbg(&udev->dev,"device reset changed speed!\n");
				retval = -ENODEV;
				goto fail;
			}
			if (r) {
				dev_err(&udev->dev,"device descriptor read/64, error %d\n",r);
				retval = -EMSGSIZE;
				continue;
			}
#undef GET_DESCRIPTOR_BUFSIZE
		}
		if (udev->wusb == 0) {
			for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
				retval = hub_set_address(udev, devnum);	//hub设置usb地址并告诉usb设备
				if (retval >= 0)
					break;
				msleep(200);
			}
			if (retval < 0) {
				dev_err(&udev->dev,"device not accepting address %d, error %d\n",devnum, retval);
				goto fail;
			}
			if (udev->speed == USB_SPEED_SUPER) {
				devnum = udev->devnum;
				dev_info(&udev->dev,"%s SuperSpeed USB device using %s and address %d\n",
				(udev->config) ? "reset" : "new",udev->bus->controller->driver->name, devnum);
			}
			msleep(10);
			if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3))
				break;
  		}

		retval = usb_get_device_descriptor(udev, 8);	//获取设备描述符先读8字节
		if (retval < 8) {
			dev_err(&udev->dev,"device descriptor read/8, error %d\n",retval);
			if (retval >= 0)
				retval = -EMSGSIZE;
		} else {
			retval = 0;
			break;
		}
	}
	if (retval)
		goto fail;
	if (udev->descriptor.bMaxPacketSize0 == 0xff ||
			udev->speed == USB_SPEED_SUPER)
		i = 512;
	else
		i = udev->descriptor.bMaxPacketSize0;
	if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
		if (udev->speed == USB_SPEED_LOW ||!(i == 8 || i == 16 || i == 32 || i == 64)) {
			dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i);
			retval = -EMSGSIZE;
			goto fail;
		}
		if (udev->speed == USB_SPEED_FULL)
			dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
		else
			dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
		usb_ep0_reinit(udev);
	}
  	retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);	//再次获取设备描述符
	if (retval < (signed)sizeof(udev->descriptor)) {
		dev_err(&udev->dev, "device descriptor read/all, error %d\n",
			retval);
		if (retval >= 0)
			retval = -ENOMSG;
		goto fail;
	}
	retval = 0;
	if (hcd->driver->update_device)
		hcd->driver->update_device(hcd, udev);
fail:
	if (retval) {
		hub_port_disable(hub, port1, 0);
		update_address(udev, devnum);	/* for disconnect processing */
	}
	mutex_unlock(&usb_address0_mutex);
	return retval;
}

usb_new_device

  1. int usb_new_device(struct usb_device *udev)  
  2. {  
  3.     int err;  
  4.     if (udev->parent) {  
  5.         device_init_wakeup(&udev->dev, 0);  
  6.     }  
  7.     pm_runtime_set_active(&udev->dev);  
  8.     pm_runtime_enable(&udev->dev);  
  9.     err = usb_enumerate_device(udev);   //读取usb设备的描述符信息   
  10.     if (err < 0)  
  11.         goto fail;  
  12.     dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",udev->devnum, udev->bus->busnum,  
  13.             (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));  
  14.     udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));    //分配设备号   
  15.     announce_device(udev);  //打印usb设备厂商啊啥的信息   
  16.     device_enable_async_suspend(&udev->dev);  
  17.     err = device_add(&udev->dev);    //添加设备(至此usb枚举完了)-->usb设备与驱动的匹配   
  18.     if (err) {  
  19.         dev_err(&udev->dev, "can't device_add, error %d\n", err);  
  20.         goto fail;  
  21.     }  
  22.     (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);  
  23.     return err;  
  24.   
  25. fail:  
  26.     usb_set_device_state(udev, USB_STATE_NOTATTACHED);  
  27.     pm_runtime_disable(&udev->dev);  
  28.     pm_runtime_set_suspended(&udev->dev);  
  29.     return err;  
  30. }  
int usb_new_device(struct usb_device *udev)
{
	int err;
	if (udev->parent) {
		device_init_wakeup(&udev->dev, 0);
	}
	pm_runtime_set_active(&udev->dev);
	pm_runtime_enable(&udev->dev);
	err = usb_enumerate_device(udev);	//读取usb设备的描述符信息
	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)));
	udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));	//分配设备号
	announce_device(udev);	//打印usb设备厂商啊啥的信息
	device_enable_async_suspend(&udev->dev);
	err = device_add(&udev->dev);	//添加设备(至此usb枚举完了)-->usb设备与驱动的匹配
	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);
	return err;

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

usb_enumerate_device

  1. static int usb_enumerate_device(struct usb_device *udev)  
  2. {  
  3.     int err;  
  4.     if (udev->config == NULL) {  
  5.         err = usb_get_configuration(udev);  //usb获取配置描述符   
  6.         if (err < 0) {  
  7.             dev_err(&udev->dev, "can't read configurations, error %d\n",err);  
  8.             goto fail;  
  9.         }  
  10.     }  
  11.     if (udev->wusb == 1 && udev->authorized == 0) {  
  12.         udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);  
  13.         udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);  
  14.         udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);  
  15.     }  
  16.     else {  
  17.         udev->product = usb_cache_string(udev, udev->descriptor.iProduct);    //设置产品id   
  18.         udev->manufacturer = usb_cache_string(udev,udev->descriptor.iManufacturer);   //设置厂商id   
  19.         udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);    //设置产品序列号   
  20.     }  
  21.     err = usb_enumerate_device_otg(udev);  
  22. fail:  
  23.     return err;  
  24. }  
static int usb_enumerate_device(struct usb_device *udev)
{
	int err;
	if (udev->config == NULL) {
		err = usb_get_configuration(udev);	//usb获取配置描述符
		if (err < 0) {
			dev_err(&udev->dev, "can't read configurations, error %d\n",err);
			goto fail;
		}
	}
	if (udev->wusb == 1 && udev->authorized == 0) {
		udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
		udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
		udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
	}
	else {
		udev->product = usb_cache_string(udev, udev->descriptor.iProduct);	//设置产品id
		udev->manufacturer = usb_cache_string(udev,udev->descriptor.iManufacturer);	//设置厂商id
		udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);	//设置产品序列号
	}
	err = usb_enumerate_device_otg(udev);
fail:
	return err;
}

device_add函数会出发总线的通知链发送通知,最终会调用总线的match方法

usb设备和驱动一旦match,则会调用驱动的drvwrap.driver.probe方法

若是设备则调用usb_probe_device

若是接口则调用usb_probe_interface
这里我们调用的是usb接口的,也就是usb_probe_interface

  1. static int usb_probe_interface(struct device *dev)  
  2. {  
  3.     struct usb_driver *driver = to_usb_driver(dev->driver);  
  4.     struct usb_interface *intf = to_usb_interface(dev);  
  5.     struct usb_device *udev = interface_to_usbdev(intf);  
  6.     const struct usb_device_id *id;  
  7.     int error = -ENODEV;  
  8.     dev_dbg(dev, "%s\n", __func__);  
  9.     intf->needs_binding = 0;  
  10.     if (usb_device_is_owned(udev))  
  11.         return error;  
  12.     if (udev->authorized == 0) {  
  13.         dev_err(&intf->dev, "Device is not authorized for usage\n");  
  14.         return error;  
  15.     }  
  16.     id = usb_match_id(intf, driver->id_table);   //静态id匹配   
  17.     if (!id)  
  18.         id = usb_match_dynamic_id(intf, driver);    //动态id匹配   
  19.     if (!id)  
  20.         return error;  
  21.     dev_dbg(dev, "%s - got id\n", __func__);  
  22.     error = usb_autoresume_device(udev);  
  23.     if (error)  
  24.         return error;  
  25.     intf->condition = USB_INTERFACE_BINDING;  
  26.     pm_runtime_set_active(dev);  
  27.     pm_suspend_ignore_children(dev, false);  
  28.     if (driver->supports_autosuspend)  
  29.         pm_runtime_enable(dev);  
  30.     if (intf->needs_altsetting0) {  
  31.         error = usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);  
  32.         if (error < 0)  
  33.             goto err;  
  34.         intf->needs_altsetting0 = 0;  
  35.     }  
  36.     error = driver->probe(intf, id); //最终调用usb驱动的probe方法   
  37.     if (error)  
  38.         goto err;  
  39.     intf->condition = USB_INTERFACE_BOUND;  
  40.     usb_autosuspend_device(udev);  
  41.     return error;  
  42. err:  
  43.     intf->needs_remote_wakeup = 0;  
  44.     intf->condition = USB_INTERFACE_UNBOUND;  
  45.     usb_cancel_queued_reset(intf);  
  46.     if (driver->supports_autosuspend)  
  47.         pm_runtime_disable(dev);  
  48.     pm_runtime_set_suspended(dev);  
  49.     usb_autosuspend_device(udev);  
  50.     return error;  
  51. }  
static int usb_probe_interface(struct device *dev)
{
	struct usb_driver *driver = to_usb_driver(dev->driver);
	struct usb_interface *intf = to_usb_interface(dev);
	struct usb_device *udev = interface_to_usbdev(intf);
	const struct usb_device_id *id;
	int error = -ENODEV;
	dev_dbg(dev, "%s\n", __func__);
	intf->needs_binding = 0;
	if (usb_device_is_owned(udev))
		return error;
	if (udev->authorized == 0) {
		dev_err(&intf->dev, "Device is not authorized for usage\n");
		return error;
	}
	id = usb_match_id(intf, driver->id_table);	//静态id匹配
	if (!id)
		id = usb_match_dynamic_id(intf, driver);	//动态id匹配
	if (!id)
		return error;
	dev_dbg(dev, "%s - got id\n", __func__);
	error = usb_autoresume_device(udev);
	if (error)
		return error;
	intf->condition = USB_INTERFACE_BINDING;
	pm_runtime_set_active(dev);
	pm_suspend_ignore_children(dev, false);
	if (driver->supports_autosuspend)
		pm_runtime_enable(dev);
	if (intf->needs_altsetting0) {
		error = usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
		if (error < 0)
			goto err;
		intf->needs_altsetting0 = 0;
	}
	error = driver->probe(intf, id);	//最终调用usb驱动的probe方法
	if (error)
		goto err;
	intf->condition = USB_INTERFACE_BOUND;
	usb_autosuspend_device(udev);
	return error;
err:
	intf->needs_remote_wakeup = 0;
	intf->condition = USB_INTERFACE_UNBOUND;
	usb_cancel_queued_reset(intf);
	if (driver->supports_autosuspend)
		pm_runtime_disable(dev);
	pm_runtime_set_suspended(dev);
	usb_autosuspend_device(udev);
	return error;
}

一般在usb设备驱动的probe方法中会调用usb_alloc_urb分配urb

usb_fill_int_urb
usb_fill_bulk_urb
usb_fill_control_urb
填充urb

然后用usb_submit_urb提交urb

  1. int usb_submit_urb(struct urb *urb, gfp_t mem_flags)  
  2. {  
  3.     int xfertype, max;  
  4.     struct usb_device   *dev;  
  5.     struct usb_host_endpoint    *ep;  
  6.     int is_out;  
  7.     if (!urb || urb->hcpriv || !urb->complete)  
  8.         return -EINVAL;  
  9.     dev = urb->dev;  
  10.     if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))  
  11.         return -ENODEV;  
  12.     ep = usb_pipe_endpoint(dev, urb->pipe);  //获取端点   
  13.     if (!ep)  
  14.         return -ENOENT;  
  15.     urb->ep = ep;    //设置端点   
  16.     urb->status = -EINPROGRESS;  
  17.     urb->actual_length = 0;  
  18.     xfertype = usb_endpoint_type(&ep->desc);  
  19.     if (xfertype == USB_ENDPOINT_XFER_CONTROL) {    //控制传输   
  20.         struct usb_ctrlrequest *setup =(struct usb_ctrlrequest *) urb->setup_packet; //设置setup包   
  21.         if (!setup)  
  22.             return -ENOEXEC;  
  23.         is_out = !(setup->bRequestType & USB_DIR_IN) ||!setup->wLength;  
  24.     } else {  
  25.         is_out = usb_endpoint_dir_out(&ep->desc);  
  26.     }  
  27.   
  28.     urb->transfer_flags &= ~(URB_DIR_MASK | URB_DMA_MAP_SINGLE |URB_DMA_MAP_PAGE | URB_DMA_MAP_SG | URB_MAP_LOCAL |  
  29.             URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |URB_DMA_SG_COMBINED);  
  30.     urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN);  //输入还是输出端点   
  31.     if (xfertype != USB_ENDPOINT_XFER_CONTROL &&dev->state < USB_STATE_CONFIGURED)  
  32.         return -ENODEV;  
  33.     max = le16_to_cpu(ep->desc.wMaxPacketSize);  
  34.     if (max <= 0) {  
  35.         dev_dbg(&dev->dev,"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",  
  36.             usb_endpoint_num(&ep->desc), is_out ? "out" : "in",__func__, max);  
  37.         return -EMSGSIZE;  
  38.     }  
  39.     if (xfertype == USB_ENDPOINT_XFER_ISOC) {   //同步传输   
  40.         int n, len;  
  41.         if (dev->speed == USB_SPEED_HIGH) {  
  42.             int mult = 1 + ((max >> 11) & 0x03);  
  43.             max &= 0x07ff;  
  44.             max *= mult;  
  45.         }  
  46.         if (urb->number_of_packets <= 0)  
  47.             return -EINVAL;  
  48.         for (n = 0; n < urb->number_of_packets; n++) {  
  49.             len = urb->iso_frame_desc[n].length;  
  50.             if (len < 0 || len > max)  
  51.                 return -EMSGSIZE;  
  52.             urb->iso_frame_desc[n].status = -EXDEV;  
  53.             urb->iso_frame_desc[n].actual_length = 0;  
  54.         }  
  55.     }  
  56.     if (urb->transfer_buffer_length > INT_MAX)  
  57.         return -EMSGSIZE;  
  58.     switch (xfertype) { //传输类型   
  59.     case USB_ENDPOINT_XFER_ISOC:    //同步传输   
  60.     case USB_ENDPOINT_XFER_INT:     //中断传输   
  61.         switch (dev->speed) {  
  62.         case USB_SPEED_WIRELESS:    //无线?   
  63.             if (urb->interval < 6)  
  64.                 return -EINVAL;  
  65.             break;  
  66.         default:  
  67.             if (urb->interval <= 0)  
  68.                 return -EINVAL;  
  69.             break;  
  70.         }  
  71.         switch (dev->speed) {  
  72.         case USB_SPEED_SUPER:   //超速设备   
  73.             if (urb->interval > (1 << 15))  
  74.                 return -EINVAL;  
  75.             max = 1 << 15;  
  76.             break;  
  77.         case USB_SPEED_WIRELESS:    //无线?   
  78.             if (urb->interval > 16)  
  79.                 return -EINVAL;  
  80.             break;  
  81.         case USB_SPEED_HIGH:    //高速设备   
  82.             if (urb->interval > (1024 * 8))  
  83.                 urb->interval = 1024 * 8;  
  84.             max = 1024 * 8;  
  85.             break;  
  86.         case USB_SPEED_FULL:    //全速   
  87.         case USB_SPEED_LOW:     //低速   
  88.             if (xfertype == USB_ENDPOINT_XFER_INT) {  
  89.                 if (urb->interval > 255)  
  90.                     return -EINVAL;  
  91.                 max = 128;  
  92.             } else {  
  93.                 if (urb->interval > 1024)  
  94.                     urb->interval = 1024;  
  95.   
  96.                 max = 1024;  
  97.             }  
  98.             break;  
  99.         default:  
  100.             return -EINVAL;  
  101.         }  
  102.         if (dev->speed != USB_SPEED_WIRELESS) {  
  103.             urb->interval = min(max, 1 << ilog2(urb->interval));  
  104.         }  
  105.     }  
  106.     return usb_hcd_submit_urb(urb, mem_flags);  
  107. }  
int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
	int	xfertype, max;
	struct usb_device	*dev;
	struct usb_host_endpoint	*ep;
	int	is_out;
	if (!urb || urb->hcpriv || !urb->complete)
		return -EINVAL;
	dev = urb->dev;
	if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
		return -ENODEV;
	ep = usb_pipe_endpoint(dev, urb->pipe);	//获取端点
	if (!ep)
		return -ENOENT;
	urb->ep = ep;	//设置端点
	urb->status = -EINPROGRESS;
	urb->actual_length = 0;
	xfertype = usb_endpoint_type(&ep->desc);
	if (xfertype == USB_ENDPOINT_XFER_CONTROL) {	//控制传输
		struct usb_ctrlrequest *setup =(struct usb_ctrlrequest *) urb->setup_packet;	//设置setup包
		if (!setup)
			return -ENOEXEC;
		is_out = !(setup->bRequestType & USB_DIR_IN) ||!setup->wLength;
	} else {
		is_out = usb_endpoint_dir_out(&ep->desc);
	}

	urb->transfer_flags &= ~(URB_DIR_MASK | URB_DMA_MAP_SINGLE |URB_DMA_MAP_PAGE | URB_DMA_MAP_SG | URB_MAP_LOCAL |
			URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |URB_DMA_SG_COMBINED);
	urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN);	//输入还是输出端点
	if (xfertype != USB_ENDPOINT_XFER_CONTROL &&dev->state < USB_STATE_CONFIGURED)
		return -ENODEV;
	max = le16_to_cpu(ep->desc.wMaxPacketSize);
	if (max <= 0) {
		dev_dbg(&dev->dev,"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
			usb_endpoint_num(&ep->desc), is_out ? "out" : "in",__func__, max);
		return -EMSGSIZE;
	}
	if (xfertype == USB_ENDPOINT_XFER_ISOC) {	//同步传输
		int	n, len;
		if (dev->speed == USB_SPEED_HIGH) {
			int	mult = 1 + ((max >> 11) & 0x03);
			max &= 0x07ff;
			max *= mult;
		}
		if (urb->number_of_packets <= 0)
			return -EINVAL;
		for (n = 0; n < urb->number_of_packets; n++) {
			len = urb->iso_frame_desc[n].length;
			if (len < 0 || len > max)
				return -EMSGSIZE;
			urb->iso_frame_desc[n].status = -EXDEV;
			urb->iso_frame_desc[n].actual_length = 0;
		}
	}
	if (urb->transfer_buffer_length > INT_MAX)
		return -EMSGSIZE;
	switch (xfertype) {	//传输类型
	case USB_ENDPOINT_XFER_ISOC:	//同步传输
	case USB_ENDPOINT_XFER_INT:		//中断传输
		switch (dev->speed) {
		case USB_SPEED_WIRELESS:	//无线?
			if (urb->interval < 6)
				return -EINVAL;
			break;
		default:
			if (urb->interval <= 0)
				return -EINVAL;
			break;
		}
		switch (dev->speed) {
		case USB_SPEED_SUPER:	//超速设备
			if (urb->interval > (1 << 15))
				return -EINVAL;
			max = 1 << 15;
			break;
		case USB_SPEED_WIRELESS:	//无线?
			if (urb->interval > 16)
				return -EINVAL;
			break;
		case USB_SPEED_HIGH:	//高速设备
			if (urb->interval > (1024 * 8))
				urb->interval = 1024 * 8;
			max = 1024 * 8;
			break;
		case USB_SPEED_FULL:	//全速
		case USB_SPEED_LOW:		//低速
			if (xfertype == USB_ENDPOINT_XFER_INT) {
				if (urb->interval > 255)
					return -EINVAL;
				max = 128;
			} else {
				if (urb->interval > 1024)
					urb->interval = 1024;

				max = 1024;
			}
			break;
		default:
			return -EINVAL;
		}
		if (dev->speed != USB_SPEED_WIRELESS) {
			urb->interval = min(max, 1 << ilog2(urb->interval));
		}
	}
	return usb_hcd_submit_urb(urb, mem_flags);
}

调用主控器usb_hcd_submit_urb

  1. int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)  
  2. {  
  3.     int status;  
  4.     struct usb_hcd  *hcd = bus_to_hcd(urb->dev->bus);  
  5.     usb_get_urb(urb);  
  6.     atomic_inc(&urb->use_count);  
  7.     atomic_inc(&urb->dev->urbnum);  
  8.     usbmon_urb_submit(&hcd->self, urb);  
  9.     if (is_root_hub(urb->dev)) { //这次不是根hub   
  10.         status = rh_urb_enqueue(hcd, urb);  
  11.     } else {  
  12.         status = map_urb_for_dma(hcd, urb, mem_flags);  
  13.         if (likely(status == 0)) {  
  14.             status = hcd->driver->urb_enqueue(hcd, urb, mem_flags);   //调用主控器的urb_enqueue方法   
  15.             if (unlikely(status))  
  16.                 unmap_urb_for_dma(hcd, urb);  
  17.         }  
  18.     }  
  19.     if (unlikely(status)) {  
  20.         usbmon_urb_submit_error(&hcd->self, urb, status);  
  21.         urb->hcpriv = NULL;  
  22.         INIT_LIST_HEAD(&urb->urb_list);  
  23.         atomic_dec(&urb->use_count);  
  24.         atomic_dec(&urb->dev->urbnum);  
  25.         if (atomic_read(&urb->reject))  
  26.             wake_up(&usb_kill_urb_queue);  
  27.         usb_put_urb(urb);  
  28.     }  
  29.     return status;  
  30. }  
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值