aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-core.c
diff options
context:
space:
mode:
authorChris Rankin <rankincj@yahoo.com>2011-09-24 10:02:32 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-24 11:12:48 -0400
commitd7222e7d6fb06ca3e7aa7a1ab07f8e6c6adb1d22 (patch)
tree733646ed67e9d39e4cdec59f4ed1ee08d46fc63a /drivers/media/video/em28xx/em28xx-core.c
parentbd829e9d1d7de3178d67d94043f43527213a63a0 (diff)
[media] 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. Signed-off-by: Chris Rankin <rankincj@yahoo.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-core.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c23
1 files changed, 5 insertions, 18 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index bd481ab65f29..804a4ab47ac6 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1184,18 +1184,6 @@ static LIST_HEAD(em28xx_devlist);
1184static DEFINE_MUTEX(em28xx_devlist_mutex); 1184static DEFINE_MUTEX(em28xx_devlist_mutex);
1185 1185
1186/* 1186/*
1187 * em28xx_realease_resources()
1188 * unregisters the v4l2,i2c and usb devices
1189 * called when the device gets disconected or at module unload
1190*/
1191void em28xx_remove_from_devlist(struct em28xx *dev)
1192{
1193 mutex_lock(&em28xx_devlist_mutex);
1194 list_del(&dev->devlist);
1195 mutex_unlock(&em28xx_devlist_mutex);
1196};
1197
1198/*
1199 * Extension interface 1187 * Extension interface
1200 */ 1188 */
1201 1189
@@ -1245,14 +1233,13 @@ void em28xx_init_extension(struct em28xx *dev)
1245 1233
1246void em28xx_close_extension(struct em28xx *dev) 1234void em28xx_close_extension(struct em28xx *dev)
1247{ 1235{
1248 struct em28xx_ops *ops = NULL; 1236 const struct em28xx_ops *ops = NULL;
1249 1237
1250 mutex_lock(&em28xx_devlist_mutex); 1238 mutex_lock(&em28xx_devlist_mutex);
1251 if (!list_empty(&em28xx_extension_devlist)) { 1239 list_for_each_entry(ops, &em28xx_extension_devlist, next) {
1252 list_for_each_entry(ops, &em28xx_extension_devlist, next) { 1240 if (ops->fini)
1253 if (ops->fini) 1241 ops->fini(dev);
1254 ops->fini(dev);
1255 }
1256 } 1242 }
1243 list_del(&dev->devlist);
1257 mutex_unlock(&em28xx_devlist_mutex); 1244 mutex_unlock(&em28xx_devlist_mutex);
1258} 1245}