弃,因为我们只关心我们提供的buffer 是否装满了,是否达到了我们要求的length个字节,如果达到了,那么 剩下的不管也罢,不过写代码的同志们在这个问题上考虑得比我们要周到,他们对这个细节也是体贴入微的. 或者说他们对这种傻X 的设备也是很关心的.对于这种情况,写代码的同志们考虑,还是应该向上层汇报一 下, 说明这个命令对这个设备来说,执行起来总有些问题.因为这种情况完全可能就是,比如说,一个命令可以带 有一些参数,而可能某个设备并不支持其中的某个参数,而你执行命令的时候去设了这个参数,那么设备的返 回值可能就不正常,所谓的比预期的值要多就是一种不正常的表现,所以呢,对于这种情况,我们干脆就告诉 上层这个命令有问题,在Linux 中,我们就可以通过sense data 来向上层汇报.而之所以这里称作fake sense,说的是这个sense data 里面的东西是我们自己设置好的,因为我们已经很清楚我们应该在设备里 放置什么,不需要向设备发送一个REQUEST SENSE 的命令,而更确切的说,我们这个命令的返回结果是 US_BULK_STAT_OK,也就是说,从设备那方返回的状态来看,设备认为命令没有问题,但是你说设备的话 你能相信吗?老实说,从孙志刚案件开始,我不相信警察!从刘涌案件开始,我不相信法律!从苏秀文案件开始, 我不相信政府!从打工受户籍歧视开始,我不相信有公平!从CCTV 每天报喜不报忧开始,我不相信有真话!而 从我进入复旦微电子系开始学习计算机硬件,我他妈的就没相信过硬件设备.不是这有毛病就是那有毛病,硬 件bug 到处都是.算了,别跑题了,继续说,因为设备认为传输是成功的,所以你发送REQUEST SENSE 根本 就没用,因为设备根本就不会为你准备sense data,因为sense data 本来就是为了提供错误信息的.因此 我们需要自己设一个sense data,放进sense_buffer 里去.从而让scsi core 那一层知道有这么一回事, 别被设备瞒天过海给忽悠了. 讲到这里,usb_stor_Bulk_transport()这个函数就算结束了.返回值一共就是四种情 况,USB_STOR_TRANSPORT_GOOD,USB_STOR_TRANSPORT_FAILED,USB_STOR_TRANSPO RT_ERROR,以及USB_STOR_TRANSPORT_NO_SENSE.然后上层会去分析这些返回值.让我们结束这 个函数,回到调用她的函数中来,即usb_stor_invoke_transport().在回去之前,我们需要记住的就是,对 于刚才说的这种情况,即fake_sense 为1 的情况,我们返回的就是 USB_STOR_TRANSPORT_NO_SENSE.一会我们会看到usb_stor_invoke_transport()中是如何应 付这种情况的. 跟着感觉走(二) 回到usb_stor_invoke_transport()中来,540行,还是老套路,又问是不是命令被放弃了,放弃了当然下 面的就别执行了.goto Handle_Abort 去. 546 行,如果有错误,注意正如前面所说,USB_STOR_TRANSPORT_ERROR 表示传输本身就是有问题 的,比如管道堵塞.而USB_STOR_TRANSPORT_FAILED 则只是说明命令传输是没有问题的,就比如你 作 为场外观众给非常六加一发短信了,然后李咏随机抽到你,给你打电话,电话通了,让你砸金蛋,砸出了金花你 就能获得自己想要的奖品,但是问题是你没有砸中,这样你就失去了机会,这属于FAILED,但是另一种更惨 的情况是,咏哥给你打电话还赶上你小子把手机关了,那你就只好认倒霉了,这就属于ERROR.对于这种疑似 管道堵塞的问题,我们会调用自己写的一个函数us->transport_reset(us),us->transport_reset()其 174 实也是一个指针,我们也是很早以前和us->transport()一起赋的值,对于U 盘,我们赋的值是 usb_stor_Bulk_reset().所谓reset,就相当于我们重起计算机,每次遇到些什么乱七八糟的问题,我们二 话不说,重起机器通常就会发现一切都好了.关于设备reset 的冬冬,我们讲完命令的执行这一块之后再来专 门讲.暂且不表.对于这种情况,当然我们会设置srb->result 为DID_ERROR.然后返回. 554 行,看到了吧,这里就判断是不是USB_STOR_TRANSPORT_NO_SENSE 了.如果是的,那么返回 给scsi 的结果是SAM_STAT_CHECK_CONDITION.返回这个值,scsi 核心层那边就知道会去读
srb->sense_buffer 里边的东西.SAM_STAT_CHECK_CONDITION 是scsi 那边定义的宏,scsi 协议 规 定,scsi 总线上有若干个阶段,比如命令阶段,比如数据阶段,比如状态阶段,这三个阶段其实咱们Bulk-Only spec 里边也有.不过scsi 协议里还规定了更多的一些阶段,在scsi 协议里边称一个阶段为一个phase.除 了 这三个phase 以外,还可以有bus free phase,有selection phase,有message phase 等等.而状态阶 段就是要求目标设备返回给主机一个状态码(status code).关于这些状态码,在scsi 的规范里边定义得很 清楚.在include/scsi/scsi.h 中也有相关的宏定义. 117 /* 118 * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft 119 * T10/1561-D Revision 4 Draft dated 7th November 2002. 120 */ 121 #define SAM_STAT_GOOD 0x00 122 #define SAM_STAT_CHECK_CONDITION 0x02 123 #define SAM_STAT_CONDITION_MET 0x04 124 #define SAM_STAT_BUSY 0x08 125 #define SAM_STAT_INTERMEDIATE 0x10 126 #define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14 127 #define SAM_STAT_RESERVATION_CONFLICT 0x18 128 #define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */ 129 #define SAM_STAT_TASK_SET_FULL 0x28 130 #define SAM_STAT_ACA_ACTIVE 0x30 131 #define SAM_STAT_TASK_ABORTED 0x40 其中,SAM_STAT_CHECK_CONDITION就是对应scsi 协议中的CHECK CONDITION,这一状态表明 有sense data 被_________放置在相应的buffer 里,于是scsi core 那边就会去读sense buffer.而我们 这里遇到这 种情况,当然就可以返回了. 559 行,要是没别的啥意外的话,到了这里我们就可以设置srb->result 为SAM_STAT_GOOD 了,说明 一切都是ok 的.当然,对于之后会出现的REQUEST SENSE 的执行失败,我们会再次修改srb->result 的. 下面566 行,出现了一个叫做need_auto_sense 的变量,这是我们定义的临时变量,这里赋初值为 0.574 到588 行,两个if 语句,为need_auot_sense 赋了值,赋值为1.我们首先很容易理解第二个if,正 如 我们前面介绍的那样,REQUEST SENSE 这个艰巨的任务被下放给了我们底层驱动,那么我们就勇敢的去 承担它,在USB_STOR_TRANSPORT_FAILED 的情况下,我们就去发送一个REQUEST SENSE 命令.设 了这个flag 稍后我们就会看到我们会因此而执行REQUEST SENSE.那么第一个if 呢?相信那些注释已经 说得很清楚了吧,如果你对自己的智商还有一丁点儿信心的话,应该就不需要我解释了.我只说一句,对于那 些遵守CB 或者DPCM 协议的设备它们没有自己没有办法决定状态,所以scsi 核心层当然就不知道去读它 175 们的sense buffer 了,但是不读sense buffer 我们连这个命令执行成功与否都不知道,那怎么行?而设备 对于大多数读操作的错误也不需要使用sense buffer,因为它们对于读操作的错误通常会停止掉bulk-in pipe,这已经是一个很明显的信号了,不需要再检测sense buffer,因为检测sense buffer 或者说检测 sense data 的目的无非就是出错了以后想知道出错的原因,而这种情况下原因已经清楚了嘛不是.至于你
- Page 1 and 2:
摘要 ............................
- Page 3 and 4:
迷雾重重的Bulk 传输(二)....
- Page 5 and 6:
引子 也许是在复旦养成了
- Page 7 and 8:
usb.h datafab.h dpcm.h initializers
- Page 9 and 10:
的Linux 内核划分为许许多
- Page 11 and 12:
目录下执行make 了.Ok,make 之
- Page 13 and 14:
只 是一个usb 接口.这些口
- Page 15 and 16:
中也定义了这么一些数据
- Page 17 and 18:
511 * @driver: the driver model cor
- Page 19 and 20:
233 .owner = THIS_MODULE, 234 .name
- Page 21 and 22:
91 * construct these entries. Each
- Page 23 and 24:
324 struct usb_host_config *actconf
- Page 25 and 26:
22 88 * @class_dev: driver model's
- Page 27 and 28:
必须给各个地方取名,完了
- Page 29 and 30:
26 136 trans_cmnd transport; /* tra
- Page 31 and 32:
944 init_MUTEX_LOCKED(&(us->sema));
- Page 33 and 34:
147 #if !defined(CONFIG_BLK_DEV_UB)
- Page 35 and 36:
124 #define USB_DEVICE_ID_MATCH_DEV
- Page 37 and 38:
intf 来代替. us 之所以重要,
- Page 39 and 40:
睡眠,那就得用GPF_ATOMIC,这
- Page 41 and 42:
504 if (msg >= 0 && !(unusual_dev->
- Page 43 and 44:
179 } 180 181 static struct us_unus
- Page 45 and 46:
711 /* Submitted by Hartmut Wahl */
- Page 47 and 48:
3. useProtocol 为US_SC_DEVICE, use
- Page 49 and 50:
Bus 004 Device 001: ID 0000:0000 Bu
- Page 51 and 52:
993 result = get_pipes(us); 994 if
- Page 53 and 54:
631 us->transport_reset = usb_stor_
- Page 55 and 56:
659 us->max_lun = 0; 660 break; 661
- Page 57 and 58:
740 /* Calculate and store the pipe
- Page 59 and 60:
storage 会有两个bulk 端点,用
- Page 61 and 62:
比如说,复旦大学,有一个主
- Page 63 and 64:
1079 #define PIPE_ISOCHRONOUS 0 108
- Page 65 and 66:
782 us->unusual_dev->initFunction(u
- Page 67 and 68:
630 * each frame is in the fields o
- Page 69 and 70:
716 * Bulk URBs may 717 * use the U
- Page 71 and 72:
802 int number_of_packets; /* (in)
- Page 73 and 74:
先说互斥锁.它诞生于这样
- Page 75 and 76:
920 US_DEBUGP("GetMaxLUN command re
- Page 77 and 78:
148 /* set up data structures for t
- Page 79 and 80:
90 * @wValue: matches the USB wValu
- Page 81 and 82:
830 void *transfer_buffer, 831 int
- Page 83 and 84:
25 { 26 x->done = 0; 27 init_waitqu
- Page 85 and 86:
都会过期,我开始怀疑,在这
- Page 87 and 88:
是实际长度,要么就是不成
- Page 89 and 90:
87 258 行,usb_pipeendpoint,定义
- Page 91 and 92:
对爱你的人掘了一条无法
- Page 93 and 94:
Type: Direct-Access ANSI SCSI revis
- Page 95 and 96:
416 /* 417 * this defines our host
- Page 97 and 98:
69 * Ioctl interface 70 * 71 * Stat
- Page 99 and 100:
155 * "is this a new device" checks
- Page 101 and 102:
241 char *proc_name; 242 243 /* 244
- Page 103 and 104:
328 * True if the low-level driver
- Page 105 and 106:
可以看到这个函数的参数
- Page 107 and 108:
451 short unsigned int max_sectors;
- Page 109 and 110:
地 说明了为啥咱们要显式
- Page 111 and 112:
usb_stor_acquire_resources()函数
- Page 113 and 114:
341 } 342 343 /* reject if target !
- Page 115 and 116:
内核的核心位置,kernel/exit.c
- Page 117 and 118:
1023 dissociate_dev(us); 1024 retur
- Page 119 and 120:
917 行,再次判断设备有没有
- Page 121 and 122: 181 182 /* fail the command if we a
- Page 123 and 124: 83 struct timer_list eh_timeout; /*
- Page 125 and 126: 123 两个scsi_done,一个是struct
- Page 127 and 128: 56 jiffie count on our counter, the
- Page 129 and 130: 中 看到如下的定义: UNUSUAL_
- Page 131 and 132: 269 memcpy(data+16, us->unusual_dev
- Page 133 and 134: 一切准备好了之后,我们就
- Page 135 and 136: 238 (sg->offset + *offset) & (PAGE_
- Page 137 and 138: 所以对于那些不能相应INQUI
- Page 139 and 140: 239 行对unsigned int sglen 赋值
- Page 141 and 142: 请求,所以这里就判断abort
- Page 143 and 144: 112 case GPCMD_READ_HEADER: what =
- Page 145 and 146: 到北京,每每只有在夜深人
- Page 147 and 148: 580 /* 581 * If we have a failure,
- Page 149 and 150: 666 memcpy(srb->cmnd, old_cmnd, MAX
- Page 151 and 152: 950 struct bulk_cb_wrap *bcb = (str
- Page 153 and 154: 1034 /* get the status again */ 103
- Page 155 and 156: 426 /* store the actual length of t
- Page 157 and 158: 后她会给host 返回一个CSW.CB
- Page 159 and 160: 296 } 297 298 US_DEBUGP("-- transfe
- Page 161 and 162: 491 * scatter-gather or not, and ac
- Page 163 and 164: 迷雾重重的 Bulk 传输(五) us
- Page 165 and 166: 然后把她赋给了result.而us->
- Page 167 and 168: 而bcs->Status,标志命令执行
- Page 169 and 170: 就必须设置US_FL_IGNORE_RESIDUE
- Page 171: 485 }; 486 这是一个字符数组
- Page 175 and 176: 一个类似的函数,名叫usb_sto
- Page 177 and 178: 这种命令应该由mid level 来
- Page 179 and 180: Disk /dev/sda: 146.1 GB, 1461631057
- Page 181 and 182: through to the most significant bit
- Page 183 and 184: 1192 USB_TYPE_CLASS | USB_RECIP_INT
- Page 185 and 186: 315 行,scsi_report_device_reset(),
- Page 187 and 188: 285 US_DEBUGP("No reset during disc
- Page 189 and 190: 229 /* Wait for the aborted command
- Page 191 and 192: 两个函数中需要判断它,一
- Page 193 and 194: associate_dev()相对应.我们来
- Page 195 and 196: 束for 死循环,从而usb_stor_con
- Page 197 and 198: 317 for (i = 1; i < us->host->max_i