读Linux那些事儿之我是U盘笔记(六)

27INQUIRY 命令是最最基本的一个 SCSI 命令,,比如主机第一次探测设备的时候就要用INQUIRY命令来了解这是一个什么设备,比如scsi总线上有一个插槽插了一个设备,那么scsi主机就问它,你是scsi磁盘呢,还是scsi磁带,又或是scsiCD ROM?作为设备,它内部一

定有一段固件程序,即所谓的 firmware.它就在接收到主机的 INQUIRY 命令之后作出回答.具体应该怎么回答?当然是依据 scsi 协议里规定的格式了

.具体来说, 设备在受到INQUIRY命令查询时,她的相应遵从scsi协议里面规定的标准格式,标准格式规定了,响应数据必须至少包含36个字节

scsi 协议里规定了,标准的 INQUIRY data data[0],总共 8 bit,其中 bit7~bi5 被称为peripheral qualifier(三位),bit4~bit0 被称为perpheral device type(五位)20h 就表示 peripheral qualifier 这个外围设备限定符为 001b, peripheral device type这个外围设备类型则为 00h,查阅 scsi 协议可知,后者代表的是设备类型为磁盘,或者说直接访问设备,前者代表的是目标设备的当前 lun 支持这种类型,然而,实际的物理设备并没有连接在当前 lun 上;从 data[8]一直到 data[35] 28 个字节都是保存的 vendor product 的信息,data[8]开始的8个字节可以保存 vendor 相关的信息,从16开始存放productName,不能超过 16 个字符;

 

28bcdDevice:表示的是制造商指定的产品的版本号,道上的规矩是用版本号,制造商 id 和产品 id 来标志一个设备;

bcdDevice 一共 16 ,是以 bcd的方式保存的信息,也就是说,4位代表一个十进制的数,比如0011 0110 1001 0111就代表的3697. 而在scsi 标准的INQUIRY data,data[32]data[35]被定义为保存这四个数,并且要求以ASCII码的方式保存,ASCII 码中 48 对应咱们日常的 0,49 对应 1,50 对应 2,也就是说得在现有数字的基础上加上48,或者说加上0x30.

 

30scatter/gather

   解释:她是一种用于高性能IO的标准技术.她通常意味着一种DMA传输方式,对于一个给定的数据块,她老人家可能在内存中存在于一些离散的缓冲区,换言之,就是说一些不连续的内存缓冲区一起保存一个数据块

   事实上,要玩scatter/gather,就需要一个scatterlist数组,有人管她叫散列表数组.

   use_sg 0就表示没有scatter gather list,或者说scatterlist,对于这种情况,数据将直接

传送给request_buffer或者直接从request_buffer中取得数据.而如果use_sg大于 0,那么表示

scatter gather list这么一个数组就在request_buffer,而数组元素个数正是use_sg.也就是

,srb->request_buffer里边的冬冬有两种可能,一种是包含了数据本身,另一种是包含了scatter

gather list

 对于使用scatter/gather传输的情况,request_buffer里边实际上是一个数组,每一个元素都是一个struct scatterlist的指针,而每一个scatterlist指针的 page里边包含了一些page(而不是一个page),offset里边包含的是每一个DMA buffer的总的偏移量,她由两部分组成,高位部分标志着page,低位部分标志着具体某个page 中的偏移量,高位低位由PAGE_SHIFT宏来划分,不同的硬件平台PAGE_SHIFT值不一样,因为不同的硬件平台page的大小也不一样,即这里的PAGE_SIZE 不一样,目前比较前卫的硬件平台其page size4k或者 8k,

PAGE_SHIFT 也就是12或者13,换言之,sg->offset去掉低12位或者低13位就是 page,而低 12位或者低13位恰恰是在该page内的偏移量;

 

31kmap  需要把物理地址映射到内核地址空间中来;

 

你可能感兴趣的:(linux,driver,职场,usb,休闲)