Scsi - Index of

Scsi - Index of Scsi - Index of

07.06.2013 Views

154 for (i = 0; i < srb->cmd_len && i < 16; i++) 155 US_DEBUGPX(" %02x", srb->cmnd[i]); 156 US_DEBUGPX("\n"); 157 } 相信即使是天下无贼里边的傻根也能看懂这个函数,很简单,就是把要执行的scsi 命令打印出来.列出这 个函数没别的意思,让不熟悉scsi 的同志们知道基本上会遇到些啥命令.显然,刚才说的那个INQUIRY 也 包 含在其中的. 不过别看这个函数很easy,你要是不熟悉scsi 协议的话,你还真的解释不了这个函数.比如你说 srb->cmnd[]这个数组到底是什么内容?有什么格式?为啥函数一开始只判断cmnd[0]?实不相瞒,这里边 还真有学问.首先,在scsi 的规范里边定义了一些命令,每个命令都有一定的格式,命令的字节数也有好几 种, 有的命令是六个字节的,有的命令是10 个字节的,有的命令是12 个字节的.你看,你看,下面就是摘自scsi 规范里边的几张图,scsi 命令就该是这个样子. 这是6 字节的, 143 这是10 个字节的, 这是12 个字节的. 之所以有这好几种命令描述块,没什么特别的,也许只是想体现生物的多样性而已,又或许,印证了张爱 玲的那句话,也许每一个男子全都有过这样的两个女人,至少两个.娶了红玫瑰,久而久之,红的变成了墙上的 一抹蚊子血,白的还是”窗前明月光”;娶了白玫瑰,白的便是衣服上的一粒饭粘子,红的却是心口上的一颗朱 砂痣. 江湖中人们把这样几个字节的命令称之为CDB, command descriptor block, 命令描述符块.而我 们为CDB 准备了一个字符数组,结构体struct scsi_cmnd 中的unsigned char cmnd[16],你说最大就 12 个字节,干嘛不申请一个12 个字节的数组?给你一个建议:我记得复旦并没有一门课程叫做可持续性发 144 展,但是我记得我上海交大的同学有修过这样一门课程,有机会的话,去交大听一下吧. Ok,既然这个CDB 有16 个字节,那么为什么我们每次都判断cmnd[0]就够了?仔细看这三幅图,注意 到那个Operation code 了吗?没错,三幅图中的第一个字节都被称为Operation code,换言之,不管你是 什么样子的命令, 你都必须在第一个字节里签上自己的名字, 向世人说明你是谁. 于是在 include/scsi/scsi.h 中,定义了好多好多宏,比如#define INQUIRY 0x12,又比如#define READ_6 0x08,再比如#define FORMAT_UNIT 0x04,够了,实际上操作码就相当于scsi 命令的序列号,scsi 命令 总共也就那么多,8 位的操作码已经足够表示了,因此,我们只要用一个字节就可以判断出这是哪个命令了. 因为你的第一个字节就相当于你的眼睛,不管你埋藏的多深,你会发现最终总是你的眼睛背叛了你的心,这一 点郑中基大概感受颇深吧. 好了,命令说完了,开始进入真正处理命令的部分了. 迷雾重重的 bulk 传输(一) 2006 年的最后一个星期,来到了北京,开始了北漂的生活.和上海不同的是,在这里待了三个月之后,发现 竟然没有下过一次雨,难怪日本小孩说:”你们北京小孩真幸福,城外就是大沙漠,出了城就可以骑骆驼看日落 了.”不过,今天下雨了,下了大雨,好大好大,一阵阵的闪电,回家的时候下半身都湿了…(天哪,怎么写着写着 又往那个方向走去了…算了,我承认我只是一个用下半身思考的男青年.) 很累,但是听着北京不眠夜,又不想入睡,听着刘杨的声音,心里感到特别温暖,这些年里,从长沙,到上海,再

到北京,每每只有在夜深人静的时候,听着广播,才能忘却一些绝望.于是继续写吧,既然人生的幕布已经拉 开, 就一定要积极的演出;既然脚步已经跨出,风雨坎坷也不能退步;既然我已把希望播在这里,就一定要坚持到 胜利的谢幕. 375 行,us->proto_handler()其实是一个函数指针,知道它指向什么吗?不要说你不知道,早年我们在 storage_probe()中,确切的说,在get_protocol()就赋了值,当时只知道是get protocol,却不知道究竟干 什么用,现在该用上了,别以为写代码的都是傻子,一个指针要是没什么用人家才不会为它赋值呢.当初我们 就讲了,对于U 盘,proto_handler 被赋值为usb_stor_transparent_scsi_command,所以我们来看后 者吧. 后者定义于drivers/usb/storage/protocol.c: 172 void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, 173 struct us_data *us) 174 { 175 /* send the command to the transport layer */ 176 usb_stor_invoke_transport(srb, us); 177 178 if (srb->result == SAM_STAT_GOOD) { 179 /* Fix the READ CAPACITY result if necessary */ 180 if (us->flags & US_FL_FIX_CAPACITY) 181 fix_read_capacity(srb); 182 } 183 } 145 首先注意到的是usb_stor_invoke_transport()函数这个函数可不简单.咱们先做好思想准备, 接下 来就去见识一下她的庐山真面目. 她来自drivers/usb/storage/transport.c: 519 /*********************************************************************** 520 * Transport routines 521 **************************************************************** *******/ 522 523 /* Invoke the transport and basic error-handling/recovery methods 524 * 525 * This is used by the protocol layers to actually send the message to 526 * the device and receive the response. 527 */ 528 void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) 529 { 530 int need_auto_sense; 531 int result; 532 533 /* send the command to the transport layer */ 534 srb->resid = 0; 535 result = us->transport(srb, us); 536

154 for (i = 0; i < srb->cmd_len && i < 16; i++)<br />

155 US_DEBUGPX(" %02x", srb->cmnd[i]);<br />

156 US_DEBUGPX("\n");<br />

157 }<br />

相信即使是天下无贼里边的傻根也能看懂这个函数,很简单,就是把要执行的scsi 命令打印出来.列出这<br />

个函数没别的意思,让不熟悉scsi 的同志们知道基本上会遇到些啥命令.显然,刚才说的那个INQUIRY 也<br />

包<br />

含在其中的.<br />

不过别看这个函数很easy,你要是不熟悉scsi 协议的话,你还真的解释不了这个函数.比如你说<br />

srb->cmnd[]这个数组到底是什么内容?有什么格式?为啥函数一开始只判断cmnd[0]?实不相瞒,这里边<br />

还真有学问.首先,在scsi 的规范里边定义了一些命令,每个命令都有一定的格式,命令的字节数也有好几<br />

种,<br />

有的命令是六个字节的,有的命令是10 个字节的,有的命令是12 个字节的.你看,你看,下面就是摘自scsi<br />

规范里边的几张图,scsi 命令就该是这个样子.<br />

这是6 字节的,<br />

143<br />

这是10 个字节的,<br />

这是12 个字节的.<br />

之所以有这好几种命令描述块,没什么特别的,也许只是想体现生物的多样性而已,又或许,印证了张爱<br />

玲的那句话,也许每一个男子全都有过这样的两个女人,至少两个.娶了红玫瑰,久而久之,红的变成了墙上的<br />

一抹蚊子血,白的还是”窗前明月光”;娶了白玫瑰,白的便是衣服上的一粒饭粘子,红的却是心口上的一颗朱<br />

砂痣.<br />

江湖中人们把这样几个字节的命令称之为CDB, command descriptor block, 命令描述符块.而我<br />

们为CDB 准备了一个字符数组,结构体struct scsi_cmnd 中的unsigned char cmnd[16],你说最大就<br />

12 个字节,干嘛不申请一个12 个字节的数组?给你一个建议:我记得复旦并没有一门课程叫做可持续性发<br />

144<br />

展,但是我记得我上海交大的同学有修过这样一门课程,有机会的话,去交大听一下吧.<br />

Ok,既然这个CDB 有16 个字节,那么为什么我们每次都判断cmnd[0]就够了?仔细看这三幅图,注意<br />

到那个Operation code 了吗?没错,三幅图中的第一个字节都被称为Operation code,换言之,不管你是<br />

什么样子的命令, 你都必须在第一个字节里签上自己的名字, 向世人说明你是谁. 于是在<br />

include/scsi/scsi.h 中,定义了好多好多宏,比如#define INQUIRY 0x12,又比如#define READ_6<br />

0x08,再比如#define FORMAT_UNIT 0x04,够了,实际上操作码就相当于scsi 命令的序列号,scsi 命令<br />

总共也就那么多,8 位的操作码已经足够表示了,因此,我们只要用一个字节就可以判断出这是哪个命令了.<br />

因为你的第一个字节就相当于你的眼睛,不管你埋藏的多深,你会发现最终总是你的眼睛背叛了你的心,这一<br />

点郑中基大概感受颇深吧.<br />

好了,命令说完了,开始进入真正处理命令的部分了.<br />

迷雾重重的 bulk 传输(一)<br />

2006 年的最后一个星期,来到了北京,开始了北漂的生活.和上海不同的是,在这里待了三个月之后,发现<br />

竟然没有下过一次雨,难怪日本小孩说:”你们北京小孩真幸福,城外就是大沙漠,出了城就可以骑骆驼看日落<br />

了.”不过,今天下雨了,下了大雨,好大好大,一阵阵的闪电,回家的时候下半身都湿了…(天哪,怎么写着写着<br />

又往那个方向走去了…算了,我承认我只是一个用下半身思考的男青年.)<br />

很累,但是听着北京不眠夜,又不想入睡,听着刘杨的声音,心里感到特别温暖,这些年里,从长沙,到上海,再

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

Saved successfully!

Ooh no, something went wrong!