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

【转】Linux那些事儿之我是U盘(44)迷雾重重的Bulk传输(二)

2013年01月22日 ⁄ 综合 ⁄ 共 7275字 ⁄ 字号 评论关闭
其实故事已经讲了很久了,但如果你觉得到这里你已经把故事都看明白了,那么你错了.不仅仅是错了,你这种想法无异于就是,手里拿着一把刀,就以为自己是刀郎,手里举着一个窝头,就以为自己是托塔李天王.不信,我们就继续看,先看535,us->transport(),这个函数指针同样是在storage_probe的时候被赋值,对于咱们的u,她遵守的是Bulk-Only协议,因此us->transport()被赋值为usb_stor_Bulk_transport().来看usb_stor_Bulk_transport(),她同样来自drivers/usb/storage/transport.c:

948 int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
    949 {
    950         struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
    951         struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
    952         unsigned int transfer_length = srb->request_bufflen;
    953         unsigned int residue;
    954         int result;
    955         int fake_sense = 0;
    956         unsigned int cswlen;
    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 = srb->serial_number;
    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, US_BULK_CB_WRAP_LEN, NULL);
    980         US_DEBUGP("Bulk command transfer result=%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         /* Genesys Logic interface chips need a 100us delay between the
    988          * command phase and the data phase */
    989         if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS)
    990                 udelay(100);
    991
    992         if (transfer_length) {
    993                 unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ?
    994                                 us->recv_bulk_pipe : us->send_bulk_pipe;
    995                 result = usb_stor_bulk_transfer_sg(us, pipe,
    996                                         srb->request_buffer, transfer_length,
    997                                         srb->use_sg, &srb->resid);
    998                 US_DEBUGP("Bulk data transfer result 0x%x/n", result);
    999                 if (result == USB_STOR_XFER_ERROR)
   1000                         return USB_STOR_TRANSPORT_ERROR;
   1001
   1002                 /* If the device tried to send back more data than the
   1003                  * amount requested, the spec requires us to transfer
   1004                  * the CSW anyway.  Since there's no point retrying the
   1005                  * the command, we'll return fake sense data indicating
   1006                  * Illegal Request, Invalid Field in CDB.
   1007                  */
   1008                 if (result == USB_STOR_XFER_LONG)
   1009                         fake_sense = 1;
   1010         }
   1011
   1012         /* See flow chart on pg 15 of the Bulk Only Transport spec for
   1013          * an explanation of how this code works.
   1014          */
   1015
   1016         /* get CSW for device status */
   1017         US_DEBUGP("Attempting to get CSW.../n");
   1018         result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
   1019                                 bcs, US_BULK_CS_WRAP_LEN, &cswlen);
   1020
   1021         /* Some broken devices add unnecessary zero-length packets to the
   1022          * end of their data transfers.  Such packets show up as 0-length
   1023          * CSWs.  If we encounter such a thing, try to read the CSW again.
   1024          */
   1025         if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
   1026                 US_DEBUGP("Received 0-length CSW; retrying.../n");
   1027                 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
   1028                                 bcs, US_BULK_CS_WRAP_LEN, &cswlen);
   1029         }
   1030
   1031         /* did the attempt to read the CSW fail? */
   1032         if (result == USB_STOR_XFER_STALLED) {
   1033
   1034                 /* get the status again */
   1035                 US_DEBUGP("Attempting to get CSW (2nd try).../n");
   1036                 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
   1037                                 bcs, US_BULK_CS_WRAP_LEN, NULL);
   1038         }
   1039
   1040         /* if we still have a failure at this point, we're in trouble */
   1041         US_DEBUGP("Bulk status result = %d/n", result);
   1042         if (result != USB_STOR_XFER_GOOD)
   1043                 return USB_STOR_TRANSPORT_ERROR;
   1044
   1045         /* check bulk status */
   1046         residue = le32_to_cpu(bcs->Residue);
   1047         US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x/n",
   1048                         le32_to_cpu(bcs->Signature), bcs->Tag,
   1049                         residue, bcs->Status);
   1050         if ((bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) &&
   1051                     bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) ||
   1052                         bcs->Tag != srb->serial_number ||
   1053                         bcs->Status > US_BULK_STAT_PHASE) {
   1054                 US_DEBUGP("Bulk logical error/n");
   1055                 return USB_STOR_TRANSPORT_ERROR;
   1056         }
   1057
   1058         /* try to compute the actual residue, based on how much data
   1059          * was really transferred and what the device tells us */
   1060         if (residue) {
   1061                 if (!(us->flags & US_FL_IGNORE_RESIDUE) ||
   1062                                 srb->sc_data_direction == DMA_TO_DEVICE) {
   1063                         residue = min(residue, transfer_length);
   1064                         srb->resid = max(srb->resid, (int) residue);
   1065                 }
   1066         }
   1067
   1068         /* based on the status code, we report good or bad */
   1069         switch (bcs->Status) {
   1070                 case US_BULK_STAT_OK:
   1071                         /* device babbled -- return fake sense data */
   1072                         if (fake_sense) {
   1073                                 memcpy(srb->sense_buffer,
   1074                                        usb_stor_sense_invalidCDB,
   1075                                        sizeof(usb_stor_sense_invalidCDB));
   1076                                 return USB_STOR_TRANSPORT_NO_SENSE;
   1077                         }
   1078
   1079                         /* command good -- note that data could be short */
   1080                         return USB_STOR_TRANSPORT_GOOD;
   1081
   1082                 case US_BULK_STAT_FAIL:
   1083                         /* command failed */
   1084                         return USB_STOR_TRANSPORT_FAILED;
   1085
   1086                 case US_BULK_STAT_PHASE:
   1087                         /* phase error -- note that a transport reset will be
   1088                          * invoked by the invoke_transport() function
   1089                          */
   1090                         return USB_STOR_TRANSPORT_ERROR;
   1091         }
   1092
   1093         /* we should never get here, but if we do, we're in trouble */
   1094         return USB_STOR_TRANSPORT_ERROR;
   1095 }

看傻了吧,这个函数也不是好惹的.但正是这个函数掀开了我们bulk传输的新篇章.

  

抱歉!评论已关闭.