`
javatome
  • 浏览: 822333 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Linux那些事儿 之 戏说USB(24)设备的生命线(三)

 
阅读更多
函数usb_control_msg调用了usb_internal_control_msg之后就去一边儿睡大觉了,脏活儿累活儿,全部留给usb_internal_control_msg去做了,这才叫骨干啊,俺一华为的哥们儿如是说。那么咱们接下来就给这个骨干多点儿关注,了解一下它背后的真实生活,现在是焦点访谈时间,要用事实说话。
70 // returns status (negative) or length (positive)
71 static int usb_internal_control_msg(struct usb_device *usb_dev,
72 unsigned int pipe,
74 void *data, int len, int timeout)
75 {
76 struct urb *urb;
77 int retv;
78 int length;
81 if (!urb)
82 return -ENOMEM;
84 usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
88 if (retv < 0)
89 return retv;
90 else
91 return length;
92 }
这个函数粗看过去,可以概括为一个中心,三个基本点,以一个struct urb结构体为中心,以usb_alloc_urbusb_fill_control_urbusb_start_wait_urb三个函数为基本点。
一个中心:struct urb结构体,就是咱们前面多次提到又多次飘过,只闻其名不见其形的传说中的urb,全称usb request block,站在咱们的角度看,usb通信靠的就是它这张脸。
第一个基本点:usb_alloc_urb函数,创建一个urb,struct urb结构体只能使用它来创建,它是urb在usb世界里的独家代理,和天盛一样的角色。
第二个基本点:usb_fill_control_urb函数,初始化一个控制urb,urb被创建之后,使用之前必须要正确的初始化。
第三个基本点:usb_start_wait_urb函数,将urb提交给咱们的usb core,以便分配给特定的主机控制器驱动进行处理,然后默默的等待处理结果,或者超时。
963 /**
964* struct urb - USB Request Block
965* @urb_list: For use by current owner of the URB.
966* @pipe: Holds endpoint number, direction, type, and more.
967* Create these values with the eight macros available;
968* usb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is "ctrl"
969* (control), "bulk", "int" (interrupt), or "iso" (isochronous).
970* For example usb_sndbulkpipe() or usb_rcvintpipe().Endpoint
971* numbers range from zero to fifteen.Note that "in" endpoint two
972* is a different endpoint (and pipe) from "out" endpoint two.
973* The current configuration controls the existence, type, and
974* maximum packet size of any given endpoint.
975* @dev: Identifies the USB device to perform the request.
976* @status: This is read in non-iso completion functions to get the
977* status of the particular request.ISO requests only use it
978* to tell whether the URB was unlinked; detailed status for
979* each frame is in the fields of the iso_frame-desc.
980* @transfer_flags: A variety of flags may be used to affect how URB
981* submission, unlinking, or operation are handled.Different
982* kinds of URB can use different flags.
983* @transfer_buffer:This identifies the buffer to (or from) which
984* the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP
985* is set).This buffer must be suitable for DMA; allocate it with
986* kmalloc() or equivalent.For transfers to "in" endpoints, contents
987* of this buffer will be modified.This buffer is used for the data
988* stage of control transfers.
989* @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
990* the device driver is saying that it provided this DMA address,
991* which the host controller driver should use in preference to the
992* transfer_buffer.
993* @transfer_buffer_length: How big is transfer_buffer.The transfer may
994* be broken up into chunks according to the current maximum packet
995* size for the endpoint, which is a function of the configuration
996* and is encoded in the pipe.When the length is zero, neither
997* transfer_buffer nor transfer_dma is used.
998* @actual_length: This is read in non-iso completion functions, and
999* it tells how many bytes (out of transfer_buffer_length) were
1000* transferred.It will normally be the same as requested, unless
1001* either an error was reported or a short read was performed.
1002* The URB_SHORT_NOT_OK transfer flag may be used to make such
1003* short reads be reported as errors.
1004* @setup_packet: Only used for control transfers, this points to eight bytes
1005* of setup data.Control transfers always start by sending this data
1006* to the device.Then transfer_buffer is read or written, if needed.
1007* @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the
1008* device driver has provided this DMA address for the setup packet.
1009* The host controller driver should use this in preference to
1010* setup_packet.
1011* @start_frame: Returns the initial frame for isochronous transfers.
1012* @number_of_packets: Lists the number of ISO transfer buffers.
1013* @interval: Specifies the polling interval for interrupt or isochronous
1014* transfers.The units are frames (milliseconds) for for full and low
1015* speed devices, and microframes (1/8 millisecond) for highspeed ones.
1016* @error_count: Returns the number of ISO transfers that reported errors.
1017* @context: For use in completion functions.This normally points to
1018* request-specific driver context.
1019* @complete: Completion handler. This URB is passed as the parameter to the
1020* completion function.The completion function may then do what
1021* it likes with the URB, including resubmitting or freeing it.
1022* @iso_frame_desc: Used to provide arrays of ISO transfer buffers and to
1023* collect the transfer status for each buffer.
1024*
1025* This structure identifies USB transfer requests. URBs must be allocated by
1026* calling usb_alloc_urb() and freed with a call to usb_free_urb().
1027* Initialization may be done using various usb_fill_*_urb() functions.URBs
1028* are submitted using usb_submit_urb(), and pending requests may be canceled
1029* using usb_unlink_urb() or usb_kill_urb().
1030*
1031* Data Transfer Buffers:
1032*
1033* Normally drivers provide I/O buffers allocated with kmalloc() or otherwise
1034* taken from the general page pool.That is provided by transfer_buffer
1035* (control requests also use setup_packet), and host controller drivers
1036* perform a dma mapping (and unmapping) for each buffer transferred.Those
1037* mapping operations can be expensive on some platforms (perhaps using a dma
1038* bounce buffer or talking to an IOMMU),
1039* although they're cheap on commodity x86 and ppc hardware.
1040*
1041* Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
1042* which tell the host controller driver that no such mapping is needed since
1043* the device driver is DMA-aware.For example, a device driver might
1044* allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
1045* When these transfer flags are provided, host controller drivers will
1046* attempt to use the dma addresses found in the transfer_dma and/or
1047* setup_dma fields rather than determining a dma address themselves.(Note
1048* that transfer_buffer and setup_packet must still be set because not all
1049* host controllers use DMA, nor do virtual root hubs).
1050*
1051* Initialization:
1052*
1053* All URBs submitted must initialize the dev, pipe, transfer_flags (may be
1054* zero), and complete fields.All URBs must also initialize
1055* transfer_buffer and transfer_buffer_length.They may provide the
1056* URB_SHORT_NOT_OK transfer flag, indicating that short reads are
1057* to be treated as errors; that flag is invalid for write requests.
1058*
1059* Bulk URBs may
1060* use the URB_ZERO_PACKET transfer flag, indicating that bulk OUT transfers
1061* should always terminate with a short packet, even if it means adding an
1062* extra zero length packet.
1063*
1064* Control URBs must provide a setup_packet.The setup_packet and
1065* transfer_buffer may each be mapped for DMA or not, independently of
1066* the other.The transfer_flags bits URB_NO_TRANSFER_DMA_MAP and
1067* URB_NO_SETUP_DMA_MAP indicate which buffers have already been mapped.
1068* URB_NO_SETUP_DMA_MAP is ignored for non-control URBs.
1069*
1070* Interrupt URBs must provide an interval, saying how often (in milliseconds
1071* or, for highspeed devices, 125 microsecond units)
1072* to poll for transfers.After the URB has been submitted, the interval
1073* field reflects how the transfer was actually scheduled.
1074* The polling interval may be more frequent than requested.
1075* For example, some controllers have a maximum interval of 32 milliseconds,
1076* while others support intervals of up to 1024 milliseconds.
1077* Isochronous URBs also have transfer intervals.(Note that for isochronous
1078* endpoints, as well as high speed interrupt endpoints, the encoding of
1079* the transfer interval in the endpoint descriptor is logarithmic.
1080* Device drivers must convert that value to linear units themselves.)
1081*
1082* Isochronous URBs normally use the URB_ISO_ASAP transfer flag, telling
1083* the host controller to schedule the transfer as soon as bandwidth
1084* utilization allows, and then set start_frame to reflect the actual frame
1085* selected during submission.Otherwise drivers must specify the start_frame
1086* and handle the case where the transfer can't begin then.However, drivers
1087* won't know how bandwidth is currently allocated, and while they can
1088* find the current frame using usb_get_current_frame_number () they can't
1089* know the range for that frame number.(Ranges for frame counter values
1090* are HC-specific, and can go from 256 to 65536 frames from "now".)
1091*
1092* Isochronous URBs have a different data transfer model, in part because
1093* the quality of service is only "best effort".Callers provide specially
1094* allocated URBs, with number_of_packets worth of iso_frame_desc structures
1095* at the end.Each such packet is an individual ISO transfer.Isochronous
1096* URBs are normally queued, submitted by drivers to arrange that
1097* transfers are at least double buffered, and then explicitly resubmitted
1098* in completion handlers, so
1099* that data (such as audio or video) streams at as constant a rate as the
1100* host controller scheduler can support.
1101*
1102* Completion Callbacks:
1103*
1104 * The completion callback is made in_interrupt(), and one of the first
1105* things that a completion handler should do is check the status field.
1106* The status field is provided for all URBs.It is used to report
1107* unlinked URBs, and status for all non-ISO transfers.It should not
1108* be examined before the URB is returned to the completion handler.
1109*
1110* The context field is normally used to link URBs back to the relevant
1111* driver or request state.
1112*
1113* When the completion callback is invoked for non-isochronous URBs, the
1114* actual_length field tells how many bytes were transferred.This field
1115* is updated even when the URB terminated with an error or was unlinked.
1116*
1117* ISO transfer status is reported in the status and actual_length fields
1118* of the iso_frame_desc array, and the number of errors is reported in
1119* error_count.Completion callbacks for ISO transfers will normally
1120* (re)submit URBs to ensure a constant transfer rate.
1121*
1122* Note that even fields marked "public" should not be touched by the driver
1123* when the urb is owned by the hcd, that is, since the call to
1124* usb_submit_urb() till the entry into the completion routine.
1125*/
1126 struct urb
1127 {
1128 /* private: usb core and host controller only fields in the urb */
1129 struct kref kref; /* reference count of the URB */
1130 spinlock_t lock; /* lock for the URB */
1131 void *hcpriv; /* private data for host controller */
1132 atomic_t use_count; /* concurrent submissions counter */
1133 u8 reject; /* submissions will fail */
1135 /* public: documented fields in the urb that can be used by drivers */
1136 struct list_head urb_list; /* list head for use by the urb's
1137 * current owner */
1138 struct usb_device *dev; /* (in) pointer to associated device */
1139 unsigned int pipe; /* (in) pipe information */
1140 int status; /* (return) non-ISO status */
1141 unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/
1142 void *transfer_buffer; /* (in) associated data buffer */
1143 dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
1144 int transfer_buffer_length; /* (in) data buffer length */
1145 int actual_length; /* (return) actual transfer length */
1146 unsigned char *setup_packet; /* (in) setup packet (control only) */
1147 dma_addr_t setup_dma; /* (in) dma addr for setup_packet */
1148 int start_frame; /* (modify) start frame (ISO) */
1149 int number_of_packets; /* (in) number of ISO packets */
1150 int interval; /* (modify) transfer interval
1151 * (INT/ISO) */
1152 int error_count; /* (return) number of ISO errors */
1153 void *context; /* (in) context for completion */
1154 usb_complete_t complete; /* (in) completion routine */
1155 struct usb_iso_packet_descriptor iso_frame_desc[0];
1156 /* (in) ISO ONLY */
1157 };
“年度最大赃物”——俄罗斯一神秘男子偷走跨度达5米的整座钢桥切割后当废铁卖,俄罗斯警方破案后称。
“年度最长结构”——经过了惊情四百年,看过了上下数百行,我们对struct urb说。
1129行,kref,urb的引用计数。甭看它是隐藏在urb内部的一个不起眼的小角色,但小角色做大事情,它决定了一个urb的生死存亡。一个urb有用没用,是继续委以重任还是无情销毁都要看它的脸色。那第一个问题就来了,为什么urb的生死要掌握在这个小小的引用计数手里边儿?
很早很早很早很早以前就说过,主机与设备之间通过管道来传输数据,管道的一端是主机上的一个缓冲区,另一端是设备上的端点。管道之中流动的数据,在主机控制器和设备看来是一个个packets,在咱们看来就是urb。因而,端点之中就有那么一个队列,叫urb队列。不过,这并不代表一个urb只能发配给一个端点,它可能通过不同的管道发配给不同的端点,那么这样一来,我们如何知道这个urb正在被多少个端点使用,如何判断这个urb的生命已经over?如果没有任何一个端点在使用它,而我们又无法判断这种情况,它就会永远的飘荡在usb的世界里,犹如飘荡在人冥两届的冤魂。我们需要寻求某种办法在这种情况下给它们一个好的归宿,这就是引用计数。每多一个使用者,它的这个引用计数就加1,每减少一个使用者,引用计数就减一,如果连最后一个使用者都释放了这个urb,宣称不再使用它了,那它的生命周期就走到了尽头,会自动的销毁。
接下来就是第二个问题,如何来表示这个神奇的引用计数?其实它是一个struct kref结构体,在include/linux/kref.h里定义
23 struct kref {
24 atomic_t refcount;
25 };
这个结构与struct urb相比简约到极致了,简直就是迎着咱们的口味来的。不过别看它简单,内核里就是使用它来判断一个对象还有没有用的。它里边儿只包括了一个原子变量,为什么是原子变量?既然都使用引用计数了,那就说明可能同时有多个地方在使用这个对象,总要考虑一下它们同时修改这个计数的可能性吧,也就是俗称的并发访问,那怎么办?加个锁?就这么一个整数值专门加个锁未免也忒大材小用了些,所以就使用了原子变量。围绕这个结构,内核里还定义了几个专门操作引用计数的函数,它们在lib/kref.c里定义
17 /**
18* kref_init - initialize object.
19* @kref: object in question.
20*/
21 void kref_init(struct kref *kref)
22 {
23 atomic_set(&kref->refcount,1);
25 }
27 /**
28* kref_get - increment refcount for object.
29* @kref: object.
30*/
31 void kref_get(struct kref *kref)
32 {
33 WARN_ON(!atomic_read(&kref->refcount));
34 atomic_inc(&kref->refcount);
36 }
38 /**
39* kref_put - decrement refcount for object.
40* @kref: object.
41* @release: pointer to the function that will clean up the object when the
42* last reference to the object is released.
43* This pointer is required, and it is not acceptable to pass kfree
44* in as this function.
46* Decrement the refcount, and if 0, call release().
47* Return 1 if the object was removed, otherwise return 0.Beware, if this
48* function returns 0, you still can not count on the kref from remaining in
49* memory.Only use the return value if you want to see if the kref is now
50* gone, not present.
51*/
52 int kref_put(struct kref *kref, void (*release)(struct kref *kref))
53 {
55 WARN_ON(release == (void (*)(struct kref *))kfree);
57 if (atomic_dec_and_test(&kref->refcount)) {
59 return 1;
60 }
61 return 0;
62 }
整个kref.c文件就定义了这么三个函数,kref_init初始化,kref_get将引用计数加1,kref_put将引用计数减一并判断是不是为0,为0的话就调用参数里release函数指针指向的函数把对象销毁掉。它们对独苗儿refcount的操作都是通过原子变量特有的操作函数,其实这句话可以当选当日最大废话,原子变量当然要使用专门的操作函数了,编译器还能做些优化,否则直接使用一般的变量就可以了干吗还要使用原子变量,不是没事找事儿么,再说如果你直接像对待一般整型值一样对待它,编译器也会看不过去你的行为,直接给你个error的。友情提醒一下,kref_init初始化时,是把refcount的值初始化为1了的,不是0。还有一点要说的是kref_put参数里的那个函数指针,你不能传递一个NULL过去,否则这个引用计数就只是计数,而背离了最初的目的,要记住我们需要在这个计数减为0的时候将嵌入这个引用计数struct kref结构体的对象给销毁掉,所以这个函数指针也不能为kfree,因为这样的话就只是把这个struct kref结构体给销毁了,而不是整个对象。
第三个问题,如何使用struct kref结构来为我们的对象计数?当然我们需要把这样一个结构嵌入到你希望计数的对象里边,不然你根本就无法对对象在它整个生命周期里的使用情况作出判断,难道还真能以为Linus是linux里的太阳,像太阳神阿波罗一样掐指一算就知道谁谁在哪儿待过,现在在哪儿。但是我们应该是几乎见不到内核里边儿直接使用上面那几个函数来给对象计数的,而是每种对象又定义了自己专用的引用计数函数,比如咱们的urb,在drivers/usb/core/urb.c里定义
17 /**
18* usb_init_urb - initializes a urb so that it can be used by a USB driver
19* @urb: pointer to the urb to initialize
21* Initializes a urb so that the USB subsystem can use it properly.
23* If a urb is created with a call to usb_alloc_urb() it is not
24* necessary to call this function.Only use this if you allocate the
25* space for a struct urb on your own.If you call this function, be
26* careful when freeing the memory for your urb that it is no longer in
27* use by the USB core.
29* Only use this function if you _really_ understand what you are doing.
30*/
31 void usb_init_urb(struct urb *urb)
32 {
33 if (urb) {
34 memset(urb, 0, sizeof(*urb));
37 }
38 }
71 /**
72* usb_free_urb - frees the memory used by a urb when all users of it are finished
73* @urb: pointer to the urb to free, may be NULL
75* Must be called when a user of a urb is finished with it.When the last user
76* of the urb calls this function, the memory of the urb is freed.
78* Note: The transfer buffer associated with the urb is not freed, that must be
79* done elsewhere.
80*/
81 void usb_free_urb(struct urb *urb)
82 {
83 if (urb)
85 }
87 /**
88* usb_get_urb - increments the reference count of the urb
89* @urb: pointer to the urb to modify, may be NULL
91* This must becalled whenever a urb is transferred from a device driver to a
92* host controller driver.This allows proper reference counting to happen
93* for urbs.
95* A pointer to the urb with the incremented reference counter is returned.
96*/
97 struct urb * usb_get_urb(struct urb *urb)
98 {
99 if (urb)
101 return urb;
102 }
usb_init_urb、usb_get_urb、usb_free_urb这三个函数分别调用了前面看到的struct kref结构的三个操作函数来进行引用计数的初始化、加1、减一。什么叫封装?这就叫封装。usb_init_urb和usb_get_urb都没什么好说的,比较感兴趣的是usb_free_urb里给kref_put传递的那个函数urb_destroy,它也在urb.c里定义
9 #define to_urb(d) container_of(d, struct urb, kref)
11 static void urb_destroy(struct kref *kref)
12 {
13 struct urb *urb = to_urb(kref);
15 }
这个urb_destroy首先调用了to_urb,实际上就是一个container_of来获得引用计数关联的那个urb,然后使用kfree将它销毁。
到此,世界如此美丽,引用计数如此简单,不是么?
1130行,lock,一把自旋锁。韦唯早就唱了,每个urb都有一把自旋锁。
1131行,hcpriv,走到今天,你应该明白这个urb最终还是要提交给主机控制器驱动的,这个字段就是urb里主机控制器驱动的自留地,咱们就不插手了。
1132行,use_count,这里又是一个使用计数,不过此计数非彼计数,它与上面那个用来追踪urb生命周期的kref一点儿血缘关系也没有,连远亲都不是。那它是用来做什么的,凭什么在臃肿的struct urb不断喊着要瘦身的时候还仍有一席之地?
先了解下使用urb来完成一次完整的usb通信都要经历哪些阶段,首先,驱动程序发现自己有与usb设备通信的需要,于是创建一个urb,并指定它的目的地是设备上的哪个端点,然后提交给usb core,usb core将它修修补补的做些美化之后再移交给主机控制器的驱动程序HCD,HCD会去解析这个urb,了解它的目的是什么,并与usb设备进行相应的交流,在交流结束,urb的目的达到之后,HCD再把这个urb的所有权移交回驱动程序。
这里的use_count就是在usb core将urb移交给HCD,办理移交手续的时候,插上了那么一脚,每当走到这一步,它的值就会加1。什么时候减1?在HCD重新将urb的所有权移交回驱动程序的时候。这样说吧,只要HCD拥有这个urb的所有权,那么该urb的use_count就不会为0。这么一说,似乎use_count也有点追踪urb生命周期的味道了,当它的值大于0时,就表示当前有HCD正在处理它,和上面的kref概念上有部分的重叠,不过,显然它们之间是有区别的,没区别的话这儿干吗要用两个计数,不是没事儿找抽么。上面的那个kref实现方式是内核里统一的引用计数机制,当计数减为0时,urb对象就被urb_destroy给销毁了。这里的use_count只是用来统计当前这个urb是不是正在被哪个HCD处理,即使它的值为0,也只是说明没有HCD在使用它而已,并不代表就得把它给销毁掉。比方说,HCD利用完了urb,把它还给了驱动,这时驱动还可以对这个urb检修检修,再提交给哪个HCD去使用。
下面的问题就是既然它不会平白无故的多出来,那它究竟是用来干啥的?还要从刚提到的那几个阶段说起。urb驱动也创建了,提交也提交了,HCD正处理着那,可驱动反悔了,它不想再继续这次通信了,想将这个urb给终止掉,善解任意的usb core当然会给驱动提供这样的接口来满足这样的需要。不过这个需要还被写代码的哥们儿细分为两种,一种是驱动只想通过usb core告诉HCD一声,说这个urb我想终止掉,您就别费心再处理了,然后它不想在那里等着HCD的处理,想忙别的事去,这就是俗称的异步,对应的是usb_unlink_urb函数。当然对应的还有种同步的,驱动会在那里苦苦等候着HCD的处理结果,等待着urb被终止,对应的是usb_kill_urb函数。而HCD将这次通信终止后,同样会将urb的所有权移交回驱动。那么驱动通过什么判断HCD已经终止了这次通信?就是通过这里的use_count,驱动会在usb_kill_urb里面一直等待着这个值变为0。
1133行,reject,拒绝,拒绝什么?不是邀请ppmm共进晚餐被拒绝,也不是你要求老板多给点薪水被拒绝,那又是被谁拒绝?
在目前版本的内核里,只有usb_kill_urb函数有特权对它进行修改,那么,显然reject就与上面说的urb终止有关了。那就看看drivers/usb/core/urb.c里定义的这个函数
444 /**
445* usb_kill_urb - cancel a transfer request and wait for it to finish
446* @urb: pointer to URB describing a previously submitted request,
447* may be NULL
449* This routine cancels an in-progress request.It is guaranteed that
450* upon return all completion handlers will have finished and the URB
451* will be totally idle and available for reuse.These features make
452* this an ideal way to stop I/O in a disconnect() callback or close()
453* function.If the request has not already finished or been unlinked
454* the completion handler will see urb->status == -ENOENT.
456* While the routine is running, attempts to resubmit the URB will fail
457* with error -EPERM.Thus even if the URB's completion handler always
458* tries to resubmit, it will not succeed and the URB will become idle.
460* This routine may not be used in an interrupt context (such as a bottom
461* half or a completion handler), or when holding a spinlock, or in other
462* situations where the caller can't schedule().
463*/
464 void usb_kill_urb(struct urb *urb)
465 {
467 if (!(urb && urb->dev && urb->dev->bus))
468 return;
470 ++urb->reject;
477 --urb->reject;
479 }
466行,因为usb_kill_urb函数要一直等候着HCD将urb终止掉,它必须是可以休眠的,不然就太可恶了,就像那些脚踩多只船的,占着本来就稀有的ppmm资源,让大批男同志们找不到另一半来关爱。而历史上,当大批男性无法结婚时,他们就会聚到一起,要么成为和尚,要么结为匪帮,所以说这可是一个严重的社会问题、治安问题。所以说usb_kill_urb不能用在中断上下文,必须能够休眠将自己占的资源给让出来。
写代码的哥们儿也都是忧国忧民的主儿,也深刻体会到广大男同胞们的无奈,于是提供了might_sleep函数,用它来判断一下这个函数是不是处在能够休眠的情况,如果不是,就会打印出一大堆的堆栈信息,比如你在中断上下文调用了这个函数时。不过,它也就是基于调试的目的用一用,方便日后找错,并不能强制哪个函数改变自己的上下文。法律也规定了要一夫一妻制,但也就是用来警示警示,如果以为实际上真能禁止些什么,纯粹就是扯淡。
467行,这里就是判断一下urb,urb要去的那个设备,还有那个设备在的总线有没有,如果哪个不存在,就还是返回吧。
469行,去获得每个urb都有的那把锁,然后将reject加1。加1有什么用?其实目前版本的内核里只有两个地方用到了这个值进行判断。第一个地方是在usb core将urb提交给HCD,正在办移交手续的时候,如果reject大于0,就不再接着移交了,也就是说这个urb被HCD给拒绝了。这是为了防止这边儿正在终止这个urb,那边儿某个地方却又妄想将这个urb重新提交给HCD。
473行,这里告诉HCD驱动要终止这个urb了,usb_hcd_unlink_urb函数也只是告诉HCD一声,然后不管HCD怎么处理就返回了。
474行,上面的usb_hcd_unlink_urb是返回了,但并不代表HCD已经将urb给终止了,HCD可能没那么快,所以这里usb_kill_urb要休息休息,等人通知它。这里使用了wait_event宏来实现休眠,usb_kill_urb_queue是在/drivers/usb/core/hcd.h里定义的一个等待队列,专门给usb_kill_urb休息用的。需要注意的是这里的唤醒条件,use_count必须等于0,终于看到use_count实战的地方了。
那在哪里唤醒正在睡大觉的usb_kill_urb?这牵扯到了第二个使用reject来做判断的地方。在HCD将urb的所有权返还给驱动的时候,会对reject进行判断,如果reject大于0,就调用wake_up唤醒在usb_kill_urb_queue上休息的usb_kill_urb。也好理解,HCD都要将urb的所有权返回给驱动了,那当然就是已经处理完了,放在这里就是已经将这个urb终止了,usb_kill_urb等的就是这一天的到来,当然就要醒过来继续往下走了。
476行,再次获得urb的那把锁,将reject刚才增加的那个1给减掉。urb都已经终止了,也没人再会去拒绝它了,reject还是开始什么样儿结束的时候就什么样吧。
索性将usb_unlink_urb函数也贴出来看看它们之间有什么区别吧
435 int usb_unlink_urb(struct urb *urb)
436 {
437 if (!urb)
438 return -EINVAL;
439 if (!(urb->dev && urb->dev->bus))
440 return -ENODEV;
442 }
usb_unlink_urb这儿就简单多了,只是把自己的意愿告诉HCD,然后就非常洒脱的返回了。
struct urb结构里的前边儿这几个,只是usb core和主机控制器驱动需要关心的,实际的驱动里根本用不着也管不着,它们就是usb和HCD的后花园,想种点什么不种点什么都由写这块儿代码的哥们儿决定,他们在里面怎么为所欲为都不关你写驱动的啥事。usb在linux里起起伏伏这么多年,前边儿的这些内容早就变过多少次,说不定你今天还看到谁谁,到接下来的哪天就看不到了,不过,变化的是形式,不变的是道理。驱动要做的只是创建一个urb,然后初始化,再把它提交给usb core就可以了,使用不使用引用计数,加不加锁之类的一点都不用去操心。感谢David Brownell,感谢Alan Stern,感谢……,没有他们就没有usb在linux里的今天。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics