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);