直到现在我们才将第一次真正的开始接触usb的四种数据传输之一,控制传输.应该说从这一刻开始,代码开始变得复杂了.不过不要怕,有我在.在这个美妙的夏夜,让我们剪一段月光,来解代码的霜.
769至777行,做了一件事情,确定这个设备的max lun.不要说你不知道什么是max lun.不知道的回去跪主板吧,我很负责任的向你推荐我们Intel最新的3系列整合芯片组主板.
在get_transport()函数中,我们针对各种情况给us->max_lun赋了值,但是我们当时就注意到了,唯独对于Bulk-Only的设备,当时并没有赋值,所以这里我们看到,对于us->protocol等于US_PR_BULK的情况,有一个专门的函数来获得这个设备的max lun.网友女为悦己者_整_容好奇的问,为什么写代码的同志在这里对Bulk-Only的设备表现出一种”偏偏喜欢你”的态度呢?没什么特别的,党中央规定的.所有的usb设备遵守一个规范,这个规范叫做usb spec,而usb设备分为很多种类,usb mass storage是其中一类,而mass storage设备又分为很多子类,每个子类又有它自己的规范,比如U盘它所遵守的就是usb mass storage class bulk-only transport spec.而这个规范说得很清楚,对于这种设备,它的lun不是凭感觉就能判断的,你得发送一个命令给它,向它去查询,然后它会做出响应,这样你才能知道它究竟是几个lun.这条命令就是”GET MAX LUN”,详见spec 3.2.
所以我们即使不认真看这个函数也可以知道究竟发生了什么.而且我们之前还说过,普通的U盘的max lun肯定是0.对于那种读卡器才可能有多个lun.不过我们还是不妨来深入的看一下这个函数,毕竟这个函数是在drivers/usb/storage/transport.c中,属于我们的辖区.当然更重要的是,此前我们一直没有真正见识过究竟一次usb传输是怎么回事,作为usb设备驱动程序究竟如何发起usb传输,而这个函数正好给了我们一次不错的机会.同时我们也将会知道,了解了一次控制传输之后,别的传输也会很容易理解.
首先我们知道这次传输的目的是为了获得一个数字,max lun,而获得这个数据的方式是发送命令,所以整个过程就是,你发送一个命令给设备,设备返回一个值给你,这么简单的传输叫什么?控制传输.很显然,地球人都知道,控制传输是usb四种传输方式中最简单的那种.来看具体代码:
908 /* Determine what the maximum LUN supported is */
909 int usb_stor_Bulk_max_lun(struct us_data *us)
910 {
911 int result;
912
913 /* issue the command */
914 result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
915 US_BULK_GET_MAX_LUN,
916 USB_DIR_IN | USB_TYPE_CLASS |
917 USB_RECIP_INTERFACE,
918 0, us->ifnum, us->iobuf, 1, HZ);
919
920 US_DEBUGP("GetMaxLUN command result is %d, data is %d/n",
921 result, us->iobuf[0]);
922
923 /* if we have a successful request, return the result */
924 if (result > 0)
925 return us->iobuf[0];
926
927 /*
928 * Some devices (i.e. Iomega Zip100) need this -- apparently
929 * the bulk pipes get STALLed when the GetMaxLUN request is
930 * processed. This is, in theory, harmless to all other devices
931 * (regardless of if they stall or not).
932 */
933 if (result == -EPIPE) {
934 usb_stor_clear_halt(us, us->recv_bulk_pipe);
935 usb_stor_clear_halt(us, us->send_bulk_pipe);
936 }
937
938 /*
939 * Some devices don't like GetMaxLUN. They may STALL the control
940 * pipe, they may return a zero-length result, they may do nothing at
941 * all and timeout, or they may fail in even more bizarrely creative
942 * ways. In these cases the best approach is to use the default
943 * value: only one LUN.
944 */
945 return 0;
946 }
代码不长,不过并不容易.首先914行, usb_stor_control_msg()函数被调用,这也是我们自己定义的函数,所以也得讲,同样来自drivers/usb/storage/transport.c:
209
210 /*
211 * Transfer one control message, with timeouts, and allowing early
212 * termination. Return codes are usual -Exxx, *not* USB_STOR_XFER_xxx.
213 */
214 int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
215 u8 request, u8 requesttype, u16 value, u16 index,
216 void *data, u16 size, int timeout)
217 {
218 int status;
219
220 US_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u/n",
221 __FUNCTION__, request, requesttype,
222 value, index, size);
223
224 /* fill in the devrequest structure */
225 us->cr->bRequestType = requesttype;
226 us->cr->bRequest = request;
227 us->cr->wValue = cpu_to_le16(value);
228 us->cr->wIndex = cpu_to_le16(index);
229 us->cr->wLength = cpu_to_le16(size);
230
231 /* fill and submit the URB */
232 usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe,
233 (unsigned char*) us->cr, data, size,
234 usb_stor_blocking_completion, NULL);
235 status = usb_stor_msg_common(us, timeout);
236
237 /* return the actual length of the data transferred if no error */
238 if (status == 0)
239 status = us->current_urb->actual_length;
240 return status;
241 }
这里相对麻烦一点的函数是usb_stor_msg_common,仍然是我们自己定义的函数,所以我们又得继续往下一层看,这么多层函数调用的确挺让人看了头晕,一个人总要走陌生的路,看陌生的风景,听陌生的歌,然后在某个不经意的瞬间,你会发现,原本费尽心机想要弄清楚的函数就这么把自己弄糊涂了.然而,就像世上的每一条路都是弯的一样,每一个模块都会有曲折的函数调用,写代码的哥们儿为了表现自己一流的编剧水平,永远不会让我们一路平稳的看完整个模块的.除了面对,我们别无选择,毕竟从我们年幼时,摇篮就告诉我们,人生是不平静的,也是动荡的,所以为何不微笑着面对这些麻烦?这个函数仍旧是来自drivers/usb/storage/transport.c:
132 /* This is the common part of the URB message submission code
133 *
134 * All URBs from the usb-storage driver involved in handling a queued scsi
135 * command _must_ pass through this function (or something like it) for the
136 * abort mechanisms to work properly.
137 */
138 static int usb_stor_msg_common(struct us_data *us, int timeout)
139 {
140 struct completion urb_done;
141 struct timer_list to_timer;
142 int status;
143
144 /* don't submit URBs during abort/disconnect processing */
145 if (us->flags & ABORTING_OR_DISCONNECTING)
146 return -EIO;
147
148 /* set up data structures for the wakeup system */
149 init_completion(&urb_done);
150
151 /* fill the common fields in the URB */
152 us->current_urb->context = &urb_done;
153 us->current_urb->actual_length = 0;
154 us->current_urb->error_count = 0;
155 us->current_urb->status = 0;
156
157 /* we assume that if transfer_buffer isn't us->iobuf then it
158 * hasn't been mapped for DMA. Yes, this is clunky, but it's
159 * easier than always having the caller tell us whether the
160 * transfer buffer has already been mapped. */
161 us->current_urb->transfer_flags =
162 URB_ASYNC_UNLINK | URB_NO_SETUP_DMA_MAP;
163 if (us->current_urb->transfer_buffer == us->iobuf)
164 us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
165 us->current_urb->transfer_dma = us->iobuf_dma;
166 us->current_urb->setup_dma = us->cr_dma;
167
168 /* submit the URB */
169 status = usb_submit_urb(us->current_urb, GFP_NOIO);
170 if (status) {
171 /* something went wrong */
172 return status;
173 }
174
175 /* since the URB has been submitted successfully, it's now okay
176 * to cancel it */
177 set_bit(US_FLIDX_URB_ACTIVE, &us->flags);
178
179 /* did an abort/disconnect occur during the submission? */
180 if (us->flags & ABORTING_OR_DISCONNECTING) {
181
182 /* cancel the URB, if it hasn't been cancelled already */
183 if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {
184 US_DEBUGP("-- cancelling URB/n");
185 usb_unlink_urb(us->current_urb);
186 }
187 }
188
189 /* submit the timeout timer, if a timeout was requested */
190 if (timeout > 0) {
191 init_timer(&to_timer);
192 to_timer.expires = jiffies + timeout;
193 to_timer.function = timeout_handler;
194 to_timer.data = (unsigned long) us;
195 add_timer(&to_timer);
196 }
197
198 /* wait for the completion of the URB */
199 wait_for_completion(&urb_done);
200 clear_bit(US_FLIDX_URB_ACTIVE, &us->flags);
201
202 /* clean up the timeout timer */
203 if (timeout > 0)
204 del_timer_sync(&to_timer);
205
206 /* return the URB status */
207 return us->current_urb->status;
208 }
好了,代码贴完了,现在让我们一点一点去认识这段代码.记住我们最终就是为了看清楚usb_stor_Bulk_max_lun()这个函数究竟是怎么获得max lun的.