Linux USB驱动框架分析(四)

转载 2012年03月26日 09:18:36

probe是usb子系统自动调用的一个函数,有USB设备接到硬件集线器时,usb子系统会根据production ID和vendor ID的组合或者设备的class、subclass跟protocol的组合来识别设备调用相应驱动程序的probe(探测)函数,对于skeleton来说,就是skel_probe。系统会传递给探测函数一个usb_interface *跟一个struct usb_device_id *作为参数。他们分别是该USB设备的接口描述(一般会是该设备的第0号接口,该接口的默认设置也是第0号设置)跟它的设备ID描述(包括Vendor ID、Production ID等)。Probe函数比较长,我们分段来分析这个函数:

dev->udev = usb_get_dev(interface_to_usbdev(interface));

dev->interface = interface;

在初始化了一些资源之后,我们可以看到第一个关键的函数调用——interface_to_usbdev。他同uo一个usb_interface来得到该接口所在设备的设备描述结构。本来,要得到一个usb_device只要用interface_to_usbdev就够了,但因为要增加对该usb_device的引用计数,我们应该在做一个usb_get_dev的操作,来增加引用计数,并在释放设备时用usb_put_dev来减少引用计数。这里要解释的是,该引用计数值是对该usb_device的计数,并不是对本模块的计数,本模块的计数要由kref来维护。所以,probe一开始就有初始化kref。事实上,kref_init操作不单只初始化kref,还将其置设成1。所以在出错处理代码中有kref_put,它把kref的计数减1,如果kref计数已经为0,那么kref会被释放。Kref_put的第二个参数是一个函数指针,指向一个清理函数。注意,该指针不能位空,或者kfree。该函数会在最后一个对kref的引用释放时被调用(如果我的理解不准确,请指正)。下面是内核源码中的一段注释及代码:

/**

* kref_put - decrement refcount for object.

* @kref: object.

* @release: pointer to the function that will clean up the object when the

* last reference to the object is released.

* This pointer is required, and it is not acceptable to pass kfree

* in as this function.

*

* Decrement the refcount, and if 0, call release().

* Return 1 if the object was removed, otherwise return 0. Beware, if this

* function returns 0, you still can not count on the kref from remaining in

* memory. Only use the return value if you want to see if the kref is now

* gone, not present.

*/

int kref_put(struct kref *kref, void (*release)(struct kref *kref))

{

WARN_ON(release == NULL);

WARN_ON(release == (void (*)(struct kref *))kfree);

/*

* if current count is one, we are the last user and can release object

* right now, avoiding an atomic operation on 'refcount'

*/

if ((atomic_read(&kref->refcount) == 1) ||

(atomic_dec_and_test(&kref->refcount))) {

release(kref);

return 1;

}

return 0;

}

当我们执行打开操作时,我们要增加kref的计数,我们可以用kref_get,来完成。所有对struct kref的操作都有内核代码确保其原子性。

得到了该usb_device之后,我们要对我们自定义的usb_skel各个状态跟资源作初始化。这部分工作的任务主要是向usb_skel注册该usb设备的端点。这里可能要补充以下一些关于usb_interface_descriptor的知识,但因为内核源码对该结构体的注释不多,所以只能靠个人猜测。在一个usb_host_interface结构里面有一个usb_interface_descriptor叫做desc的成员,他应该是用于描述该interface的一些属性,其中bNubEndpoints一个8位(b for byte)的数字,他代表了该接口的端点数。Probe然后遍历所有的端点,检查他们的类型跟方向,注册到usb_skel中。

/* set up the endpoint information */

/* use only the first bulk-in and bulk-out endpoints */

iface_desc = interface->cur_altsetting;

for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {

endpoint = &iface_desc->endpoint[i].desc;

if (!dev->bulk_in_endpointAddr &&

((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)

== USB_DIR_IN) &&

((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

== USB_ENDPOINT_XFER_BULK)) {

/* we found a bulk in endpoint */

buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);

dev->bulk_in_size = buffer_size;

dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;

dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);

if (!dev->bulk_in_buffer) {

err("Could not allocate bulk_in_buffer");

goto error;

}

}

if (!dev->bulk_out_endpointAddr &&

((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)

== USB_DIR_OUT) &&

((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

== USB_ENDPOINT_XFER_BULK)) {

/* we found a bulk out endpoint */

dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;

}

}

if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {

err("Could not find both bulk-in and bulk-out endpoints");

goto error;

}


linux usb子系统.框架

关键词: linux, 驱动,usb USB驱动组成部分:  USB的bus驱动。 usb_core。当USB设备接到USB控制器接口时,usb_core就检测该设备的一些信息...
  • cutter2002
  • cutter2002
  • 2017年04月08日 19:52
  • 420

USB驱动框架分析1

本文主要分析usb框架的主要数据结构,usb驱动框架的初始化,usb系统模型的建立过程...
  • xuao20060793
  • xuao20060793
  • 2015年06月17日 10:09
  • 916

linux驱动之USB驱动程序框架

USB驱动程序框架: app: -----------------------------------------------------------------------             ...
  • a912293097
  • a912293097
  • 2015年01月01日 10:37
  • 2480

Linux USB驱动框架分析

Linux USB驱动框架分析(一)    事实上,Linux的设备驱动都遵循一个惯例——表征驱动程序的结构体,结构体里面应该包含了驱动程序所需要的所有资源。用术语来说,就是这个驱动器对象所拥有的属性...
  • transistor0
  • transistor0
  • 2013年11月22日 15:37
  • 433

Linux USB驱动框架分析

转自http://blog.chinaunix.net/u1/59572/showart_1120862.htmlLinux USB驱动框架分析(一)    初次接触与OS相关的设备驱动编写,感觉还挺...
  • huanjieshuijing
  • huanjieshuijing
  • 2008年12月10日 15:39
  • 326

Linux USB驱动框架分析 上

Linux USB驱动框架分析 上Linux USB驱动框架分析(一)   初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结当然不可缺,更何况我决定为嵌入式卖命...
  • wangxuyang
  • wangxuyang
  • 2009年06月09日 18:08
  • 401

Linux USB驱动框架分析(三)

下面我们来分析一下usb-skeleton的源码吧。这个范例程序可以在linux-2.6.17/drivers/usb下找到,其他版本的内核程序源码可能有所不同,但相差不大。大家可以先找到源码看一看,...
  • leiwen_ndsc
  • leiwen_ndsc
  • 2012年03月26日 09:17
  • 230

Linux USB驱动框架分析 下

Linux USB驱动框架分析 下Linux USB驱动框架分析(五)    接下来的工作是向系统注册一些以后会用的的信息。首先我们来说明一下usb_set_intfdata(),他向内核注册一个da...
  • wangxuyang
  • wangxuyang
  • 2009年06月09日 18:12
  • 509

【转】Linux USB驱动框架分析

Linux USB驱动 框架分析(一)    初次接触与OS相关的设备 驱动编写,感觉还挺有意思的,为了不至于忘掉看过的 东西,笔记跟总结当然不可缺,更何况我决定为嵌入式 卖命了。好,言归正...
  • yuweixian
  • yuweixian
  • 2010年07月04日 21:41
  • 740

Linux USB驱动框架分析(六)

Linux USB驱动框架分析(六) 作者:admin    文章来源:网络    点击数:    更新时间:2012-3-7 http://www.linuxpx...
  • win2domain
  • win2domain
  • 2014年07月21日 10:47
  • 297
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux USB驱动框架分析(四)
举报原因:
原因补充:

(最多只允许输入30个字)