V4L/DVB (7712): pvrusb2: Close connect/disconnect race

If a disconnect happens before initialization is completed, the
pvrusb2 driver can accidentally touch dangling pointers.  The whole
initialization function must be protected by the big_lock, and once
inside that lock, the initialization function should abort if it is
discovered that a disconnect has already taken place.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 4f6bb58..f907a56 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1854,10 +1854,19 @@
 			void *callback_data)
 {
 	LOCK_TAKE(hdw->big_lock); do {
+		if (hdw->flag_disconnected) {
+			/* Handle a race here: If we're already
+			   disconnected by this point, then give up.  If we
+			   get past this then we'll remain connected for
+			   the duration of initialization since the entire
+			   initialization sequence is now protected by the
+			   big_lock. */
+			break;
+		}
 		hdw->state_data = callback_data;
 		hdw->state_func = callback_func;
+		pvr2_hdw_setup(hdw);
 	} while (0); LOCK_GIVE(hdw->big_lock);
-	pvr2_hdw_setup(hdw);
 	return hdw->flag_init_ok;
 }