您的位置:首页 > 运维架构 > Linux

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

2007-07-31 00:35 399 查看
其实故事已经讲了很久了,但如果你觉得到这里你已经把故事都看明白了,那么你错了.不仅仅是错了,你这种想法无异于就是,手里拿着一把刀,就以为自己是刀郎,手里举着一个窝头,就以为自己是托塔李天王.不信,我们就继续看,先看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传输的新篇章.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: