五、从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. }  

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. }  

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. }  

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. }  

这里会触发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));  

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. }  

hub口状态变化处理函数

[cpp]  view plain copy
  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. }  

hub端口初始化

[cpp]  view plain copy
  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. }  

usb_new_device

[cpp]  view plain copy
  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. }  

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. }  

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

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

若是设备则调用usb_probe_device

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

[cpp]  view plain copy
  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. }  

一般在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. }  

调用主控器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. }  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值