徐志摩说:轻轻的我穿衣,正如我轻轻的脱;
后来徐志摩又说:轻轻的我走了,正如我轻轻的来.
hub_events(),没错,胡汉三又回来了.
再一次进入while这个(该)死(的)循环.
第一次来这里的时候,hub_event_list是空的,可是这一次不是了,我们刚刚在kick_khubd()里面才执行了往这个队列里插入的操作,所以我们不会再像第一次一样,从2621行的break跳出循环.相反,我们直接走到2624行,把刚才插入队列的那个节点取出来,存为tmp,然后把tmp从队列里删除掉.(是从队列里删除,不是把tmp本身给删除.)
2627行,list_entry(),这个经典的函数,或者说宏,就像复旦南区食堂的大排,永恒的经典.通过这个宏这里得到的是那个触发hub_events()的hub.然后2628行,同时用局部变量hdev记录hub->hdev.2629行,又得到对应的struct usb_interface和struct device,这下好了,什么都得到了,该付出了吧.
2640行, usb_get_intf(),看仔细了,别和我们当年在usb-storage里面调用的那个usb_get_intfdata()混淆了,这里usb_get_intf只是一个引用计数.是usb core提供的一个函数,以前黑客们推荐用另一个引用计数的函数usb_get_dev(),但在当今世界这样一种现状下,随着一个usb device越来越成为多个interface耦合的情况的出现,struct usb_device实际上已经快淡出历史舞台了,现在在驱动程序里关注的最多的就是interface,而不是device.和usb_get_intf()对应的有另一个函数,叫做usb_put_intf(),很显然,一个是增加引用计数一个减少引用计数.这个函数我们马上就能看到.
前面我们贴hub_events()只贴到2641行,现在继续贴,贴完这个粉恐怖的函数.
2642
2643 /* Lock the device, then check to see if we were
2644 * disconnected while waiting for the lock to succeed. */
2645 if (locktree(hdev) < 0) {
2646 usb_put_intf(intf);
2647 continue;
2648 }
2649 if (hub != usb_get_intfdata(intf))
2650 goto loop;
2651
2652 /* If the hub has died, clean up after it */
2653 if (hdev->state == USB_STATE_NOTATTACHED) {
2654 hub->error = -ENODEV;
2655 hub_pre_reset(intf);
2656 goto loop;
2657 }
2658
2659 /* Autoresume */
2660 ret = usb_autopm_get_interface(intf);
2661 if (ret) {
2662 dev_dbg(hub_dev, "Can't autoresume: %d/n", ret);
2663 goto loop;
2664 }
2665
2666 /* If this is an inactive hub, do nothing */
2667 if (hub->quiescing)
2668 goto loop_autopm;
2669
2670 if (hub->error) {
2671 dev_dbg (hub_dev, "resetting for error %d/n",
2672 hub->error);
2673
2674 ret = usb_reset_composite_device(hdev, intf);
2675 if (ret) {
2676 dev_dbg (hub_dev,
2677 "error resetting hub: %d/n", ret);
2678 goto loop_autopm;
2679 }
2680
2681 hub->nerrors = 0;
2682 hub->error = 0;
2683 }
2684
2685 /* deal with port status changes */
2686 for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {
2687 if (test_bit(i, hub->busy_bits))
2688 continue;
2689 connect_change = test_bit(i, hub->change_bits);
2690 if (!test_and_clear_bit(i, hub->event_bits) &&
2691 !connect_change && !hub->activating)
2692 continue;
2693
2694 ret = hub_port_status(hub, i,
2695 &portstatus, &portchange);
2696 if (ret < 0)
2697 continue;
2698
2699 if (hub->activating && !hdev->children[i-1] &&
2700 (portstatus &
2701 USB_PORT_STAT_CONNECTION))
2702 connect_change = 1;
2703
2704 if (portchange & USB_PORT_STAT_C_CONNECTION) {
2705 clear_port_feature(hdev, i,
2706 USB_PORT_FEAT_C_CONNECTION);
2707 connect_change = 1;
2708 }
2709
2710 if (portchange & USB_PORT_STAT_C_ENABLE) {
2711 if (!connect_change)
2712 dev_dbg (hub_dev,
2713 "port %d enable change, "
2714 "status %08x/n",
2715 i, portstatus);
2716 clear_port_feature(hdev, i,
2717 USB_PORT_FEAT_C_ENABLE);
2718
2719 /*
2720 * EM interference sometimes causes badly
2721 * shielded USB devices to be shutdown by
2722 * the hub, this hack enables them again.
2723 * Works at least with mouse driver.
2724 */
2725 if (!(portstatus & USB_PORT_STAT_ENABLE)
2726 && !connect_change
2727 && hdev->children[i-1]) {
2728 dev_err (hub_dev,
2729 "port %i "
2730 "disabled by hub (EMI?), "
2731 "re-enabling.../n",
2732 i);
2733 connect_change = 1;
2734 }
2735 }
2736
2737 if (portchange & USB_PORT_STAT_C_SUSPEND) {
2738 clear_port_feature(hdev, i,
2739 USB_PORT_FEAT_C_SUSPEND);
2740 if (hdev->children[i-1]) {
2741 ret = remote_wakeup(hdev->
2742 children[i-1]);
2743 if (ret < 0)
2744 connect_change = 1;
2745 } else {
2746 ret = -ENODEV;
2747 hub_port_disable(hub, i, 1);
2748 }
2749 dev_dbg (hub_dev,
2750 "resume on port %d, status %d/n",
2751 i, ret);
2752 }
2753
2754 if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
2755 dev_err (hub_dev,
2756 "over-current change on port %d/n",
2757 i);
2758 clear_port_feature(hdev, i,
2759 USB_PORT_FEAT_C_OVER_CURRENT);
2760 hub_power_on(hub);
2761 }
2762
2763 if (portchange & USB_PORT_STAT_C_RESET) {
2764 dev_dbg (hub_dev,
2765 "reset change on port %d/n",
2766 i);
2767 clear_port_feature(hdev, i,
2768 USB_PORT_FEAT_C_RESET);
2769 }
2770
2771 if (connect_change)
2772 hub_port_connect_change(hub, i,
2773 portstatus, portchange);
2774 } /* end for i */
2775
2776 /* deal with hub status changes */
2777 if (test_and_clear_bit(0, hub->event_bits) == 0)
2778 ; /* do nothing */
2779 else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
2780 dev_err (hub_dev, "get_hub_status failed/n");
2781 else {
2782 if (hubchange & HUB_CHANGE_LOCAL_POWER) {
2783 dev_dbg (hub_dev, "power change/n");
2784 clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
2785 if (hubstatus & HUB_STATUS_LOCAL_POWER)
2786 /* FIXME: Is this always true? */
2787 hub->limited_power = 0;
2788 else
2789 hub->limited_power = 1;
2790 }
2791 if (hubchange & HUB_CHANGE_OVERCURRENT) {
2792 dev_dbg (hub_dev, "overcurrent change/n");
2793 msleep(500); /* Cool down */
2794 clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
2795 hub_power_on(hub);
2796 }
2797 }
2798
2799 hub->activating = 0;
2800
2801 /* If this is a root hub, tell the HCD it's okay to
2802 * re-enable port-change interrupts now. */
2803 if (!hdev->parent && !hub->busy_bits[0])
2804 usb_enable_root_hub_irq(hdev->bus);
2805
2806 loop_autopm:
2807 /* Allow autosuspend if we're not going to run again */
2808 if (list_empty(&hub->event_list))
2809 usb_autopm_enable(intf);
2810 loop:
2811 usb_unlock_device(hdev);
2812 usb_put_intf(intf);
2813
2814 } /* end while (1) */
2815 }
我真想诚恳的问候一下写代码的人的女性长辈.当裴多菲说:"若为自由故,两者皆可抛",我懂得了作为人的价值;当鲁迅说:"不在沉默中爆发,就在沉默中灭亡",我懂得人应具有反抗精神;当白朗宁说:"拿走爱,世界将变成一座坟墓",我懂得了为他人奉献爱心的重要;当简爱说:"我们是平等的,我不是无感情的机器",我懂得了作为女性的自尊;当我看到这段代码,我却完全不懂写代码的人为什么总要写一些恐怖的函数出来.一定要吓唬吓唬我他们就开心么?我是复旦的,不是厦(吓)大的.