linux内核中USB总线的hub中断的调用 | 您所在的位置:网站首页 › Linux内核关闭USB总线 › linux内核中USB总线的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)函数,从而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 实验室设备网 版权所有 |