diff options
author | Jonathan Nieder <jrnieder@gmail.com> | 2011-05-01 05:30:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:29:38 -0400 |
commit | 344d6c6ba6ba5c4fede2f07adbd26d53109a2dd8 (patch) | |
tree | e76f78428ccde8e7c294f23ce128728ce0afb3d6 /drivers/media/video/cx88 | |
parent | 1d6213ab995c61f7d1d81cf6cf876acf15d6e714 (diff) |
[media] cx88: protect cx8802_devlist with a mutex
Add and use a mutex to protect the cx88-mpeg device list. Previously
the BKL prevented races.
Based on work by Ben Hutchings <ben@decadent.org.uk>.
Tested-by: Andi Huber <hobrom@gmx.at>
Tested-by: Marlon de Boer <marlon@hyves.nl>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx88')
-rw-r--r-- | drivers/media/video/cx88/cx88-mpeg.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 455290011d4e..1a7b983f8297 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -78,6 +78,7 @@ static void flush_request_modules(struct cx8802_dev *dev) | |||
78 | 78 | ||
79 | 79 | ||
80 | static LIST_HEAD(cx8802_devlist); | 80 | static LIST_HEAD(cx8802_devlist); |
81 | static DEFINE_MUTEX(cx8802_mutex); | ||
81 | /* ------------------------------------------------------------------ */ | 82 | /* ------------------------------------------------------------------ */ |
82 | 83 | ||
83 | static int cx8802_start_dma(struct cx8802_dev *dev, | 84 | static int cx8802_start_dma(struct cx8802_dev *dev, |
@@ -689,6 +690,8 @@ int cx8802_register_driver(struct cx8802_driver *drv) | |||
689 | return err; | 690 | return err; |
690 | } | 691 | } |
691 | 692 | ||
693 | mutex_lock(&cx8802_mutex); | ||
694 | |||
692 | list_for_each_entry(dev, &cx8802_devlist, devlist) { | 695 | list_for_each_entry(dev, &cx8802_devlist, devlist) { |
693 | printk(KERN_INFO | 696 | printk(KERN_INFO |
694 | "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", | 697 | "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", |
@@ -698,8 +701,10 @@ int cx8802_register_driver(struct cx8802_driver *drv) | |||
698 | 701 | ||
699 | /* Bring up a new struct for each driver instance */ | 702 | /* Bring up a new struct for each driver instance */ |
700 | driver = kzalloc(sizeof(*drv),GFP_KERNEL); | 703 | driver = kzalloc(sizeof(*drv),GFP_KERNEL); |
701 | if (driver == NULL) | 704 | if (driver == NULL) { |
702 | return -ENOMEM; | 705 | err = -ENOMEM; |
706 | goto out; | ||
707 | } | ||
703 | 708 | ||
704 | /* Snapshot of the driver registration data */ | 709 | /* Snapshot of the driver registration data */ |
705 | drv->core = dev->core; | 710 | drv->core = dev->core; |
@@ -722,7 +727,10 @@ int cx8802_register_driver(struct cx8802_driver *drv) | |||
722 | mutex_unlock(&drv->core->lock); | 727 | mutex_unlock(&drv->core->lock); |
723 | } | 728 | } |
724 | 729 | ||
725 | return i ? 0 : -ENODEV; | 730 | err = i ? 0 : -ENODEV; |
731 | out: | ||
732 | mutex_unlock(&cx8802_mutex); | ||
733 | return err; | ||
726 | } | 734 | } |
727 | 735 | ||
728 | int cx8802_unregister_driver(struct cx8802_driver *drv) | 736 | int cx8802_unregister_driver(struct cx8802_driver *drv) |
@@ -736,6 +744,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) | |||
736 | drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", | 744 | drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", |
737 | drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); | 745 | drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); |
738 | 746 | ||
747 | mutex_lock(&cx8802_mutex); | ||
748 | |||
739 | list_for_each_entry(dev, &cx8802_devlist, devlist) { | 749 | list_for_each_entry(dev, &cx8802_devlist, devlist) { |
740 | printk(KERN_INFO | 750 | printk(KERN_INFO |
741 | "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", | 751 | "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", |
@@ -762,6 +772,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) | |||
762 | mutex_unlock(&dev->core->lock); | 772 | mutex_unlock(&dev->core->lock); |
763 | } | 773 | } |
764 | 774 | ||
775 | mutex_unlock(&cx8802_mutex); | ||
776 | |||
765 | return err; | 777 | return err; |
766 | } | 778 | } |
767 | 779 | ||
@@ -799,7 +811,9 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
799 | goto fail_free; | 811 | goto fail_free; |
800 | 812 | ||
801 | INIT_LIST_HEAD(&dev->drvlist); | 813 | INIT_LIST_HEAD(&dev->drvlist); |
814 | mutex_lock(&cx8802_mutex); | ||
802 | list_add_tail(&dev->devlist,&cx8802_devlist); | 815 | list_add_tail(&dev->devlist,&cx8802_devlist); |
816 | mutex_unlock(&cx8802_mutex); | ||
803 | 817 | ||
804 | /* now autoload cx88-dvb or cx88-blackbird */ | 818 | /* now autoload cx88-dvb or cx88-blackbird */ |
805 | request_modules(dev); | 819 | request_modules(dev); |