当usb设备插入接口,电压变化会通知到usb主控器,
触发主控器中断,如果主控器不支持中断,那么会使用rh_timer方法,轮询接口
其结果都是调用usb_hcd_poll_rh_status
- 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函数
- void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
- {