- 论坛徽章:
- 0
|
于是,走过了千山万水,经历了千辛万苦,咱们再一次回到了久违的usb_stor_Bulk_max_lun() 函数.
这样一次真正的控制传输就这么开始就这么结束了.
接下来,我们继续看,控制传输的结果返回给了result, 我们说过,单纯的U 盘一般来说这个结果总是0,即
它必然只有一个lun. 这里判断的是result 大于0,道理很简单,result 是一个int 型的数据,而返回的给它的
实际上是iobuf[0] 这么一个char 类型的变量,所以是字符’0’,保存成int 型当然就大于0 了,所以这里打印
出来结果是0,但是result 实际上是大于0 的.而945 行我们同样注意到,如果result 是一些奇怪的值,正如
注释所说,有的设备它就不认GetMaxLUN 这个命令,就像在她的心里潜伏着一个深渊,扔下巨石也发不出
声音来,或者它干脆就返回一个0 长度的结果来,那么这种情况那么我们就只能把这种设备当作只有一个
LUN 了,所以也就返回0 得了.
不过933 到935 这三行需要说一下.这也是专门为一些变态的设备准备的.一般的设备用不着.只是
usb_stor_clear_halt 这个函数是我们自己定义的,并且今后我们也会用到,所以我们还是讲一下.不过,在
这个函数中,我们将再一次见到控制传输,但是毕竟不再是我们的第一次亲密接触了,所以,虽然我们依然还
是在usb_stor_Bulk_max_lun 中,但还是让我们下一节在讲吧.
最后需要解释一下的是,像init_timer(),add_timer(),del_timer_sync() 这几个函数都是Linux 内核
中的核心函数,包括结构体struct timer_list, 他们都来自include/linux/timer.h 和kernel/timer.c 中,
我们只需要知道调用就可以了,不用知道究竟怎么实现的,只需要知道这样设置了超时的话,我们注册的超时
处理函数就会被执行.而至于它究竟如何去调用的,如何计时如何去判断超时这些内核自会处理,不用我们担
心,我们瞎操心也没用.对于内核来说,时间是怎样划破她的皮肤,只有她自己最清楚.而对于写设备驱动的人
来说,这些核心代码就像是天空中的云朵,你看着它往某一个方向飘,却什么也做不了.正如令狐冲所说的那
样:”有些事情本身我们无法控制,只好控制自己.”
将控制传输进行到底
其实usb_stor_clear_halt 这个函数的作用很简单,就是spec 里边规定了,usb 设备中,有两类端点,必
须具有一个叫做Halt 的特征,啥是Halt?查金山词霸去,中断,停止,暂停,怎么解释呢,你把手机关了,就不能
给超级女生发短信投票了吧,你把电脑关了,就不能上黄色网站了吧,你把电视机关了,就不能看中国之队在
亚洲杯上的精彩表演了吧.对于usb 设备来说,其中端端点和Bulk 端点就有这么一个特征,叫做Halt,其实
就是寄存器里的某一位,设为1,就表示设置了Halt 的特征,那就是表示这个端点不工作了.要想让端点重新
工作,很简单,把这一位设置为0 就可以了.
关于Halt,用我们行话说,这叫做一个feature,其实就是一个特征,坊间更喜欢说feature.而usb 设备实
际上有很多feature.确切的说,有的feature 是算device 的feature,有些是interface 的feature,有些
是endpoint 的feature.而Halt是endpoint 的feature. usb spec规定了一些请求,比如SET_FEATURE,
以及CLEAR_FEATURE,顾名思义,就是设置一个feature 或者清除一个feature.那么我们这里发生的是
clear halt, 实际上就是执行CLEAR_FEATURE,清除halt 这个feature.刚才通过
usb_stor_Bulk_max_lun() 函数我们已经看到了对于一次控制传输,我们作为设备驱动需要做哪些工作,
这里和刚才的区别仅仅在于,刚才发送的请求是GET MAX LUN, 而现在要发送的请求是CLEAR FEATURE.
另一方面呢,GET MAX LUN 是usb mass storage spec 专门给它们这一小类设备定义的,而CLEAR
FEATURE 那是所有的usb 设备都通用的,因为它是usb spec 所规定的. |
|