其实故事已经讲了很久,但如果你觉得到这里你已经把故事都看明白了,那么你错了。不仅仅是错了。不信,我们就继续看,先看512行,us->transport(),这个函数指针同样是在storage_probe时被赋值,对于U盘,它遵守的是Bulk-Only协议,因此us->transport()被赋值为usb_stor_Bulk_transport()。来看usb_stor_Bulk_transport(),它同样来自drivers/usb/storage/transport.c:

941 int usb_stor_Bulk_transport(struct scsi_cmnd*srb, struct us_data *us)

942 {

943      struct bulk_cb_wrap *bcb = (structbulk_cb_wrap *) us->iobuf;

944      struct bulk_cs_wrap *bcs = (structbulk_cs_wrap *) us->iobuf;

945      unsigned int transfer_length =srb->request_bufflen;

946      unsigned int residue;

947     int result;

948      int fake_sense = 0;

949      unsigned int cswlen;

950      unsigned int cbwlen = US_BULK_CB_WRAP_LEN;

951

952      /* Take care of BULK32 devices; set extra Byteto 0 */

953      if ( unlikely(us->flags &US_FL_BULK32)) {

954           cbwlen = 32;

955           us->iobuf[31] = 0;

956      }

957

958      /* set up the command wrapper */

959      bcb->Signature =cpu_to_le32(US_BULK_CB_SIGN);

960      bcb->DataTransferLength =cpu_to_le32(transfer_length);

961      bcb->Flags = srb->sc_data_direction ==DMA_FROM_DEVICE ? 1 <<7 : 0;

962      bcb->Tag= ++us->tag;

963      bcb->Lun= srb->device->lun;

964      if (us->flags & US_FL_SCM_MULT_TARG)

965           bcb->Lun |= srb->device->id <<4;

966      bcb->Length = srb->cmd_len;

967

968      /* copy the command payload */

969      memset(bcb->CDB, 0, sizeof(bcb->CDB));

970      memcpy(bcb->CDB, srb->cmnd,bcb->Length);

971

972      /* send it to out endpoint */

973      US_DEBUGP("Bulk Command S 0x%x T 0x%x L%d F %d Trg %d LUN %d CL %d\n",

974                        le32_to_cpu(bcb->Signature), bcb->Tag,

975                         le32_to_cpu(bcb->DataTransferLength),bcb->Flags,

976                         (bcb->Lun >>4), (bcb->Lun & 0x0F),

977                         bcb->Length);

978      result = usb_stor_bulk_transfer_buf(us,us->send_bulk_pipe,

979                                 bcb, cbwlen,NULL);

980      US_DEBUGP("Bulk command transferresult=%d\n", result);

981      if (result != USB_STOR_XFER_GOOD)

982           return USB_STOR_TRANSPORT_ERROR;

983

984      /* DATA STAGE */

985      /* send/receive data payload, if there is any*/

986

987      /* Some USB-IDE converter chips need a 100usdelay between the

988       *command phase and the data phase.  Somedevices need a little

989       * morethan that, probably because of clock rate inaccuracies. */

990      if (unlikely(us->flags &US_FL_GO_SLOW))

991           udelay(125);

992

993      if (transfer_length) {

994      unsigned int pipe = srb->sc_data_direction== DMA_FROM_DEVICE ?

995                                us->recv_bulk_pipe : us->send_bulk_pipe;

996      result = usb_stor_bulk_transfer_sg(us, pipe,

997                                srb->request_buffer, transfer_length,

998                                 srb->use_sg, &srb->resid);

999           US_DEBUGP("Bulk data transfer result0x%x\n", result);

1000          if (result == USB_STOR_XFER_ERROR)

1001              return USB_STOR_TRANSPORT_ERROR;

1002

1003          /* If the device tried to send back more datathan the

1004           *amount requested, the spec requires us to transfer

1005            * theCSW anyway.  Since there's no pointretrying the

1006           * thecommand, we'll return fake sense data indicating

1007           * IllegalRequest, Invalid Field in CDB.

1008           */

1009         if (result == USB_STOR_XFER_LONG)

1010              fake_sense = 1;

1011    }

1012

1013    /* See flow chart on pg 15 of the Bulk OnlyTransport spec for

1014      * anexplanation of how this code works.

1015      */

1016

1017     /* get CSW for device status */

1018    US_DEBUGP("Attempting to getCSW...\n");

1019     result = usb_stor_bulk_transfer_buf(us,us->recv_bulk_pipe,

1020                                 bcs,US_BULK_CS_WRAP_LEN, &cswlen);

1021

1022    /* Some broken devices add unnecessaryzero-length packets to the

1023      * endof their data transfers.  Such packetsshow up as 0-length

1024      *CSWs.  If we encounter such a thing, tryto read the CSW again.

1025     */

1026     if (result == USB_STOR_XFER_SHORT &&cswlen == 0) {

1027          US_DEBUGP("Received 0-length CSW;retrying...\n");

1028         result = usb_stor_bulk_transfer_buf(us,us->recv_bulk_pipe,

1029                                 bcs,US_BULK_CS_WRAP_LEN, &cswlen);

1030     }

1031

1032     /* did the attempt to read the CSW fail? */

1033     if (result == USB_STOR_XFER_STALLED) {

1034

1035          /* get the status again */

1036          US_DEBUGP("Attempting to get CSW (2ndtry)...\n");

1037         result = usb_stor_bulk_transfer_buf(us,us->recv_bulk_pipe,

1038                                 bcs,US_BULK_CS_WRAP_LEN, NULL);

1039     }

1040

1041     /* if we still have a failure at this point,we're in trouble */

1042     US_DEBUGP("Bulk status result =%d\n", result);

1043     if(result != USB_STOR_XFER_GOOD)

1044          return USB_STOR_TRANSPORT_ERROR;

1045

1046     /* check bulk status */

1047    residue = le32_to_cpu(bcs->Residue);

1048     US_DEBUGP("Bulk Status S 0x%x T 0x%x R%u Stat 0x%x\n",

1049                         le32_to_cpu(bcs->Signature), bcs->Tag,

1050                         residue,bcs->Status);

1051     if (bcs->Tag != us->tag ||bcs->Status > US_BULK_STAT_PHASE) {

1052          US_DEBUGP("Bulk logical error\n");

1053          return USB_STOR_TRANSPORT_ERROR;

1054     }

1055

1056     /* Some broken devices report odd signatures,so we do not check them

1057      * forvalidity against the spec. We store the first one we see,

1058      * andcheck subsequent transfers for validity against this signature.

1059      */

1060     if (!us->bcs_signature) {

1061          us->bcs_signature = bcs->Signature;

1062          if (us->bcs_signature !=cpu_to_le32(US_BULK_CS_SIGN))

1063              US_DEBUGP("Learnt BCSsignature 0x%08X\n",

1064                                         le32_to_cpu(us->bcs_signature));

1065     } else if (bcs->Signature !=us->bcs_signature) {

1066          US_DEBUGP("Signature mismatch: got %08X,expecting %08X\n",

1067                          le32_to_cpu(bcs->Signature),

1068                           le32_to_cpu(us->bcs_signature));

1069          return USB_STOR_TRANSPORT_ERROR;

1070     }

1071

1072     /* try to compute the actual residue, basedon how much data

1073      * wasreally transferred and what the device tells us */

1074     if (residue) {

1075          if(!(us->flags & US_FL_IGNORE_RESIDUE)) {

1076          residue = min(residue,transfer_length);

1077              srb->resid =max(srb->resid, (int) residue);

1078          }

1079     }

1080

1081     /* based on the status code, we report goodor bad */

1082    switch (bcs->Status) {

1083    case US_BULK_STAT_OK:

1084         /* device babbled -- return fake sense data */

1085          if (fake_sense) {

1086              memcpy(srb->sense_buffer,

1087                               usb_stor_sense_invalidCDB,

1088                               sizeof(usb_stor_sense_invalidCDB));

1089          returnUSB_STOR_TRANSPORT_NO_SENSE;

1090          }

1091

1092         /* command good -- note that data could beshort */

1093          return USB_STOR_TRANSPORT_GOOD;

1094

1095    case US_BULK_STAT_FAIL:

1096          /* command failed */

1097         return USB_STOR_TRANSPORT_FAILED;

1098

1099    case US_BULK_STAT_PHASE:

1100          /* phase error -- note that a transport resetwill be

1101          *invoked by the invoke_transport() function

1102          */

1103         return USB_STOR_TRANSPORT_ERROR;

1104    }

1105

1106    /* we should never get here, but if we do,we're in trouble */

1107     return USB_STOR_TRANSPORT_ERROR;

1108 }

这个函数也不是好“惹”的。但正是这个函数掀开了我们批量传输的新篇章。

《Linux那些事儿之我是USB》我是U盘(33)迷雾重重的批量传输(二)相关推荐

  1. 《Linux那些事儿之我是USB》我是U盘(37)迷雾重重的批量传输(六)

    usb_stor_bulk_transfer_sglist()函数有一定的"蛊惑性",我们前面说过,之所以采用sglist,就是为了提高传输效率.我们更知道,sg的目的就是让一堆不 ...

  2. 《Linux那些事儿之我是USB》我是U盘(34)迷雾重重的批量传输(三)

    在usb_stor_Bulk_transport()中,这个函数中调用的第一个最重要的函数,那就是usb_stor_bulk_transfer_buf().仍然是来自drivers/usb/stroa ...

  3. 《Linux那些事儿之我是USB》我是U盘(36)迷雾重重的批量传输(五)

    在讲数据传输阶段之前,先解决刚才的历史遗留问题.usb_stor_bulk_transfer_buf()中,406行,有一个很有趣的函数interpret_urb_result()被调用.这个函数同样 ...

  4. 《Linux那些事儿之我是USB》我是U盘(35)迷雾重重的批量传输(四)

    有时候我也被这个问题所困扰,我不知道是我不明白,还是这世界变化太快.连Linux中都引入了过期这么一个概念.设置一个时间,如果时间到了该做的事情还没有做完,那么某些事情就会发生. 比如需要烤蛋糕,现在 ...

  5. 《Linux那些事儿之我是USB》我是U盘(32)迷雾重重的批量传输(一)

    374行,us->proto_handler()其实是一个函数指针,知道它指向什么吗?我们早在storage_probe()中,确切地说,在get_protocol()就赋了值,当时只知道是ge ...

  6. Linux那些事儿 之 戏说USB(3)我是一棵树

    从拓扑上来看,USB子系统并不以总线的方式来部署,它是一颗由几个点对点的连接构成的树. 它主要包括了USB连接.USB host controller和USB device三个部分.而USB devi ...

  7. Linux那些事儿 之 戏说USB(22)设备的生命线(五)

    下面接着看那三个基本点. 第一个基本点,usb_alloc_urb函数,创建urb的专用函数,为一个urb申请内存并做初始化,在drviers/usb/core/urb.c里定义. struct ur ...

  8. Linux那些事儿 之 戏说USB(15)设备

    struct usb_device结构冗长而又杂乱 include/linux/usb.h struct usb_device {int devnum;char devpath[16];u32 rou ...

  9. Linux那些事儿 之 戏说USB(25)设备的生命线(四)

    转载地址:http://blog.csdn.net/fudan_abc/article/details/1819919 洗澡是屁股享福,脑袋吃苦:看电影是脑袋享福,屁股吃苦:看内核代码是脑袋.屁股都吃 ...

最新文章

  1. python -- numpy 基本数据类型,算术运算,组合,分割 函数
  2. Class NPOI
  3. JS图片放大查看效果!
  4. 【杭州】Hack for Cloud Beginner微软黑客松大赛
  5. DEX Integral 上线 11 小时锁仓价值接近 3 亿美元
  6. 【Data guard】Failover切换
  7. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 图片:为图片添加圆角 (IE8 不支持)
  8. 解决sklearn库使用过程中No module named model_selection的错误
  9. (转)图文详解手把手教你在Windows环境下下载Android源码(Launcher为例)
  10. Mastik:微体系结构侧信道攻击工具包
  11. 全国大学生计算机ms系统,全国计算机等级考试一级计算机基础及MS Office应用模拟练习系统...
  12. (转)电脑内外接口全程图解
  13. SPSS神经网络心得(一)
  14. 和老外聊天、发邮件常用英语缩写(超实用)
  15. 北辰创业笔记:百度引流推广有用吗?百度引流最有效的方法
  16. 单片机复位电路是怎么工作的?
  17. 深职计算机学院官网,深圳职业中专
  18. 怎样看股市K线图指标之相对价位指标CKD
  19. 如何在WORD中输入方框,并且在里面打勾?
  20. Google 出的 Guava 是个什么鬼?

热门文章

  1. 波斯顿翻跟头机器人_翻跟头和大圣有的一拼 波士顿动力机器人演示惊艳
  2. docker配置OOM打dump追加时间戳
  3. CSS加号(+)选择器
  4. 基于RTL8211E的千兆以太网收发verilog程序(已经硬件验证,初学=语法注释较多)
  5. 透视前端工程化之一:模板功能设计
  6. 2012年元旦,我为何离家出走?
  7. 数学分析教程史济怀练习15.4
  8. MAC搭建kafka客户端以及实现生产消费
  9. mysql mac 客户端
  10. windows 10 Quick Assist 远程协助工具