V4L/DVB (11172): pvrusb2: Cause overall initialization to fail if sub-driver(s) fail

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 74b365f..2f9667e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1974,8 +1974,8 @@
 }
 
 
-static void pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
-				 const struct pvr2_device_client_desc *cd)
+static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
+				const struct pvr2_device_client_desc *cd)
 {
 	const char *fname;
 	unsigned char mid;
@@ -1989,11 +1989,10 @@
 	fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
 	if (!fname) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "Module ID %u for device %s is unknown"
-			   " (this is probably a bad thing...)",
+			   "Module ID %u for device %s has no name",
 			   mid,
 			   hdw->hdw_desc->description);
-		return;
+		return -EINVAL;
 	}
 
 	i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list,
@@ -2007,11 +2006,10 @@
 
 	if (!i2ccnt) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "Module ID %u for device %s:"
-			   " No i2c addresses"
-			   " (this is probably a bad thing...)",
-			   mid, hdw->hdw_desc->description);
-		return;
+			   "Module ID %u (%s) for device %s:"
+			   " No i2c addresses",
+			   mid, fname, hdw->hdw_desc->description);
+		return -EINVAL;
 	}
 
 	/* Note how the 2nd and 3rd arguments are the same for both
@@ -2033,10 +2031,9 @@
 
 	if (!sd) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "Module ID %u for device %s failed to load"
-			   " (this is probably a bad thing...)",
-			   mid, hdw->hdw_desc->description);
-		return;
+			   "Module ID %u (%s) for device %s failed to load",
+			   mid, fname, hdw->hdw_desc->description);
+		return -EIO;
 	}
 
 	/* Tag this sub-device instance with the module ID we know about.
@@ -2080,6 +2077,8 @@
 		break;
 	default: break;
 	}
+
+	return 0;
 }
 
 
@@ -2088,6 +2087,7 @@
 	unsigned int idx;
 	const struct pvr2_string_table *cm;
 	const struct pvr2_device_client_table *ct;
+	int okFl = !0;
 
 	cm = &hdw->hdw_desc->client_modules;
 	for (idx = 0; idx < cm->cnt; idx++) {
@@ -2096,8 +2096,9 @@
 
 	ct = &hdw->hdw_desc->client_table;
 	for (idx = 0; idx < ct->cnt; idx++) {
-		pvr2_hdw_load_subdev(hdw,&ct->lst[idx]);
+		if (!pvr2_hdw_load_subdev(hdw, &ct->lst[idx])) okFl = 0;
 	}
+	if (!okFl) pvr2_hdw_render_useless(hdw);
 }
 
 
@@ -2159,6 +2160,7 @@
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
 	pvr2_hdw_load_modules(hdw);
+	if (!pvr2_hdw_dev_ok(hdw)) return;
 
 	for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
 		cptr = hdw->controls + idx;