aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2008-04-22 13:45:44 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:07:48 -0400
commitc4a8828ddbf5fb445d2679ab006d5743540fc41a (patch)
tree2b17fa77218b812f164f1d897dfe1015d98d2510 /drivers/media/video/pvrusb2
parentee9ca4b24f03b4da04cae1a24ea445ceb8a1f3d2 (diff)
V4L/DVB (7319): pvrusb2: Close potential race condition during initialization
There is a callback that is issued to into pvr2_context from pvr2_hdw after initialization is done. There was a probability that this callback could get missed. Fixed. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pvrusb2')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.c7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c31
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h11
3 files changed, 26 insertions, 23 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c
index 2a6726e403f0..953784c08abb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.c
@@ -75,10 +75,9 @@ struct pvr2_context *pvr2_context_create(
75 mp = NULL; 75 mp = NULL;
76 goto done; 76 goto done;
77 } 77 }
78 pvr2_hdw_set_state_callback(mp->hdw, 78 pvr2_hdw_initialize(mp->hdw,
79 (void (*)(void *))pvr2_context_state_check, 79 (void (*)(void *))pvr2_context_state_check,
80 mp); 80 mp);
81 pvr2_context_state_check(mp);
82 done: 81 done:
83 return mp; 82 return mp;
84} 83}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index c51c5cef82dd..f2d2677936b3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1813,8 +1813,23 @@ static void pvr2_hdw_setup(struct pvr2_hdw *hdw)
1813} 1813}
1814 1814
1815 1815
1816/* Create and return a structure for interacting with the underlying 1816/* Perform second stage initialization. Set callback pointer first so that
1817 hardware */ 1817 we can avoid a possible initialization race (if the kernel thread runs
1818 before the callback has been set). */
1819void pvr2_hdw_initialize(struct pvr2_hdw *hdw,
1820 void (*callback_func)(void *),
1821 void *callback_data)
1822{
1823 LOCK_TAKE(hdw->big_lock); do {
1824 hdw->state_data = callback_data;
1825 hdw->state_func = callback_func;
1826 } while (0); LOCK_GIVE(hdw->big_lock);
1827 queue_work(hdw->workqueue,&hdw->workinit);
1828}
1829
1830
1831/* Create, set up, and return a structure for interacting with the
1832 underlying hardware. */
1818struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, 1833struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1819 const struct usb_device_id *devid) 1834 const struct usb_device_id *devid)
1820{ 1835{
@@ -2039,7 +2054,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2039 mutex_init(&hdw->ctl_lock_mutex); 2054 mutex_init(&hdw->ctl_lock_mutex);
2040 mutex_init(&hdw->big_lock_mutex); 2055 mutex_init(&hdw->big_lock_mutex);
2041 2056
2042 queue_work(hdw->workqueue,&hdw->workinit);
2043 return hdw; 2057 return hdw;
2044 fail: 2058 fail:
2045 if (hdw) { 2059 if (hdw) {
@@ -2521,17 +2535,6 @@ static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state)
2521} 2535}
2522 2536
2523 2537
2524void pvr2_hdw_set_state_callback(struct pvr2_hdw *hdw,
2525 void (*callback_func)(void *),
2526 void *callback_data)
2527{
2528 LOCK_TAKE(hdw->big_lock); do {
2529 hdw->state_data = callback_data;
2530 hdw->state_func = callback_func;
2531 } while (0); LOCK_GIVE(hdw->big_lock);
2532}
2533
2534
2535/* Return name for this driver instance */ 2538/* Return name for this driver instance */
2536const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) 2539const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2537{ 2540{
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 57e1ff491497..597ee5033149 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -101,14 +101,15 @@ struct pvr2_hdw;
101struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, 101struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
102 const struct usb_device_id *devid); 102 const struct usb_device_id *devid);
103 103
104/* Perform second stage initialization, passing in a notification callback
105 for when the master state changes. */
106void pvr2_hdw_initialize(struct pvr2_hdw *,
107 void (*callback_func)(void *),
108 void *callback_data);
109
104/* Destroy hardware interaction structure */ 110/* Destroy hardware interaction structure */
105void pvr2_hdw_destroy(struct pvr2_hdw *); 111void pvr2_hdw_destroy(struct pvr2_hdw *);
106 112
107/* Register a function to be called whenever the master state changes. */
108void pvr2_hdw_set_state_callback(struct pvr2_hdw *,
109 void (*callback_func)(void *),
110 void *callback_data);
111
112/* Return true if in the ready (normal) state */ 113/* Return true if in the ready (normal) state */
113int pvr2_hdw_dev_ok(struct pvr2_hdw *); 114int pvr2_hdw_dev_ok(struct pvr2_hdw *);
114 115