[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>
This commit is contained in:
Родитель
ce67943e2d
Коммит
54a2a84ea9
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче