07.06.2013 Views

Scsi - Index of

Scsi - Index of

Scsi - Index of

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

storage 会有两个bulk 端点,用于bulk 传输,即所谓的批量传输.我们日常的读写U 盘里的文件,就是属<br />

于<br />

批量传输,所以毫无疑问,对于mass storage 设备来说,bulk 传输是它的主要工作方式,道理很简单,我们<br />

使<br />

用U 盘就是用来读写文件的,谁没事天天去读它的这种描述符那种描述符呢,吃错药了?和这些描述符打交<br />

道无非就是为了帮助我们最终实现读写文件的工作,这才是每一个usb 存储设备真正的使命.<br />

于是我们来这段循环到底在干嘛, altsetting->endpoint[i].desc,对照struct usb_host_endpoint<br />

这个结构体的定义,可知,desc 正是一个struct usb_endpoint_descriptor 的变量.咱们刚刚定义了四个<br />

这种结构体的指针,ep,ep_in,ep_out,ep_int,很简单,就是用来记录端点描述符的,ep_in 用于<br />

bulk-in,ep_out 用于bulk-out,ep_int 用于记录中断端点(如果有的话).而ep,只是一个临时指针.<br />

我们看struct usb_endpoint_descriptor,它的成员中, bmAttributes 表示属性,总共8位,其中bit1<br />

和bit0 共同称为Transfer Type,即传输类型,即00 表示控制,01 表示等时,10 表示批量,11 表示中断.<br />

而<br />

719 行我们看到, USB_ENDPOINT_XFERTYPE_MASK 这个宏定义于include/linux/usb_ch9.h 中:<br />

286 #define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */<br />

287 #define USB_ENDPOINT_XFER_CONTROL 0<br />

288 #define USB_ENDPOINT_XFER_ISOC 1<br />

289 #define USB_ENDPOINT_XFER_BULK 2<br />

290 #define USB_ENDPOINT_XFER_INT 3<br />

懂一点C 语言的人就不难理解,719 行就是判断这个端点描述符描述的是不是一个Bulk 端点,如果是,<br />

继续比较,我们先看bEndpointAddress,这个struct usb_endpoint_descriptor 中的另一个成员,也是8<br />

个bit,或者说1 个byte,其中bit7 表示的是这个端点的方向,0 表示OUT,1 表示IN,OUT 与IN 是对主机<br />

而言.OUT 就是从主机到设备,IN 就是从设备到主机.而宏USB_DIR_IN 仍然来自<br />

include/linux/usb_ch9.h<br />

25 /*<br />

26 * USB directions<br />

57<br />

27 *<br />

28 * This bit flag is used in endpoint descriptors' bEndpointAddress field.<br />

29 * It's also one <strong>of</strong> three fields in control requests bRequestType.<br />

30 */<br />

31 #define USB_DIR_OUT 0 /* to device */<br />

32 #define USB_DIR_IN 0x80 /* to host */<br />

所以这里意思很明显,就是为了让ep_in 和ep_out 指向该指的endpoint descriptor.<br />

729就不用再说了,如果这还看不懂的话,可以考虑去复旦的绝情谷找到那棵老树上吊自杀了,可惜如今<br />

学校里不断搞建设,绝情谷可能已经不复存在了.729 这一个else if 的作用就是如果这个端点是中断端点,<br />

那么就让ep_int 指向它.我们说了,每一类usb 其上面有多少端点有何种端点都是不确定的,都得遵守该类<br />

设备的规范,而usb mass storage 的规范说了,一个usb mass storage 设备至少应该有两个bulk 端点,<br />

除此之外,那个控制端点显然是必须的,毋庸置疑,另外,可能会有一个中断端点,这种设备支持CBI 协议,即<br />

Control/Bulk/Interrupt 协议.我们也说过了,U 盘遵守的是Bulk-only 协议,它不需要有中断端点.<br />

735 到738 这段代码,没啥好说的,就是判断是否ep_in 或者ep_out 不存在,或者是遵守CBI 协议但<br />

是没有中断端点,这些都是不合理的,当然就会出错啰!<br />

剩下一小段代码,我们下节再看.需要说的是,这个函数结束之后我们将开始最精彩的部分,它就是伟大<br />

的usb_stor_acquire_resources().黑暗即将过去,黎明已经带我们上路.让我们共同期待吧.同时,我们小

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

Saved successfully!

Ooh no, something went wrong!