发布时间:2014-09-05 16:39:50作者:知识屋
其实故事已经讲了很久,但如果你觉得到这里你已经把故事都看明白了,那么你错了。不仅仅是错了。不信,我们就继续看,先看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一键安装web环境全攻略 在linux系统中怎么一键安装web环境方法
Linux网络基本网络配置方法介绍 如何配置Linux系统的网络方法
Linux下DNS服务器搭建详解 Linux下搭建DNS服务器和配置文件
对Linux进行详细的性能监控的方法 Linux 系统性能监控命令详解
linux系统root密码忘了怎么办 linux忘记root密码后找回密码的方法
Linux基本命令有哪些 Linux系统常用操作命令有哪些
Linux必学的网络操作命令 linux网络操作相关命令汇总
linux系统从入侵到提权的详细过程 linux入侵提权服务器方法技巧
linux系统怎么用命令切换用户登录 Linux切换用户的命令是什么
在linux中添加普通新用户登录 如何在Linux中添加一个新的用户
2012-07-10
CentOS 6.3安装(详细图解教程)
Linux怎么查看网卡驱动?Linux下查看网卡的驱动程序
centos修改主机名命令
Ubuntu或UbuntuKyKin14.04Unity桌面风格与Gnome桌面风格的切换
FEDORA 17中设置TIGERVNC远程访问
StartOS 5.0相关介绍,新型的Linux系统!
解决vSphere Client登录linux版vCenter失败
LINUX最新提权 Exploits Linux Kernel <= 2.6.37
nginx在网站中的7层转发功能