From: Helge Deller Adds the missing sysfs support to the CPiA driver by adding the needed remove() function. This avoids the current kernel warnings: videodev: "CPiA Camera" has no release callback. Please fix your driver for proper sysfs support, see http://lwn.net/Articles/36850/ Tested with a CPiA USB webcam. Signed-off-by: Andrew Morton --- 25-akpm/drivers/media/video/cpia.c | 39 +++++++++++++++++++++++++++---------- 25-akpm/drivers/media/video/cpia.h | 2 - 2 files changed, 30 insertions(+), 11 deletions(-) diff -puN drivers/media/video/cpia.c~add-missing-sysfs-support-to-cpia-webcam-video-driver drivers/media/video/cpia.c --- 25/drivers/media/video/cpia.c~add-missing-sysfs-support-to-cpia-webcam-video-driver Thu Jul 8 16:04:30 2004 +++ 25-akpm/drivers/media/video/cpia.c Thu Jul 8 16:04:30 2004 @@ -1368,7 +1368,7 @@ static void create_proc_cpia_cam(struct if (!cpia_proc_root || !cam) return; - sprintf(name, "video%d", cam->vdev.minor); + sprintf(name, "video%d", cam->vdev->minor); ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root); if (!ent) @@ -1393,7 +1393,7 @@ static void destroy_proc_cpia_cam(struct if (!cam || !cam->proc_entry) return; - sprintf(name, "video%d", cam->vdev.minor); + sprintf(name, "video%d", cam->vdev->minor); remove_proc_entry(name, cpia_proc_root); cam->proc_entry = NULL; } @@ -3710,7 +3710,7 @@ static int cpia_do_ioctl(struct inode *i DBG("VIDIOCGUNIT\n"); - vu->video = cam->vdev.minor; + vu->video = cam->vdev->minor; vu->vbi = VIDEO_NO_UNIT; vu->radio = VIDEO_NO_UNIT; vu->audio = VIDEO_NO_UNIT; @@ -3804,6 +3804,14 @@ static int cpia_mmap(struct file *file, return 0; } + +void cpia_video_release(struct video_device *vfd) +{ + struct cam_data *cam = vfd->priv; + down(&cam->busy_lock); + video_device_release(vfd); +} + static struct file_operations cpia_fops = { .owner = THIS_MODULE, .open = cpia_open, @@ -3820,6 +3828,8 @@ static struct video_device cpia_template .type = VID_TYPE_CAPTURE, .hardware = VID_HARDWARE_CPIA, .fops = &cpia_fops, + .release = cpia_video_release, + .minor = -1, }; /* initialise cam_data structure */ @@ -3930,7 +3940,7 @@ static void reset_camera_struct(struct c } /* initialize cam_data structure */ -static void init_camera_struct(struct cam_data *cam, +static int init_camera_struct(struct cam_data *cam, struct cpia_camera_ops *ops ) { int i; @@ -3946,8 +3956,13 @@ static void init_camera_struct(struct ca cam->proc_entry = NULL; - memcpy(&cam->vdev, &cpia_template, sizeof(cpia_template)); - cam->vdev.priv = cam; + cam->vdev = video_device_alloc(); + if (!cam->vdev) { + printk(KERN_ERR "cpia: video_device_alloc() failed!\n"); + return -ENOMEM; + } + memcpy(cam->vdev, &cpia_template, sizeof(cpia_template)); + cam->vdev->priv = cam; cam->curframe = 0; for (i = 0; i < FRAME_NUM; i++) { @@ -3960,6 +3975,7 @@ static void init_camera_struct(struct ca cam->decompressed_frame.height = 0; cam->decompressed_frame.state = FRAME_UNUSED; cam->decompressed_frame.data = NULL; + return 0; } struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel) @@ -3970,11 +3986,14 @@ struct cam_data *cpia_register_camera(st return NULL; - init_camera_struct( camera, ops ); + if (init_camera_struct( camera, ops )) { + kfree(camera); + return NULL; + } camera->lowlevel_data = lowlevel; /* register v4l device */ - if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { + if (video_register_device(camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { kfree(camera); printk(KERN_DEBUG "video_register_device failed\n"); return NULL; @@ -4019,7 +4038,7 @@ struct cam_data *cpia_register_camera(st void cpia_unregister_camera(struct cam_data *cam) { DBG("unregistering video\n"); - video_unregister_device(&cam->vdev); + video_unregister_device(cam->vdev); if (cam->open_count) { put_cam(cam->ops); DBG("camera open -- setting ops to NULL\n"); @@ -4027,7 +4046,7 @@ void cpia_unregister_camera(struct cam_d } #ifdef CONFIG_PROC_FS - DBG("destroying /proc/cpia/video%d\n", cam->vdev.minor); + DBG("destroying /proc/cpia/video%d\n", cam->vdev->minor); destroy_proc_cpia_cam(cam); #endif if (!cam->open_count) { diff -puN drivers/media/video/cpia.h~add-missing-sysfs-support-to-cpia-webcam-video-driver drivers/media/video/cpia.h --- 25/drivers/media/video/cpia.h~add-missing-sysfs-support-to-cpia-webcam-video-driver Thu Jul 8 16:04:30 2004 +++ 25-akpm/drivers/media/video/cpia.h Thu Jul 8 16:04:30 2004 @@ -268,7 +268,7 @@ struct cam_data { /* v4l */ int video_size; /* VIDEO_SIZE_ */ volatile enum v4l_camstates camstate; /* v4l layer status */ - struct video_device vdev; /* v4l videodev */ + struct video_device *vdev; /* v4l videodev */ struct video_picture vp; /* v4l camera settings */ struct video_window vw; /* v4l capture area */ struct video_capture vc; /* v4l subcapture area */ _