diff options
author | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-12-27 20:01:04 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-01-05 14:58:49 +0400 |
commit | 54a2a84ea9e8640b4f1df4e222e305d03bb64065 (patch) | |
tree | 0267199272444b3ae7d66534dc71c0dfbdb56e87 /drivers/media/usb | |
parent | ce67943e2dfd3bc8b7e86b428fc0dfc568730971 (diff) | |
download | linux-54a2a84ea9e8640b4f1df4e222e305d03bb64065.tar.xz |
[media] em28xx: Fix em28xx deplock
When em28xx extensions are loaded/removed, there are two locks:
a single static em28xx_devlist_mutex that registers each extension
and the struct em28xx dev->lock.
When extensions are registered, em28xx_devlist_mutex is taken first,
and then dev->lock.
Be sure that, when extensions are being removed, the same order
will be used.
Reviewed-by: Frank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-cards.c | 5 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-core.c | 2 |
2 files changed, 5 insertions, 2 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 551cbc294190..154e6f028fd2 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -3485,9 +3485,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) dev->disconnected = 1; if (dev->is_audio_only) { - mutex_lock(&dev->lock); em28xx_close_extension(dev); - mutex_unlock(&dev->lock); return; } @@ -3506,10 +3504,13 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE); } + mutex_unlock(&dev->lock); em28xx_close_extension(dev); + /* NOTE: must be called BEFORE the resources are released */ + mutex_lock(&dev->lock); if (!dev->users) em28xx_release_resources(dev); diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 3012912d2997..f77301773aee 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -1094,10 +1094,12 @@ void em28xx_close_extension(struct em28xx *dev) const struct em28xx_ops *ops = NULL; mutex_lock(&em28xx_devlist_mutex); + mutex_lock(&dev->lock); list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->fini) ops->fini(dev); } + mutex_unlock(&dev->lock); list_del(&dev->devlist); mutex_unlock(&em28xx_devlist_mutex); } |