- Linux那些事儿之我是USB
- 肖林甫 肖季东 任桥伟
- 2003字
- 2020-08-27 00:52:23
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状态。该继续看设备的那条生命线了。