现在的位置: 首页 > 综合 > 正文

Linux那些事儿之我是U盘(45)迷雾重重的Bulk传输(三)

2013年08月26日 ⁄ 综合 ⁄ 共 3689字 ⁄ 字号 评论关闭

   usb_stor_Bulk_transport(), 古人一针见血的为我们指出了这个函数中调用的第一个最重要的函数,那就是usb_stor_bulk_transfer_buf().仍然是来自drivers/usb/stroage/transport.c.

     409 /*
    410  * Transfer one buffer via bulk pipe, without timeouts, but allowing early
    411  * termination.  Return codes are USB_STOR_XFER_xxx.  If the bulk pipe
    412  * stalls during the transfer, the halt is automatically cleared.
    413  */
    414 int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
    415         void *buf, unsigned int length, unsigned int *act_len)
    416 {
    417         int result;
    418
    419         US_DEBUGP("%s: xfer %u bytes/n", __FUNCTION__, length);
    420
    421         /* fill and submit the URB */
    422         usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf, length,
    423                       usb_stor_blocking_completion, NULL);
    424         result = usb_stor_msg_common(us, 0);
    425
    426         /* store the actual length of the data transferred */
    427         if (act_len)
    428                 *act_len = us->current_urb->actual_length;
    429         return interpret_urb_result(us, pipe, length, result,
    430                         us->current_urb->actual_length);
    431 }
  一路走来的同志们不会对这里这个usb_fill_bulk_urb()完全陌生.我们的确是第一次见这个函数,但是此前我们有见过usb_fill_control_urb(),除此之外还有一个叫做usb_fill_int_urb()的函数,不用说,这几个函数是差不多的,只不过她们分别对应usb传输模式中的bulk,control,interrupt.唯一一处和usb_fill_control_urb不同的便是bulk传输不需要有一个setup_packet.具体来看,usb_fill_bulk_urb()定义于include/linux/usb.h:

845 /**
    846  * usb_fill_bulk_urb - macro to help initialize a bulk urb
    847  * @urb: pointer to the urb to initialize.
    848  * @dev: pointer to the struct usb_device for this urb.
    849  * @pipe: the endpoint pipe
    850  * @transfer_buffer: pointer to the transfer buffer
    851  * @buffer_length: length of the transfer buffer
    852  * @complete: pointer to the usb_complete_t function
    853  * @context: what to set the urb context to.
    854  *
    855  * Initializes a bulk urb with the proper information needed to submit it
    856  * to a device.
    857  */
    858 static inline void usb_fill_bulk_urb (struct urb *urb,
    859                                       struct usb_device *dev,
    860                                       unsigned int pipe,
    861                                       void *transfer_buffer,
    862                                       int buffer_length,
    863                                       usb_complete_t complete,
    864                                       void *context)
    865 {
    866         spin_lock_init(&urb->lock);
    867         urb->dev = dev;
    868         urb->pipe = pipe;
    869         urb->transfer_buffer = transfer_buffer;
    870         urb->transfer_buffer_length = buffer_length;
    871         urb->complete = complete;
    872         urb->context = context;
    873 }

  看过了那个usb_fill_control_urb之后看这个函数应该是很简单的了.结合上面调用这个函数的代码,可知,urb->complete被赋值为usb_stor_blocking_completion,不用说,这个函数之后肯定会被调用.正如上次控制传输中所讲的那样.

424,usb_stor_msg_common()这个函数再一次被调用,年年岁岁花相似,岁岁年年人不同,urb还像上次那样被被提交,然后核心层去调度,去执行她.如果结果是提交成功了,那么返回值result将是0.act_len将记录实际传输的长度.不过光看这两个函数其实看不出什么,我们必须结合上下文来看.换句话说,我们需要结合usb_stor_Bulk_transport()usb_stor_bulk_transfer_buf被调用的上下文,对比形参和实参来看,才能真的明白,才能拨开这浓浓的迷雾.

usb_stor_Bulk_transport()函数中,978,usb_stor_bulk_transfer_buf()函数得到调用.第一个参数,us,无需多说,第二个参数,us->send_bulk_pipe,作为u盘来说,她除了有一个控制管道以外,还会有两个bulk管道,一个是In,一个是Out,经历过此前的风风雨雨,咱们已经对usb中那些名词不再有神秘感,所谓管道无非就是一个unsigned int类型的数.us->send_bulk_pipe和接下来我们立刻会邂逅的us->recv_bulk_pipe都是在曾经那个令人回味的storage_probe()中调用get_pipes()函数获得的.然后第三个参数bcb,这是什么玩艺?嘿嘿,看仔细了.

950,定义了这么一个指针bcb,struct bulk_cb_wrap结构体的指针,这是一个专门为bulk only协议特别准备的数据结构,来自drivers/usb/storage/transport.h:

     80 /*
     81  * Bulk only data structures
     82  */
     83
     84 /* command block wrapper */
     85 struct bulk_cb_wrap {
     86         __le32  Signature;              /* contains 'USBC' */
     87         __u32   Tag;                    /* unique per command id */
     88         __le32  DataTransferLength;     /* size of data */
     89

抱歉!评论已关闭.