From: Ronald Bultje This patch adds a release callback which frees the video_device struct. This is needed to prevent freeing memory before it's not in use anymore, as described in http://lwn.net/Articles/36850/. Without this, the driver will give a warning when loaded. It might crash when unloading (see article), too. The video4linux patch (by Gerd Knorr) was accepted a week (or 2?) ago, but I forgot to adapt my driver to it. drivers/media/video/zoran.h | 2 +- drivers/media/video/zoran_card.c | 26 ++++++++++++++++++++------ drivers/media/video/zoran_card.h | 1 + drivers/media/video/zoran_driver.c | 5 +++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff -puN drivers/media/video/zoran_card.c~zoran-release-callback drivers/media/video/zoran_card.c --- 25/drivers/media/video/zoran_card.c~zoran-release-callback 2003-08-24 02:07:59.000000000 -0700 +++ 25-akpm/drivers/media/video/zoran_card.c 2003-08-24 02:07:59.000000000 -0700 @@ -987,6 +987,7 @@ static int __devinit zr36057_init (struct zoran *zr) { unsigned long mem; + void *vdev; unsigned mem_needed; int j; int two = 2; @@ -1041,11 +1042,16 @@ zr36057_init (struct zoran *zr) * in case allocation fails */ mem_needed = BUZ_NUM_STAT_COM * 4; mem = (unsigned long) kmalloc(mem_needed, GFP_KERNEL); - if (!mem) { + vdev = (void *) kmalloc(sizeof(struct video_device), GFP_KERNEL); + if (!mem || !vdev) { dprintk(1, KERN_ERR "%s: zr36057_init() - kmalloc (STAT_COM) failed\n", ZR_DEVNAME(zr)); + if (vdev) + kfree(vdev); + if (mem) + kfree((void *)mem); return -ENOMEM; } memset((void *) mem, 0, mem_needed); @@ -1057,12 +1063,14 @@ zr36057_init (struct zoran *zr) /* * Now add the template and register the device unit. */ - memcpy(&zr->video_dev, &zoran_template, sizeof(zoran_template)); - strcpy(zr->video_dev.name, ZR_DEVNAME(zr)); - if (video_register_device - (&zr->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { + zr->video_dev = vdev; + memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); + strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); + if (video_register_device(zr->video_dev, VFL_TYPE_GRABBER, + video_nr) < 0) { zoran_unregister_i2c(zr); kfree((void *) zr->stat_com); + kfree(vdev); return -1; } @@ -1110,7 +1118,13 @@ zoran_release (struct zoran *zr) kfree((void *) zr->stat_com); zoran_proc_cleanup(zr); iounmap(zr->zr36057_mem); - video_unregister_device(&zr->video_dev); + video_unregister_device(zr->video_dev); +} + +void +zoran_vdev_release (struct video_device *vdev) +{ + kfree(vdev); } static struct videocodec_master * __devinit diff -puN drivers/media/video/zoran_card.h~zoran-release-callback drivers/media/video/zoran_card.h --- 25/drivers/media/video/zoran_card.h~zoran-release-callback 2003-08-24 02:07:59.000000000 -0700 +++ 25-akpm/drivers/media/video/zoran_card.h 2003-08-24 02:07:59.000000000 -0700 @@ -40,5 +40,6 @@ extern struct video_device zoran_templat extern int zoran_check_jpg_settings(struct zoran *zr, struct zoran_jpg_settings *settings); extern void zoran_open_init_params(struct zoran *zr); +extern void zoran_vdev_release(struct video_device *vdev); #endif /* __ZORAN_CARD_H__ */ diff -puN drivers/media/video/zoran_driver.c~zoran-release-callback drivers/media/video/zoran_driver.c --- 25/drivers/media/video/zoran_driver.c~zoran-release-callback 2003-08-24 02:07:59.000000000 -0700 +++ 25-akpm/drivers/media/video/zoran_driver.c 2003-08-24 02:07:59.000000000 -0700 @@ -1268,7 +1268,7 @@ zoran_open (struct inode *inode, /* find the device */ for (i = 0; i < zoran_num; i++) { - if (zoran[i].video_dev.minor == minor) { + if (zoran[i].video_dev->minor == minor) { zr = &zoran[i]; break; } @@ -2358,7 +2358,7 @@ zoran_do_ioctl (struct inode *inode, struct video_unit *vunit = arg; dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr)); - vunit->video = zr->video_dev.minor; + vunit->video = zr->video_dev->minor; vunit->vbi = VIDEO_NO_UNIT; vunit->radio = VIDEO_NO_UNIT; vunit->audio = VIDEO_NO_UNIT; @@ -4665,5 +4665,6 @@ struct video_device zoran_template __dev #endif .hardware = ZORAN_HARDWARE, .fops = &zoran_fops, + .release = &zoran_vdev_release, .minor = -1 }; diff -puN drivers/media/video/zoran.h~zoran-release-callback drivers/media/video/zoran.h --- 25/drivers/media/video/zoran.h~zoran-release-callback 2003-08-24 02:07:59.000000000 -0700 +++ 25-akpm/drivers/media/video/zoran.h 2003-08-24 02:07:59.000000000 -0700 @@ -383,7 +383,7 @@ struct card_info { }; struct zoran { - struct video_device video_dev; + struct video_device *video_dev; struct i2c_adapter i2c_adapter; /* */ struct i2c_algo_bit_data i2c_algo; /* */ _