Spac5xx的实现是按照标准的USB VIDEO设备的驱动框架编写(其具体的驱动框架可参照/usr/src/linux/drivers/usb/usbvideo.c文件),整个源程序由四个主体部分组成:
设备模块的初始化模块和卸载模块,上层软件接口模块,数据传输模块。
具体的模块分析如下:
一、初始化设备模块
该驱动采用了显式的模块初始化和消除函数,即调用module_init来初始化一个模块,并在卸载时调用moduel-exit函数
其具体实现如下:
1、模块初始化:
- module_init (usb_spca5xx_init);
- static int __init usb_spca5xx_init (void)
- {
- #ifdef CONFIG_PROC_FS
- proc_spca50x_create ();//建立PROC设备文件
- #endif /* CONFIG_PROC_FS */
- if (usb_register (&spca5xx_driver) < 0) //注册USB设备驱动
- return -1;
- info ("spca5xx driver %s registered", version);
- return 0;
- }
2、模块卸载:
- module_exit (usb_spca5xx_exit);
- static void __exit usb_spca5xx_exit (void)
- {
- usb_deregister (&spca5xx_driver); //注销USB设备驱动
- info ("driver spca5xx deregistered");
- #ifdef CONFIG_PROC_FS
- proc_spca50x_destroy ();//撤消PROC设备文件
- #endif /* CONFIG_PROC_FS */
- }
关键数据结构 USB驱动结构,即插即用功能的实现
- static struct usb_driver spca5xx_driver = {
- "spca5xx",
- spca5xx_probe, //注册设备自我侦测功能
- spca5xx_disconnect,//注册设备自我断开功能
- {NULL,NULL}
- };
用两个函数调用spca5xx_probe 和spca5xx_disconnect来支持USB设备的即插即用功能:
a -- spca5xx_probe 具体实现如下:
- static void * spca5xx_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
- {
- struct usb_interface_descriptor *interface; //USB设备接口描述符
- struct usb_spca50x *spca50x; //物理设备数据结构
- int err_probe;
- int i;
- if (dev->descriptor.bNumConfigurations != 1) //探测设备是不是可配置
- goto nodevice;
- if (ifnum > 0)
- goto nodevice;
- interface = &dev->actconfig->interface[ifnum].altsetting[0];
- MOD_INC_USE_COUNT;
- interface = &intf->altsetting[0].desc;
- if (interface->bInterfaceNumber > 0)
- goto nodevice;
- if ((spca50x = kmalloc (sizeof (struct usb_spca50x), GFP_KERNEL)) == NULL) //分配物理地址空间
- {
- err ("couldn't kmalloc spca50x struct");
- goto error;
- }
- memset (spca50x, 0, sizeof (struct usb_spca50x));
- spca50x->dev = dev;
- spca50x->iface = interface->bInterfaceNumber;
- if ((err_probe = spcaDetectCamera (spca50x)) < 0) //具体物理设备查找,匹配厂商号,设备号(在子程序中)
- {
- err (" Devices not found !! ");
- goto error;
- }
- PDEBUG (0, "Camera type %s ", Plist[spca50x->cameratype].name)
- for (i = 0; i < SPCA50X_NUMFRAMES; i++)
- init_waitqueue_head (&spca50x->frame[i].wq); //初始化帧等待队列
- init_waitqueue_head (&spca50x->wq); //初始化驱动等待队列
- if (!spca50x_configure (spca50x)) //物理设备配置(主要完成传感器侦测和图形参数配置),主要思想是给控制寄存器写值,读回其返回值,以此判断具体的传感器型号
- {
- spca50x->user = 0;
- init_MUTEX (&spca50x->lock); //信号量初始化
- init_MUTEX (&spca50x->buf_lock);
- spca50x->v4l_lock = SPIN_LOCK_UNLOCKED;
- spca50x->buf_state = BUF_NOT_ALLOCATED;