]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/media/video/cx88/cx88-mpeg.c
cx88: protect per-device driver list with device lock
[karo-tx-linux.git] / drivers / media / video / cx88 / cx88-mpeg.c
index addf9545e9bf42d6dac1591377e843763cee9305..918172b871483c1061344afb9b2a65617886a899 100644 (file)
@@ -748,6 +748,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
                       dev->pci->subsystem_device, dev->core->board.name,
                       dev->core->boardnr);
 
+               mutex_lock(&dev->core->lock);
+
                list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
                        /* only unregister the correct driver type */
                        if (d->type_id != drv->type_id)
@@ -755,15 +757,14 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
 
                        err = d->remove(d);
                        if (err == 0) {
-                               mutex_lock(&drv->core->lock);
                                list_del(&d->drvlist);
-                               mutex_unlock(&drv->core->lock);
                                kfree(d);
                        } else
                                printk(KERN_ERR "%s/2: cx8802 driver remove "
                                       "failed (%d)\n", dev->core->name, err);
                }
 
+               mutex_unlock(&dev->core->lock);
        }
 
        return err;
@@ -827,6 +828,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
 
        flush_request_modules(dev);
 
+       mutex_lock(&dev->core->lock);
+
        if (!list_empty(&dev->drvlist)) {
                struct cx8802_driver *drv, *tmp;
                int err;
@@ -838,9 +841,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
                list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
                        err = drv->remove(drv);
                        if (err == 0) {
-                               mutex_lock(&drv->core->lock);
                                list_del(&drv->drvlist);
-                               mutex_unlock(&drv->core->lock);
                        } else
                                printk(KERN_ERR "%s/2: cx8802 driver remove "
                                       "failed (%d)\n", dev->core->name, err);
@@ -848,6 +849,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
                }
        }
 
+       mutex_unlock(&dev->core->lock);
+
        /* Destroy any 8802 reference. */
        dev->core->dvbdev = NULL;