Scsi - Index of
Scsi - Index of Scsi - Index of
弃,因为我们只关心我们提供的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 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
弃,因为我们只关心我们提供的buffer 是否装满了,是否达到了我们要求的length个字节,如果达到了,那么<br />
剩下的不管也罢,不过写代码的同志们在这个问题上考虑得比我们要周到,他们对这个细节也是体贴入微的.<br />
或者说他们对这种傻X 的设备也是很关心的.对于这种情况,写代码的同志们考虑,还是应该向上层汇报一<br />
下,<br />
说明这个命令对这个设备来说,执行起来总有些问题.因为这种情况完全可能就是,比如说,一个命令可以带<br />
有一些参数,而可能某个设备并不支持其中的某个参数,而你执行命令的时候去设了这个参数,那么设备的返<br />
回值可能就不正常,所谓的比预期的值要多就是一种不正常的表现,所以呢,对于这种情况,我们干脆就告诉<br />
上层这个命令有问题,在Linux 中,我们就可以通过sense data 来向上层汇报.而之所以这里称作fake<br />
sense,说的是这个sense data 里面的东西是我们自己设置好的,因为我们已经很清楚我们应该在设备里<br />
放置什么,不需要向设备发送一个REQUEST SENSE 的命令,而更确切的说,我们这个命令的返回结果是<br />
US_BULK_STAT_OK,也就是说,从设备那方返回的状态来看,设备认为命令没有问题,但是你说设备的话<br />
你能相信吗?老实说,从孙志刚案件开始,我不相信警察!从刘涌案件开始,我不相信法律!从苏秀文案件开始,<br />
我不相信政府!从打工受户籍歧视开始,我不相信有公平!从CCTV 每天报喜不报忧开始,我不相信有真话!而<br />
从我进入复旦微电子系开始学习计算机硬件,我他妈的就没相信过硬件设备.不是这有毛病就是那有毛病,硬<br />
件bug 到处都是.算了,别跑题了,继续说,因为设备认为传输是成功的,所以你发送REQUEST SENSE 根本<br />
就没用,因为设备根本就不会为你准备sense data,因为sense data 本来就是为了提供错误信息的.因此<br />
我们需要自己设一个sense data,放进sense_buffer 里去.从而让scsi core 那一层知道有这么一回事,<br />
别被设备瞒天过海给忽悠了.<br />
讲到这里,usb_stor_Bulk_transport()这个函数就算结束了.返回值一共就是四种情<br />
况,USB_STOR_TRANSPORT_GOOD,USB_STOR_TRANSPORT_FAILED,USB_STOR_TRANSPO<br />
RT_ERROR,以及USB_STOR_TRANSPORT_NO_SENSE.然后上层会去分析这些返回值.让我们结束这<br />
个函数,回到调用她的函数中来,即usb_stor_invoke_transport().在回去之前,我们需要记住的就是,对<br />
于刚才说的这种情况,即fake_sense 为1 的情况,我们返回的就是<br />
USB_STOR_TRANSPORT_NO_SENSE.一会我们会看到usb_stor_invoke_transport()中是如何应<br />
付这种情况的.<br />
跟着感觉走(二)<br />
回到usb_stor_invoke_transport()中来,540行,还是老套路,又问是不是命令被放弃了,放弃了当然下<br />
面的就别执行了.goto Handle_Abort 去.<br />
546 行,如果有错误,注意正如前面所说,USB_STOR_TRANSPORT_ERROR 表示传输本身就是有问题<br />
的,比如管道堵塞.而USB_STOR_TRANSPORT_FAILED 则只是说明命令传输是没有问题的,就比如你<br />
作<br />
为场外观众给非常六加一发短信了,然后李咏随机抽到你,给你打电话,电话通了,让你砸金蛋,砸出了金花你<br />
就能获得自己想要的奖品,但是问题是你没有砸中,这样你就失去了机会,这属于FAILED,但是另一种更惨<br />
的情况是,咏哥给你打电话还赶上你小子把手机关了,那你就只好认倒霉了,这就属于ERROR.对于这种疑似<br />
管道堵塞的问题,我们会调用自己写的一个函数us->transport_reset(us),us->transport_reset()其<br />
174<br />
实也是一个指针,我们也是很早以前和us->transport()一起赋的值,对于U 盘,我们赋的值是<br />
usb_stor_Bulk_reset().所谓reset,就相当于我们重起计算机,每次遇到些什么乱七八糟的问题,我们二<br />
话不说,重起机器通常就会发现一切都好了.关于设备reset 的冬冬,我们讲完命令的执行这一块之后再来专<br />
门讲.暂且不表.对于这种情况,当然我们会设置srb->result 为DID_ERROR.然后返回.<br />
554 行,看到了吧,这里就判断是不是USB_STOR_TRANSPORT_NO_SENSE 了.如果是的,那么返回<br />
给scsi 的结果是SAM_STAT_CHECK_CONDITION.返回这个值,scsi 核心层那边就知道会去读