diff options
author | Mike Isely <isely@pobox.com> | 2008-04-07 07:22:04 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 19:09:48 +0200 |
commit | e5be15c63804e05b5a94197524023702a259e308 (patch) | |
tree | 4223cab8016088a06d0423e1e41eacb646867c46 /drivers/media/video/pvrusb2/pvrusb2-main.c | |
parent | V4L/DVB (7710): pvrusb2: Implement critical digital streaming quirk for onair... (diff) | |
download | linux-e5be15c63804e05b5a94197524023702a259e308.tar.xz linux-e5be15c63804e05b5a94197524023702a259e308.zip |
V4L/DVB (7711): pvrusb2: Fix race on module unload
The pvrusb2 driver - for basically forever - was not enforcing a
proper module tear-down. Kernel threads are used inside the driver
and all must be gone before the module can be safely removed. This
changeset reimplements a chunk of pvrusb2-context.c to enforce this
correctly. Unfortunately this is not a simple fix. The new
implementation also cuts back on kernel thread usage; instead of there
being 1 control thread per instance now it's just 1 control thread
shared by all instances. (By dropping to a single thread then the
module exit function can block on its shutdown and the thread itself
can monitor and cleanly shut down all of the other instances first.)
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-main.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-main.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c index 54d9f168d7ad..332aced8a5a1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -125,6 +125,12 @@ static int __init pvr_init(void) pvr2_trace(PVR2_TRACE_INIT,"pvr_init"); + ret = pvr2_context_global_init(); + if (ret != 0) { + pvr2_trace(PVR2_TRACE_INIT,"pvr_init failure code=%d",ret); + return ret; + } + #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS class_ptr = pvr2_sysfs_class_create(); #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ @@ -136,6 +142,8 @@ static int __init pvr_init(void) if (pvrusb2_debug) info("Debug mask is %d (0x%x)", pvrusb2_debug,pvrusb2_debug); + pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete"); + return ret; } @@ -148,6 +156,10 @@ static void __exit pvr_exit(void) #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS pvr2_sysfs_class_destroy(class_ptr); #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ + + pvr2_context_global_done(); + + pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete"); } module_init(pvr_init); |