Linux USB驱动框架分析(五)

接下来的工作是向系统注册一些以后会用的的信息。首先我们来说明一下usb-set_intfdata(),他向内核注册一个data,这个data结构可以是任意的,在这段程序用向内核注册了一个usb_skel结构,就是我们刚刚看到的被初始化的那个,这个data可以在以后用usb_get_intfdata来得到。

     usb_set_intfdata(interface, dev);

     retval = usb_register_dev(interface, &skel_class);

然后我们向这个interface注册一个skel_class结构。这个结构又是什么?我们就来看看这到底是个什么东西:

static struct usb_class_driver skel_class = {

     .name =       "skel%d",

     .fops =       &skel_fops,

     .minor_base = USB_SKEL_MINOR_BASE,

};

它其实是一个系统定义的结构,里面包含了一名字、一个文件操作结构体还有一个次设备号的基准值。事实上它定义真正完成对设备IO操作的函数。所以他的核心内容应该是skel_fops。这里补充一些我个人的估计:因为usb设备可以有多个interface,每个interface所定义的IO操作可能不一样,所以想系统注册的usb_class_driver要求注册到某一个interface,因此usb_register_dev的第一个参数是interface,而第二个参数就是某一个usb_class_driver。通常情况下,linux系统用主设备好来识别某类设备的的驱动程序,用次设备号管理识别具体的设备,驱动程序可以依照次设备好来区分不同的设备,所以,这里的次设备好其实是用来管理不同的interface的,但由于这个范例只有一个interface,在代码上无法求证这个猜想。

static struct file_operations skel_fops = {

     .owner = THIS_MODULE,

     .read =       skel_read,

     .write = skel_write,

     .open =       skel_open,

     .release =    skel_release,

};

这个文件操作结构中定义了对设备的读写、打开释放(USB设备通常使用这个术语release)。他们都是函数指针,分别指向skel_read、skel_write、skel_open、skel_release这四个函数,这四个函数应该有开发人员自己实现。

当设备被拔出集线器时,usb子系统会自动地调用disconnect,他做的事情不多,最重要的是注销class_driver(交还次设备号)和interface的data:

     dev = usb_get_intfdata(interface);

     usb_set_intfdata(interface, NULL);

 

     /* give back our minor */

     usb_deregister_dev(interface, &skel_class);

然后他会用kref_put(&dev->kref, skel_delete)进行清理,kref_put的细节参见前文。

到目前为止,我们已经分析完usb子系统要求的各个主要操作,下一部分我们在讨论一下对USB设备的IO操作。


你可能感兴趣的:(Linux USB驱动框架分析(五))