Skip to content

Commit

Permalink
[media] cx231xx: fix race condition in DVB initialization
Browse files Browse the repository at this point in the history
Fix case where analog calls come in while the DVB side of the board is still
initializing.  This patch is actually just an exact port of the same patch
made by Mauro to em28xx in hg rev 14762.

Signed-off-by: Devin Heitmueller <dheitmueller@hauppauge.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed Oct 21, 2010
1 parent d78148f commit 761f6cf
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 13 deletions.
13 changes: 4 additions & 9 deletions drivers/media/video/cx231xx/cx231xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,17 @@ void cx231xx_add_into_devlist(struct cx231xx *dev)
};

static LIST_HEAD(cx231xx_extension_devlist);
static DEFINE_MUTEX(cx231xx_extension_devlist_lock);

int cx231xx_register_extension(struct cx231xx_ops *ops)
{
struct cx231xx *dev = NULL;

mutex_lock(&cx231xx_devlist_mutex);
mutex_lock(&cx231xx_extension_devlist_lock);
list_add_tail(&ops->next, &cx231xx_extension_devlist);
list_for_each_entry(dev, &cx231xx_devlist, devlist)
ops->init(dev);

printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name);
mutex_unlock(&cx231xx_extension_devlist_lock);
mutex_unlock(&cx231xx_devlist_mutex);
return 0;
}
Expand All @@ -125,10 +122,8 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops)
ops->fini(dev);


mutex_lock(&cx231xx_extension_devlist_lock);
printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name);
list_del(&ops->next);
mutex_unlock(&cx231xx_extension_devlist_lock);
mutex_unlock(&cx231xx_devlist_mutex);
}
EXPORT_SYMBOL(cx231xx_unregister_extension);
Expand All @@ -137,28 +132,28 @@ void cx231xx_init_extension(struct cx231xx *dev)
{
struct cx231xx_ops *ops = NULL;

mutex_lock(&cx231xx_extension_devlist_lock);
mutex_lock(&cx231xx_devlist_mutex);
if (!list_empty(&cx231xx_extension_devlist)) {
list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
if (ops->init)
ops->init(dev);
}
}
mutex_unlock(&cx231xx_extension_devlist_lock);
mutex_unlock(&cx231xx_devlist_mutex);
}

void cx231xx_close_extension(struct cx231xx *dev)
{
struct cx231xx_ops *ops = NULL;

mutex_lock(&cx231xx_extension_devlist_lock);
mutex_lock(&cx231xx_devlist_mutex);
if (!list_empty(&cx231xx_extension_devlist)) {
list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
if (ops->fini)
ops->fini(dev);
}
}
mutex_unlock(&cx231xx_extension_devlist_lock);
mutex_unlock(&cx231xx_devlist_mutex);
}

/****************************************************************
Expand Down
12 changes: 8 additions & 4 deletions drivers/media/video/cx231xx/cx231xx-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ static int dvb_init(struct cx231xx *dev)
dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;

mutex_lock(&dev->lock);
cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
cx231xx_demod_reset(dev);
/* init frontend */
Expand Down Expand Up @@ -707,15 +708,18 @@ static int dvb_init(struct cx231xx *dev)
if (result < 0)
goto out_free;

cx231xx_set_mode(dev, CX231XX_SUSPEND);

printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
return 0;

out_free:
ret:
cx231xx_set_mode(dev, CX231XX_SUSPEND);
mutex_unlock(&dev->lock);
return result;

out_free:
kfree(dvb);
dev->dvb = NULL;
return result;
goto ret;
}

static int dvb_fini(struct cx231xx *dev)
Expand Down

0 comments on commit 761f6cf

Please sign in to comment.