linux内核中USB总线的hub中断的调用 您所在的位置:网站首页 Linux内核关闭USB总线 linux内核中USB总线的hub中断的调用

linux内核中USB总线的hub中断的调用

2024-07-05 21:41| 来源: 网络整理| 查看: 265

1)对于root hub的中断端点,在hub_probe中调用usb_hub_configure函数,而这个函数中设置了回调函数hub_irq:  FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,  hub, endpoint->bInterval);  然后执行usb_submit_urb(hub->urb)函数,从而root hub的hub_irq函数通过定时器周期性的执行,即执行rh_int_timer_do => urb->complete (urb);因而通过中断端点可以检测到是否有设备插入。由于控制端点没有设置这个回调函数,所以rh_submit_urb (urb_t * urb)函数的最后两条语句也就不执行任何的回调函数。  2)而对于所有的usb设备,当处理完成一个事务时,hc_interrupt-----dl_done_list-----sohci_return_urb-----urb->complete (urb);的回调函数,根据不同的端点而执行不同的回调函数hub_irq或者是usb_api_blocking_completion  所以,对于root hub的中断端点有两处执行hub_irq的地方,一处是由于定时器而周期性的执行hub_irq,另一处是由于hc处理完事务又执行了一次;而非root hub的设备只用在处理完事务后才调用一次。

你看我这样理解还有什么问题没:  1)对于root hub的中断端点,在hub_probe中调用usb_hub_configure函数,而这个函数中设置了回调函数hub_irq:  FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,  hub, endpoint->bInterval);  然后执行usb_submit_urb(hub->urb)函数,  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  上面理解的很对,但对于root hub的处理和其他的usb hub有所不同,他并不是真的提交这样的一个请求,因为root hub 和 usb controler集成在一起,所以没有必要真正的启动一次中断传输。而在这个情境中,usb_submit_urb(hub->urb)其实就是static int sohci_submit_urb (urb_t * urb),由于我们提交的是一个root hub的传输请求块,所以,具体的执行是rh_submit_urb (urb)函数,你可以具体看一看这个函数。  对于其他的非root hub的usb hub而言,usb_submit_urb(hub->urb)函数提交了一个usb中断传输请求块,之后,usb controler就主动的in包,用来启动一次中断传输。  从而root hub的hub_irq函数通过定时器周期性的执行,即执行rh_int_timer_do => urb->complete (urb);因而通过中断端点可以检测到是否有设备插入。由于控制端点没有设置这个回调函数,所以rh_submit_urb (urb_t * urb)函数的最后两条语句也就不执行任何的回调函数。  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  不对,hub_irq不会因为设定的定时器而周期的执行,只有端口状态变化才执行,在rh_submit_urb (urb)中表述的很清楚  if (usb_pipeint(pipe)) {-------------------如果是一个中断的pipe,那么执行进入  ohci->rh.urb = urb;  ohci->rh.send = 1;  ohci->rh.interval = urb->interval;  rh_init_int_timer(urb);------------初始化timer  urb->status = cc_to_error [TD_CC_NOERROR];  return 0;-------------------------返回  }  ,我们可以看一下这个初始化timer的函数  static int rh_init_int_timer (urb_t * urb)  {  ohci_t * ohci = urb->dev->bus->hcpriv;  ohci->rh.interval = urb->interval;  init_timer (&ohci->rh.rh_int_timer);  ohci->rh.rh_int_timer.function = rh_int_timer_do;-------------timer到期后执行的函数  ohci->rh.rh_int_timer.data = (unsigned long) urb;------------传递一个urb参数  ohci->rh.rh_int_timer.expires =  jiffies + (HZ * (urb->interval interval)) / 1000;  add_timer (&ohci->rh.rh_int_timer);------------启动timer  return 0;  }  我们再看一下timer到期的函数  static void rh_int_timer_do (unsigned long ptr)  {  int len;  urb_t * urb = (urb_t *) ptr;  ohci_t * ohci = urb->dev->bus->hcpriv;  if (ohci->disabled)  return;  /* ignore timers firing during PM suspend, etc */  if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER)  goto out;  if(ohci->rh.send) {  下面这个函数将检测该root hub的端口的状态,如果端口状态发生变化,则执行下面的urb->complete (urb);  len = rh_send_irq (ohci, urb->transfer_buffer, urb->transfer_buffer_length);  if (len > 0) {  urb->actual_length = len;  #ifdef DEBUG  urb_print (urb, "RET-t(rh)", usb_pipeout (urb->pipe));  #endif  if (urb->complete)  urb->complete (urb);  }  }  out:  rh_init_int_timer (urb);-------重设timer  }  2)而对于所有的usb设备,当处理完成一个事务时,hc_interrupt-----dl_done_list-----sohci_return_urb-----urb->complete (urb);的回调函数,根据不同的端点而执行不同的回调函数hub_irq或者是usb_api_blocking_completion  所以,对于root hub的中断端点有两处执行hub_irq的地方,一处是由于定时器而周期性的执行hub_irq,另一处是由于hc处理完事务又执行了一次;而非root hub的设备只用在处理完事务后才调用一次。  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  不是,对于root hub而言,hub_irq是通过timer来执行的,因为集成在一起,所以如果也启动一次中断传输会显得是那么的愚蠢,而对于其他的非root hub的usb hub,hub_irq是由于hc处理完事务而执行的



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有