EM28xx - fix race on disconnect
PATCH 2/2 EM28xx - fix race on disconnect
This patch closes the race on the device and extension lists at USB disconnect time. Previously, the device was removed from the device list during em28xx_release_resources(), and then passed to the em28xx_close_extension() function so that all extensions could run their fini() operations. However, this left a (brief, theoretical, highly unlikely ;-)) window between these two calls during which a new module could call em28xx_register_extension(). The result would have been that the em28xx_usb_disconnect() function would also have passed the device to the new extension's fini() function, despite never having called the extension's init() function.
This patch also restores em28xx_close_extension()'s symmetry with em28xx_init_extension(), and establishes the property that every device in the device list must have been initialised for every extension in the extension list.
drivers/media/video/em28xx/em28xx-core.c renamed from drivers/media/video/em28xx/em28xx-core.c.orig +5 -18
@@ -1184,18 +1184,6 @@static DEFINE_MUTEX (em28xx_devlist_mutex);/* -* em28xx_realease_resources() -* unregisters the v4l2,i2c and usb devices -* called when the device gets disconected or at module unload -*/ -void em28xx_remove_from_devlist (struct em28xx *dev) -{ -mutex_lock (&em28xx_devlist_mutex); -list_del (&dev->devlist); -mutex_unlock (&em28xx_devlist_mutex); -}; - -/* * Extension interface */
@@ -1245,14 +1233,13 @@void em28xx_close_extension (struct em28xx *dev) { -struct em28xx_ops *ops =NULL ; +const struct em28xx_ops *ops =NULL ;mutex_lock (&em28xx_devlist_mutex); -if (!list_empty (&em28xx_extension_devlist)) { -list_for_each_entry (ops, &em28xx_extension_devlist, next) { -if (ops->fini) - ops->fini (dev); - } +list_for_each_entry (ops, &em28xx_extension_devlist, next) { +if (ops->fini) + ops->fini (dev); } +list_del (&dev->devlist);mutex_unlock (&em28xx_devlist_mutex); }
drivers/media/video/em28xx/em28xx-cards.c renamed from drivers/media/video/em28xx/em28xx-cards.c.orig +3 -5
@@ -2800,9 +2800,9 @@#endif /* CONFIG_MODULES */ /* -* em28xx_realease_resources() +* em28xx_release_resources() * unregisters the v4l2,i2c and usb devices -* called when the device gets disconected or at module unload +* called when the device gets disconnected or at module unload */ void em28xx_release_resources (struct em28xx *dev) {
@@ -2816,8 +2816,6 @@em28xx_release_analog_resources (dev); -em28xx_remove_from_devlist (dev); -em28xx_i2c_unregister (dev);v4l2_device_unregister (&dev->v4l2_dev);
@@ -3255,7 +3253,7 @@/* * em28xx_usb_disconnect() -* called when the device gets diconencted +* called when the device gets disconnected * video device will be unregistered on v4l2_close in case it is still open */ static void em28xx_usb_disconnect (struct usb_interface *interface)