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.

是一种时尚.我常常对自己说,如果哪一天我没有闯红灯,那么由此可以推导出来,这一天我一定没有出门.同<br />

样,在usb 的世界中,设备也总是那么的不守规矩,我们必须要设计一个东西出来管理来控制所有的usb 设<br />

备的通信,这样,主机控制器就横空出世了.<br />

那么设备和主机控制器的分工又是如何呢?硬件实现上我们就不说了,说点具体的,Linux 中,设备驱动<br />

程序只要为每一次请求准备一个urb 结构体变量,把它填充好,(就是说赋上该赋的值)然后它调用usb core<br />

提供的函数,把这个urb 传递给host controller,host controller 就会把各个设备驱动程序所提交的urb<br />

统一规划,去执行每一个操作.而这期间,usb 设备驱动程序通常会进入睡眠,而一旦host controller 把urb<br />

要做的事情给做完了,它会调用一个函数去唤醒usb 设备驱动程序,然后usb 设备驱动程序就可以继续往<br />

下<br />

走了.这又好比我们学校里的师生关系.考试的时候,我们只管把试卷填好,然后我们交给老师,然后老师拿去<br />

批改试卷,这期间我们除了等待别无选择,等待老师改完了试卷,告诉了我们分数,我们又继续我们的生活.当<br />

然了,如果成绩不好,也许有些人的生活就不会继续了,在复旦,我们可以选择去曾经的绝情谷上吊,可以选择<br />

去第四教学楼顶层跳下来,在交大,则可以去跳思源湖.同样,usb 设备驱动程序也是如此,如果urb 提交给<br />

usb host 了,但是最终却没有成功执行,那么也许该usb 设备驱动程序的生命也就提前结束.不过这都是后<br />

话,现在只要有个感性认识即可,稍后看到了就能更深刻的体会了,这种岗位分工的方式给我们编写设备驱动<br />

程序带来了巨大的方便.<br />

心锁<br />

如果大家没意见的话,我们继续usb_stor_acquire_resources 函数.<br />

761 至764 行,这没啥好说的吧.就是刚才urb 申请了之后判断是否申请成功了,如果指针为NULL 那么<br />

就是失败了.直接返回-ENOMEM.别往下了.<br />

767 行,哦,又一个家伙闪亮登场了,dev_semaphore,这是一个信号量,在storage_probe 的最初始阶<br />

段我们曾经见过,当时有这么一句话,这就是调用一个宏init_MUTEX 来初始化一个信号量,<br />

943 init_MUTEX(&(us->dev_semaphore));<br />

我们当时说了,等到用的时候再讲.不过现在的确是到用的时候了,不过,我还不想讲.曾经我天真的以为,<br />

只要学了谭浩强的那本C 程序设计,即便不能写代码,也应该能够看懂代码.然而,后来我发现事实并非如此,<br />

世界没错,我错了.<br />

70<br />

首先,什么是信号量?毕业的时候,校园招聘中常常笔试面试会考信号量,会考死锁,不过通常考的会比较<br />

简单,更多的情况是考察一些基本概念,印象中曾经在Sun 中国工程研究院的面试中被问起过,当然也有比<br />

较复杂一点的,要求结合具体的问题对某种算法进行合理性分析,比如Intel 某年在上海交大的笔试题,考到<br />

了经典的哲学家进餐问题,不过幸运的是这种变态的笔试题我没遇上,我进Intel 的时候只被问起解释冒泡<br />

排序法...<br />

我们整个故事中有两个信号量,它们都是us 的成员,一个是这个dev_semaphore,另一个是sema,在<br />

定义struct us_data 的时候我们已经看到过,<br />

111 struct semaphore dev_semaphore; /* protect pusb_dev */<br />

156 struct semaphore sema; /* to sleep thread on */<br />

sema 也同样是在storage_probe 的一开始就做了初始化,<br />

944 init_MUTEX_LOCKED(&(us->sema));<br />

设备驱动中最难的部分在于三个方面,一个是涉及到内存管理的代码,一个是涉及到进程管理的代码,另一<br />

个就是信号量和互斥锁或者别的锁的代码.这些部分如果不合理将容易导致系统崩溃,而信号量最容易导致<br />

的就是死锁.<br />

网名为卖血上网的哥们说话了,那么到底什么是信号量?或者什么是互斥锁?

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

Saved successfully!

Ooh no, something went wrong!