07.06.2013 Views

Scsi - Index of

Scsi - Index of

Scsi - Index of

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

us->cr 别忘了我们当初为us->cr 申请内存的时候用的是下面这句:<br />

449 /* Allocate the device-related DMA-mapped buffers */<br />

450 us->cr = usb_buffer_alloc(us->pusb_dev, size<strong>of</strong>(*us->cr),<br />

451 GFP_KERNEL, &us->cr_dma);<br />

别忘了这里的us->cr_dma,这个函数虽然返回值是赋给了us->cr,但与此同时,在us->cr_dma 中记<br />

录的可以该地址所映射的dma 地址,那么刚才这里设置了URB_NO_SETUP_DMA_MAP 这么一个flag,<br />

就说明,如果是DMA 方式的传输,那么usb core 就应该使用us->cr_dma 里边的冬冬去进行dma 传输,<br />

而不要用us->cr 里边的冬冬了.换句话说,也就是urb 里边的setup_dma 而不是setup_buffer.<br />

同样transfer_buffer 和transfer_dma 的关系也是如此,我们当初同样用类似的方法申请了<br />

us->iobuf 的内存:<br />

457 us->iobuf = usb_buffer_alloc(us->pusb_dev, US_IOBUF_SIZE,<br />

458 GFP_KERNEL, &us->iobuf_dma);<br />

82<br />

这里就有us->iobuf 和us->iobuf_dma 这两个咚咚,但是我们注意到,163 和164 行,我们在设置<br />

URB_NO_TRANSFER_DMA_MAP 这个flag 的时候,先做了一次判断,判断<br />

us->current_urb->transfer_buffer 是否等于us->iobuf,这是什么意思呢?我们在什么地方对<br />

transfer_buffer 赋过值? 答案是usb_fill_control_urb 中,我们把us->iobuf 传递了过去,它被赋给了<br />

urb->transfer_buffer,这样做就意味着我们这里将使用DMA传输,所以这里就设置了这个flag,倘若我们<br />

不希望进行DMA 传输,那很简单,我们在调用usb_stor_msg_common 之前,不让<br />

urb->transfer_buffer 指向us->iobuf 就是了,反正这都是我们自己设置的,别人管不着.需要知道的<br />

是,transfer_buffer 是给各种传输方式中真正用来数据传输的,而setup_packet 仅仅是在控制传输中发<br />

送setup 的包的,控制传输除了setup 阶段之外,也会有数据传输阶段,这一阶段要传输数据还是得靠<br />

transfer_buffer,而如果使用dma 方式,那么就是使用transfer_dma.<br />

Ok,下一句,169 行,终于到了提交urb 这一步了,usb_submit_urb 得到调用,作为usb 设备驱动程序,<br />

我们不需要知道这个函数究竟在做什么,只要知道怎么使用就可以了,无需关注代码背后的哲学.它的定义在<br />

drivers/usb/core/urb.c 中,我们得知道它有两个参数,一个就是要提交的urb,一个是内存申请的flag,这<br />

里我们使用的是GFP_NOIO,意思就是不能在申请内存的时候进行IO 操作,道理很简单,咱们这个是存储设<br />

备,调用usb_submit_urb很可能是因为我们要读些磁盘或者U盘,那这种情况如果申请内存的函数又再一<br />

次去读写磁盘,那就有问题了,什么问题?嵌套呗.什么叫申请内存的函数也会读写磁盘?玩过Linux的人不会<br />

不知道swap 吧,交换分区,干嘛要交换啊,可不就是因为内存不够么.使用磁盘作为交换分区不就方便了,所<br />

以申请内存的时候可能要的内存在磁盘上,那就得交换回来.这不就读写磁盘了么?所以我们为了读写硬盘<br />

而提交urb,那么这个过程中就不能再次有IO 操作了,这样做的目的是为了杜绝嵌套死循环.<br />

于是我们调用了169 行就可以往下走了,剩下的事情usb core 和usb host 会去处理,至于这个函数本<br />

身的返回值,如果一切正常,status 将是0.所以这里判断如果status 不为0 那么就算出错了.<br />

177 行,一个urb 被提交了之后,通常我们会把us->flags 中置上一个flag, US_FLIDX_URB_ACTIVE,<br />

让我们记录下这个urb 的状态是活着的.<br />

180 行,这里我们再次判断us->flags,看是不是谁置了aborting 或者disconnected 的flag.稍后我们<br />

会看到谁会置这些flag,显然如果已经置了这些flag 的话,咱们就没必要往下了,这个urb 可以cancel 了.<br />

190 行,一个新的故事将被引出,这就是伟大的时间机制.<br />

能冲刷一切的,除_________了眼泪,就是时间.所以Linux 中引入了时间机制.<br />

第一次亲密接触(四)<br />

金城武说:不知道从什么时候开始,在什么东西上面都有个日期,秋刀鱼会过期,肉罐头会过期,连保鲜纸

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

Saved successfully!

Ooh no, something went wrong!