28.设备的生命线(九)

28.设备的生命线(九)

说完了struct usb_hcd和struct usb_bus函数,接下来就该查看usb_submit_urb()最后的那个遗留问题usb_hcd_submit_urb()函数了。

现在内核中有个很不好的现象,设计结构比较复杂,函数比较长。

921 int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
922 {
923     int             status;
924     struct usb_hcd    *hcd = bus_to_hcd(urb->dev->bus);
925     struct usb_host_endpoint *ep;
926     unsigned long    flags;
927
928     if (!hcd)
929         return -ENODEV;
930
931     usbmon_urb_submit(&hcd->self, urb);
932
933     /*
934      * Atomically queue the urb, first to our records, then to the HCD.
935      * Access to urb->status is controlled by urb->lock ... changes on
936      * i/o completion (normal or fault) or unlinking.
937      */
938
939     // FIXME: verify that quiescing hc works right (RH cleans up)
940
941     spin_lock_irqsave (&hcd_data_lock, flags);
942     ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out)
943                [usb_pipeendpoint(urb->pipe)];
944     if (unlikely (!ep))
945         status = -ENOENT;
946     else if (unlikely (urb->reject))
947         status = -EPERM;
948     else switch (hcd->state) {
949     case HC_STATE_RUNNING:
950     case HC_STATE_RESUMING:
951 doit:
952     list_add_tail (&urb->urb_list, &ep->urb_list);
953        status = 0;
954        break;
955     case HC_STATE_SUSPENDED:
956     /* HC upstream links (register access, wakeup signaling) can work
957      * even when the downstream links (and DMA etc) are quiesced; let
958      * usbcore talk to the root hub.
959      */
960      if (hcd->self.controller->power.power_state.event==PM_EVENT_ON
961                             && urb->dev->parent == NULL)
962                       goto doit;
963        /* FALL THROUGH */
964     default:
965        status = -ESHUTDOWN;
966        break;
967     }
968     spin_unlock_irqrestore (&hcd_data_lock, flags);
969     if (status) {
970     INIT_LIST_HEAD (&urb->urb_list);
971         usbmon_urb_submit_error(&hcd->self, urb, status);
972         return status;
973     }
974
975     /* increment urb's reference count as part of giving it to the HCD
976      * (which now controls it). HCD guarantees that it either returns
977      * an error or calls giveback(), but not both.
978      */
979     urb = usb_get_urb (urb);
980     atomic_inc (&urb->use_count);
981
982     if (urb->dev == hcd->self.root_hub) {
983         /* NOTE: requirement on hub callers (usbfs and the hub
984          * driver, for now) that URBs' urb->transfer_buffer be
985          * valid and usb_buffer_{sync,unmap}() not be needed, since
986          * they could clobber root hub response data.
987          */
988         status = rh_urb_enqueue (hcd, urb);
989         goto done;
990     }
991
992     /* lower level hcd code should use *_dma exclusively,
993     * unless it uses pio or talks to another transport.
994     */
995     if (hcd->self.uses_dma) {
996         if (usb_pipecontrol (urb->pipe)
997                && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
998             urb->setup_dma = dma_map_single (
999                           hcd->self.controller,
1000                            urb->setup_packet,
1001                            sizeof (struct usb_ctrlrequest),
1002                          DMA_TO_DEVICE);
1003        if (urb->transfer_buffer_length != 0
1004                && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
1005        urb->transfer_dma = dma_map_single (
1006                                 hcd->self.controller,
1007                              urb->transfer_buffer,
1008                                 urb->transfer_buffer_length,
1009                                 usb_pipein (urb->pipe)
1010                                   ? DMA_FROM_DEVICE
1011                                   : DMA_TO_DEVICE);
1012     }
1013
1014     status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);
1015 done:
1016    if (unlikely (status)) {
1017         urb_unlink (urb);
1018         atomic_dec (&urb->use_count);
1019         if (urb->reject)
1020             wake_up (&usb_kill_urb_queue);
1021         usbmon_urb_submit_error(&hcd->self, urb, status);
1022         usb_put_urb (urb);
1023    }
1024    return status;
1025 }

usb_hcd_submit_urb函数是hcd.c里的,目标也很明确,就是将提交过来的urb指派给合适的主机控制器驱动程序。Core目录下面以“hcd”打头的几个文件严格来说不能算是HCD,只能算HCDI,即主机控制器驱动的接口层,这用来衔接具体的主机控制器驱动和USB Core的。

924行,bus_to_hcd是用来获得struct usb_bus结构体对应的struct usb_hcd结构体,urb要去的那个设备所在的总线是在设备生命线的开始就初始化好了的。bus_to_hcd还有一个兄弟hcd_to_bus,都在hcd.h中定义。

131 static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
132 {
133     return &hcd->self;
134 }
135
136 static inline struct usb_hcd *bus_to_hcd (struct usb_bus *bus)
137 {
138     return container_of(bus, struct usb_hcd, self);
139 }

继续看928行,这是大多数函数开头儿必备的常规检验,如果usb_hcd都还是空的,那就返回吧。

931行,usbmon_urb_submit就是与前面Greg孕育出来的USB Monitor有关的,如果你编译内核时没有配置上CONFIG_USB_MON,它就是一个空函数。

941行,去获得一把锁,这把锁在hcd.c的开头儿就已经初始化好了,所以说是把全局锁。

102 /* used when updating hcd data */
103 static DEFINE_SPINLOCK(hcd_data_lock);

前面多次遇到过自旋锁,现在就简单介绍一下。它和信号量,还有前面提到的completion一样都是Linux里用来进行代码同步。为什么要进行同步?要知道在Linux这个庞大复杂的世界里,可能同时有多个线程,那么只要它们互相之间有一定的共享,就必须要保证某一个线程操作这个共享时让其他线程知道。

自旋锁身为同步机制的一种,自然也有它独特的本事,它可以用在中断上下文或者原子上下文使用。上下文就是代码运行的环境,Linux的这个环境使用二分法可以分成两种,能休眠的环境和不能休眠的环境。像信号量和completion就只能用在可以休眠的环境,而自旋锁就用在不能休眠的环境里。

而usb_submit_urb还有usb_hcd_submit_urb必须得在两种环境里都能够使用,所以使用的是自旋锁,想一想urb的结束处理函数,它就是不能休眠的,但它里面必须得能够重新提交urb。

再说一说hcd_data_lock这把锁都是用来保护什么的,为什么要使用它?主机控制器的struct usb_hcd结构体在它的驱动里早就初始化好了,但同一时刻是可能有多个urb向同一个主机控制器申请进行传输,可能有多个地方都希望访问它里面的内容。比如948行的state元素,显然就要同步了,hcd_data_lock这把锁就是专门用来保护主机控制器的这个结构体的。

942行,遇到多次也说过多次了,知道了pipe,就可以从struct usb_device里的两个数组ep_in和ep_out里拿出对应端点的struct usb_host_endpoint结构体。

944行到973行,这些行都是做检验的。

944行,显然都走到这一步了,目的端点为空的可能性太小了,所以加上了unlikely。

946行,前面还说过,urb里的这个reject,只有usb_kill_urb有特权修改它,如果走到这里发现它的值大于0了,那就说明哪里调用了usb_kill_urb要终止这次传输,所以还是返回吧,不过这种可能性比较小,没人无聊到那种地步,总是刚提交就终止,吊主机控制器胃口,所以仍然加上unlikely。

948行,如果上面那两个检验都通过了,现在就“case”主机控制器的状态,如果为HC_STATE_RUNNING或HC_STATE_RESUMING就说明主机控制器这边儿没问题,尽管将这个urb往端点的urb队列里塞好了,952行就是完成这个工作的。如果主机控制器的状态为HC_STATE_SUSPENDED,但它的上行链路能够工作,而且这个urb是送往Root Hub的,则将其塞到Root Hub的urb队列里。

然后判断上面几次检验的结果,如果一切正常,则继续往下走,否则就返回吧。

979行,检验都通过了,可以放心地增加urb的引用计数了。

980行,将urb的use_count也增加1,表示urb已经被HCD接受了,正在被处理着。你如果对这两个引用计数的差别还有疑问,再看一看前面讲解struct urb时的内容。

982行,判断这个urb是不是流向Root Hub的,如果是,它就走向了Root Hub的生命线。不过,毕竟你更关注的是USB设备,应该很少有机会直接和Root Hub交流什么。

995行,如果这个主机控制器支持DMA,可你却没有告诉它URB_NO_SETUP_DMA_MAP或URB_NO_TRANSFER_DMA_MAP这两个标志,它就会认为你在urb里没有提供DMA的缓冲区,就会调用dma_map_single将setup_packet或transfer_buffer映射为DMA缓冲区。

1014行,终于可以将urb交给具体的主机控制器驱动程序了。

到现在,设备已经可以进入Address状态。该继续看设备的那条生命线了。