aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2/pvrusb2-hdw.c
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/pvrusb2-hdw.c
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/pvrusb2-hdw.c')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c31
1 files changed, 17 insertions, 14 deletions
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{