HID: make debugging output runtime-configurable

There have been many reports recently about broken HID devices, the
diagnosis of which required users to recompile their kernels in order
to be able to provide debugging output needed for coding a quirk for
a particular device.

This patch makes CONFIG_HID_DEBUG default y if !EMBEDDED and makes it
possible to control debugging output produced by HID code by supplying
'debug=1' module parameter.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 6ec04e7..317cf8a 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -40,6 +40,13 @@
 #define DRIVER_DESC "HID core driver"
 #define DRIVER_LICENSE "GPL"
 
+#ifdef CONFIG_HID_DEBUG
+int hid_debug = 0;
+module_param_named(debug, hid_debug, bool, 0600);
+MODULE_PARM_DESC(debug, "Turn HID debugging mode on and off");
+EXPORT_SYMBOL_GPL(hid_debug);
+#endif
+
 /*
  * Register a new report for a device.
  */
@@ -78,7 +85,7 @@
 	struct hid_field *field;
 
 	if (report->maxfield == HID_MAX_FIELDS) {
-		dbg("too many fields in report");
+		dbg_hid("too many fields in report\n");
 		return NULL;
 	}
 
@@ -106,7 +113,7 @@
 	usage = parser->local.usage[0];
 
 	if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
-		dbg("collection stack overflow");
+		dbg_hid("collection stack overflow\n");
 		return -1;
 	}
 
@@ -114,7 +121,7 @@
 		collection = kmalloc(sizeof(struct hid_collection) *
 				parser->device->collection_size * 2, GFP_KERNEL);
 		if (collection == NULL) {
-			dbg("failed to reallocate collection array");
+			dbg_hid("failed to reallocate collection array\n");
 			return -1;
 		}
 		memcpy(collection, parser->device->collection,
@@ -150,7 +157,7 @@
 static int close_collection(struct hid_parser *parser)
 {
 	if (!parser->collection_stack_ptr) {
-		dbg("collection stack underflow");
+		dbg_hid("collection stack underflow\n");
 		return -1;
 	}
 	parser->collection_stack_ptr--;
@@ -178,7 +185,7 @@
 static int hid_add_usage(struct hid_parser *parser, unsigned usage)
 {
 	if (parser->local.usage_index >= HID_MAX_USAGES) {
-		dbg("usage index exceeded");
+		dbg_hid("usage index exceeded\n");
 		return -1;
 	}
 	parser->local.usage[parser->local.usage_index] = usage;
@@ -202,12 +209,12 @@
 	int i;
 
 	if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
-		dbg("hid_register_report failed");
+		dbg_hid("hid_register_report failed\n");
 		return -1;
 	}
 
 	if (parser->global.logical_maximum < parser->global.logical_minimum) {
-		dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
+		dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum);
 		return -1;
 	}
 
@@ -287,7 +294,7 @@
 		case HID_GLOBAL_ITEM_TAG_PUSH:
 
 			if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
-				dbg("global enviroment stack overflow");
+				dbg_hid("global enviroment stack overflow\n");
 				return -1;
 			}
 
@@ -298,7 +305,7 @@
 		case HID_GLOBAL_ITEM_TAG_POP:
 
 			if (!parser->global_stack_ptr) {
-				dbg("global enviroment stack underflow");
+				dbg_hid("global enviroment stack underflow\n");
 				return -1;
 			}
 
@@ -342,27 +349,27 @@
 
 		case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
 			if ((parser->global.report_size = item_udata(item)) > 32) {
-				dbg("invalid report_size %d", parser->global.report_size);
+				dbg_hid("invalid report_size %d\n", parser->global.report_size);
 				return -1;
 			}
 			return 0;
 
 		case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
 			if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
-				dbg("invalid report_count %d", parser->global.report_count);
+				dbg_hid("invalid report_count %d\n", parser->global.report_count);
 				return -1;
 			}
 			return 0;
 
 		case HID_GLOBAL_ITEM_TAG_REPORT_ID:
 			if ((parser->global.report_id = item_udata(item)) == 0) {
-				dbg("report_id 0 is invalid");
+				dbg_hid("report_id 0 is invalid\n");
 				return -1;
 			}
 			return 0;
 
 		default:
-			dbg("unknown global tag 0x%x", item->tag);
+			dbg_hid("unknown global tag 0x%x\n", item->tag);
 			return -1;
 	}
 }
@@ -377,7 +384,7 @@
 	unsigned n;
 
 	if (item->size == 0) {
-		dbg("item data expected for local item");
+		dbg_hid("item data expected for local item\n");
 		return -1;
 	}
 
@@ -395,14 +402,14 @@
 				 * items and the first delimiter set.
 				 */
 				if (parser->local.delimiter_depth != 0) {
-					dbg("nested delimiters");
+					dbg_hid("nested delimiters\n");
 					return -1;
 				}
 				parser->local.delimiter_depth++;
 				parser->local.delimiter_branch++;
 			} else {
 				if (parser->local.delimiter_depth < 1) {
-					dbg("bogus close delimiter");
+					dbg_hid("bogus close delimiter\n");
 					return -1;
 				}
 				parser->local.delimiter_depth--;
@@ -412,7 +419,7 @@
 		case HID_LOCAL_ITEM_TAG_USAGE:
 
 			if (parser->local.delimiter_branch > 1) {
-				dbg("alternative usage ignored");
+				dbg_hid("alternative usage ignored\n");
 				return 0;
 			}
 
@@ -424,7 +431,7 @@
 		case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
 
 			if (parser->local.delimiter_branch > 1) {
-				dbg("alternative usage ignored");
+				dbg_hid("alternative usage ignored\n");
 				return 0;
 			}
 
@@ -437,7 +444,7 @@
 		case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
 
 			if (parser->local.delimiter_branch > 1) {
-				dbg("alternative usage ignored");
+				dbg_hid("alternative usage ignored\n");
 				return 0;
 			}
 
@@ -446,14 +453,14 @@
 
 			for (n = parser->local.usage_minimum; n <= data; n++)
 				if (hid_add_usage(parser, n)) {
-					dbg("hid_add_usage failed\n");
+					dbg_hid("hid_add_usage failed\n");
 					return -1;
 				}
 			return 0;
 
 		default:
 
-			dbg("unknown local item tag 0x%x", item->tag);
+			dbg_hid("unknown local item tag 0x%x\n", item->tag);
 			return 0;
 	}
 	return 0;
@@ -487,7 +494,7 @@
 			ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
 			break;
 		default:
-			dbg("unknown main item tag 0x%x", item->tag);
+			dbg_hid("unknown main item tag 0x%x\n", item->tag);
 			ret = 0;
 	}
 
@@ -502,7 +509,7 @@
 
 static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
 {
-	dbg("reserved item type, tag 0x%x", item->tag);
+	dbg_hid("reserved item type, tag 0x%x\n", item->tag);
 	return 0;
 }
 
@@ -667,14 +674,14 @@
 	while ((start = fetch_item(start, end, &item)) != NULL) {
 
 		if (item.format != HID_ITEM_FORMAT_SHORT) {
-			dbg("unexpected long global item");
+			dbg_hid("unexpected long global item\n");
 			hid_free_device(device);
 			vfree(parser);
 			return NULL;
 		}
 
 		if (dispatch_type[item.type](parser, &item)) {
-			dbg("item %u %u %u %u parsing failed\n",
+			dbg_hid("item %u %u %u %u parsing failed\n",
 				item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
 			hid_free_device(device);
 			vfree(parser);
@@ -683,13 +690,13 @@
 
 		if (start == end) {
 			if (parser->collection_stack_ptr) {
-				dbg("unbalanced collection at end of report description");
+				dbg_hid("unbalanced collection at end of report description\n");
 				hid_free_device(device);
 				vfree(parser);
 				return NULL;
 			}
 			if (parser->local.delimiter_depth) {
-				dbg("unbalanced delimiter at end of report description");
+				dbg_hid("unbalanced delimiter at end of report description\n");
 				hid_free_device(device);
 				vfree(parser);
 				return NULL;
@@ -699,7 +706,7 @@
 		}
 	}
 
-	dbg("item fetching failed at offset %d\n", (int)(end - start));
+	dbg_hid("item fetching failed at offset %d\n", (int)(end - start));
 	hid_free_device(device);
 	vfree(parser);
 	return NULL;
@@ -915,13 +922,13 @@
 	hid_dump_input(field->usage + offset, value);
 
 	if (offset >= field->report_count) {
-		dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count);
+		dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
 		hid_dump_field(field, 8);
 		return -1;
 	}
 	if (field->logical_minimum < 0) {
 		if (value != snto32(s32ton(value, size), size)) {
-			dbg("value %d is out of range", value);
+			dbg_hid("value %d is out of range\n", value);
 			return -1;
 		}
 	}
@@ -934,19 +941,17 @@
 {
 	struct hid_report_enum *report_enum = hid->report_enum + type;
 	struct hid_report *report;
-	int n, rsize;
+	int n, rsize, i;
 
 	if (!hid)
 		return -ENODEV;
 
 	if (!size) {
-		dbg("empty report");
+		dbg_hid("empty report\n");
 		return -1;
 	}
 
-#ifdef CONFIG_HID_DEBUG
-	printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
-#endif
+	dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
 
 	n = 0;                          /* Normally report number is 0 */
 	if (report_enum->numbered) {    /* Device uses numbered reports, data[0] is report number */
@@ -954,25 +959,21 @@
 		size--;
 	}
 
-#ifdef CONFIG_HID_DEBUG
-	{
-		int i;
-		printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size);
-		for (i = 0; i < size; i++)
-			printk(" %02x", data[i]);
-		printk("\n");
-	}
-#endif
+	/* dump the report descriptor */
+	dbg_hid("report %d (size %u) = ", n, size);
+	for (i = 0; i < size; i++)
+		dbg_hid_line(" %02x", data[i]);
+	dbg_hid_line("\n");
 
 	if (!(report = report_enum->report_id_hash[n])) {
-		dbg("undefined report_id %d received", n);
+		dbg_hid("undefined report_id %d received\n", n);
 		return -1;
 	}
 
 	rsize = ((report->size - 1) >> 3) + 1;
 
 	if (size < rsize) {
-		dbg("report %d is too short, (%d < %d)", report->id, size, rsize);
+		dbg_hid("report %d is too short, (%d < %d)\n", report->id, size, rsize);
 		memset(data + size, 0, rsize - size);
 	}