Linux那些事儿之我是UHCI(9)有一种资源,叫中断

结束了uhci_init回到亲爱的usb_add_hcd之后,1604行到1606行是调试语句,飘过.

有一种液体叫眼泪,曾经以为,闭上眼睛,眼泪就不会流出来了.的确,眼泪流回了心里.

有一种资源叫中断,曾经以为,关掉中断,USB主机就不会工作了.的确,USB主机没有中断基本就挂了

1609,中断.driver有没有一个irq函数,如果没有,就简单的记录hcd->irq-1,hcd->irq就是用来记录传说中的中断号的.如果有,那就有事情要做了.显然咱们的uhci_driver里面是有的,它的赋值就是uhci_irq.当然,现在不用执行它,只是需要为它做点事情.最重要的当然就是request_irq这个函数.我们先来看看它直观的效果.

加载uhci-hcd之前:

localhost:~ # cat /proc/interrupts

CPU0

0: 29906 IO-APIC-edge timer

1: 10 IO-APIC-edge i8042

8: 2 IO-APIC-edge rtc

9: 3 IO-APIC-fasteoi acpi

12: 115 IO-APIC-edge i8042

14: 6800 IO-APIC-edge ide0

16: 780 IO-APIC-fasteoi eth0

NMI: 0

LOC: 1403

ERR: 0

MIS: 0

加载uhci-hcd模块:

localhost:~ # modprobe usbcore

localhost:~ # modprobe uhci-hcd

加载uhci-hcd模块之后:

localhost:~ # cat /proc/interrupts

CPU0

0: 32625 IO-APIC-edge timer

1: 10 IO-APIC-edge i8042

8: 2 IO-APIC-edge rtc

9: 3 IO-APIC-fasteoi acpi

12: 115 IO-APIC-edge i8042

14: 6915 IO-APIC-edge ide0

16: 870 IO-APIC-fasteoi eth0, uhci_hcd:usb1

17: 0 IO-APIC-fasteoi uhci_hcd:usb4

18: 0 IO-APIC-fasteoi uhci_hcd:usb2

19: 0 IO-APIC-fasteoi uhci_hcd:usb3

NMI: 0

LOC: 1403

ERR: 0

MIS: 0

众所周知,/proc/interrupts列出了计算机中中断资源的使用情况.这其中uhci_hcd:usb1/usb2/usb3/usb4这几个字符串就是request_irq中的倒数第二个参数,即我们看到的实参hcd->irq_descr,而这个字符串的赋值就是1610行那个snprintf语句的职责.hcd->driver->description就是”uhci-hcd”,hcd->self.busnum就是1,2,3,4这些.因为这台机器一共四个usb主机控制器,它们的编号就是1,2,3,4.

那么request_irq的具体作用是什么?请求中断资源,或者更准确地说是安装中断处理函数或者叫中断句柄(interrupt handler).

这个函数的第一个参数就是中断号.咱们的irqnum是一路传下来的,即最初的那个dev->irq.

这其中第二个参数就是中断句柄.这里我们传递的是usb_hcd_irq.这个函数将会在响应中断的时候被调用.

第三个参数,irqflags,我们在probe中调用usb_add_hcd的时候,传递的第三个参数是IRQF_SHARED,这个参数也被传递给了request_irq,所以这里的irqflagsIRQF_SHARED,这表示该中断可以被多个device共享.这也是为什么我们可以看到uhci-hcd:usb1和网卡驱动eth0用的是同一个中断号.之所以要共享,是因为当今世界中断资源相当的紧张,在现实中我们经常喊这么一句口号:要节约用水,尽量和女友一起洗澡.而在操作系统中,这句口号变为:要节约资源,尽量和别的设备共享中断号.

第四个参数就是那个字符串.第五个参数主要是用来标志使用中断的设备,它是一个指针,这个参数只是用来区分不同的设备,你可以不用它,即你可以把它设置为NULL.但更多的情况是它被设置为指向驱动程序私有的数据.我们传递的是hcd本身,这样我们在usb_hcd_irq函数中就可以使用它,因为事实上我们在usb_hcd_irq中把它当作了一个参数来用.

这样request_irq就明白了,以后释放中断资源的时候我们只要调用另一个函数,free_irq即可.这个函数将会在usb_remove_hcd的时候被调用.

最后1618,我们也把irqnum记录在了hcd->irq.

最后的最后,再强调一下,usb_hcd_irq是咱们这个故事中很重要的角色,它将在未来主机控制器需要中断的时候被调用.希望你不要把她忘怀.作为一个中断函数,如果不是它以后有一定的利用价值,咱们现在完全没有必要为它注册,这很符合常理,非常符合常理!正如南京鼓楼法院审判长对彭宇事件给出的结论一样,”从常理分析,如果不是彭宇撞的老太太,他完全不用送她去医院.”好一个常理,雷锋为火车拖地板,按照常理来说是不可能的,所以只有一个解释,地板是他弄脏的,所以他才去拖;董存瑞舍生炸碉堡,按照常理来说是不可能的,所以只有一个解释,那碉堡是董存瑞安插在那里的;黄继光堵枪眼,按照常理来说是不可能的,所以只有一个解释,里面的联合国军是他招来的;王杰扑在地雷上面,牺牲了自己,保住了十二名民兵同志的生命,按照常理来说是不可能的,所以只有一个解释,那地雷是王杰让爆的;欧阳海舍去自己生命,拉开了在铁轨上的惊马,按照常理来说是不可能的,所以只有一个解释,那匹惊马是欧阳海拉到铁轨上去的;赖宁,一个十岁小孩子,要跑去抢救山火,按照常理来说是不可能的,所以只有一个解释,那把山火是他放的;解放军战士们在灾区不要命的抢救父老乡亲,用身体堵大坝,按照常理来说是不可能不应该的,所以只有一个解释,洪水是解放军引来的;我们给希望工程捐款,按照常理来说是不可能的,所以只有一个解释,那些孩子是被我们弄辍学的常理最终告诉我们,我们80后从小要学习的英雄人物,全他妈的都是些坏蛋.

你可能感兴趣的:(linux)