Scsi - Index of

Scsi - Index of Scsi - Index of

07.06.2013 Views

弃,因为我们只关心我们提供的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 的目的无非就是出错了以后想知道出错的原因,而这种情况下原因已经清楚了嘛不是.至于你

弃,因为我们只关心我们提供的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 核心层那边就知道会去读

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!