Commit b8c0b00f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] zoran: add release callback

From: Ronald Bultje <rbultje@ronald.bitfreak.net>

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.
parent ef392885
......@@ -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; /* */
......
......@@ -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
......
......@@ -40,5 +40,6 @@ extern struct video_device zoran_template;
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__ */
......@@ -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 __devinitdata = {
#endif
.hardware = ZORAN_HARDWARE,
.fops = &zoran_fops,
.release = &zoran_vdev_release,
.minor = -1
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment