Commit 58037eb9 authored by Jiri Kosina's avatar Jiri Kosina

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: default avatarJiri Kosina <jkosina@suse.cz>
parent 7dcca30a
......@@ -24,6 +24,7 @@ config HID
config HID_DEBUG
bool "HID debugging support"
default y if !EMBEDDED
depends on HID
---help---
This option lets the HID layer output diagnostics about its internal
......
This diff is collapsed.
......@@ -347,6 +347,9 @@ static void resolv_usage_page(unsigned page) {
void hid_resolv_usage(unsigned usage) {
const struct hid_usage_entry *p;
if (!hid_debug)
return;
resolv_usage_page(usage >> 16);
printk(".");
for (p = hid_usage_table; p->description; p++)
......@@ -369,6 +372,9 @@ __inline__ static void tab(int n) {
void hid_dump_field(struct hid_field *field, int n) {
int j;
if (!hid_debug)
return;
if (field->physical) {
tab(n);
printk("Physical(");
......@@ -466,6 +472,9 @@ void hid_dump_device(struct hid_device *device) {
unsigned i,k;
static char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
if (!hid_debug)
return;
for (i = 0; i < HID_REPORT_TYPES; i++) {
report_enum = device->report_enum + i;
list = report_enum->report_list.next;
......@@ -489,6 +498,9 @@ void hid_dump_device(struct hid_device *device) {
EXPORT_SYMBOL_GPL(hid_dump_device);
void hid_dump_input(struct hid_usage *usage, __s32 value) {
if (!hid_debug)
return;
printk("hid-debug: input ");
hid_resolv_usage(usage->hid);
printk(" = %d\n", value);
......@@ -758,6 +770,9 @@ static char **names[EV_MAX + 1] = {
void hid_resolv_event(__u8 type, __u16 code) {
if (!hid_debug)
return;
printk("%s.%s", events[type] ? events[type] : "?",
names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
}
......
......@@ -308,9 +308,7 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode,
clear_bit(old_keycode, dev->keybit);
set_bit(usage->code, dev->keybit);
#ifdef CONFIG_HID_DEBUG
printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
#endif
dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
/* Set the keybit for the old keycode if the old keycode is used
* by another key */
if (hidinput_find_key (hid, 0, old_keycode))
......@@ -333,11 +331,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
field->hidinput = hidinput;
#ifdef CONFIG_HID_DEBUG
printk(KERN_DEBUG "Mapping: ");
dbg_hid("Mapping: ");
hid_resolv_usage(usage->hid);
printk(" ---> ");
#endif
dbg_hid_line(" ---> ");
if (field->flags & HID_MAIN_ITEM_CONSTANT)
goto ignore;
......@@ -819,15 +815,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
}
hid_resolv_event(usage->type, usage->code);
#ifdef CONFIG_HID_DEBUG
printk("\n");
#endif
dbg_hid_line("\n");
return;
ignore:
#ifdef CONFIG_HID_DEBUG
printk("IGNORED\n");
#endif
dbg_hid_line("IGNORED\n");
return;
}
......@@ -896,12 +890,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
}
if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
dbg("Maximum Effects - %d",value);
dbg_hid("Maximum Effects - %d\n",value);
return;
}
if (usage->hid == (HID_UP_PID | 0x7fUL)) {
dbg("PID Pool Report\n");
dbg_hid("PID Pool Report\n");
return;
}
......@@ -994,7 +988,7 @@ int hidinput_connect(struct hid_device *hid)
if (!hidinput || !input_dev) {
kfree(hidinput);
input_free_device(input_dev);
err("Out of memory during hid input probe");
err_hid("Out of memory during hid input probe");
return -1;
}
......
......@@ -127,7 +127,7 @@ static void hid_reset(struct work_struct *work)
hid_io_error(hid);
break;
default:
err("can't reset device, %s-%s/input%d, status %d",
err_hid("can't reset device, %s-%s/input%d, status %d",
hid_to_usb_dev(hid)->bus->bus_name,
hid_to_usb_dev(hid)->devpath,
usbhid->ifnum, rc);
......@@ -220,7 +220,7 @@ static void hid_irq_in(struct urb *urb)
if (status) {
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
if (status != -EPERM) {
err("can't resubmit intr, %s-%s/input%d, status %d",
err_hid("can't resubmit intr, %s-%s/input%d, status %d",
hid_to_usb_dev(hid)->bus->bus_name,
hid_to_usb_dev(hid)->devpath,
usbhid->ifnum, status);
......@@ -240,10 +240,10 @@ static int hid_submit_out(struct hid_device *hid)
usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
usbhid->urbout->dev = hid_to_usb_dev(hid);
dbg("submitting out urb");
dbg_hid("submitting out urb\n");
if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
err("usb_submit_urb(out) failed");
err_hid("usb_submit_urb(out) failed");
return -1;
}
......@@ -287,12 +287,12 @@ static int hid_submit_ctrl(struct hid_device *hid)
usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
usbhid->cr->wLength = cpu_to_le16(len);
dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u",
dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
err("usb_submit_urb(ctrl) failed");
err_hid("usb_submit_urb(ctrl) failed");
return -1;
}
......@@ -474,7 +474,7 @@ int usbhid_wait_io(struct hid_device *hid)
if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
!test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
10*HZ)) {
dbg("timeout waiting for ctrl or out queue to clear");
dbg_hid("timeout waiting for ctrl or out queue to clear\n");
return -1;
}
......@@ -667,7 +667,7 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum)
USB_CTRL_GET_TIMEOUT);
if (result < 0)
err("%s failed: %d\n", __func__, result);
err_hid("%s failed: %d\n", __func__, result);
kfree(buf);
}
......@@ -746,7 +746,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
(!interface->desc.bNumEndpoints ||
usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
dbg("class descriptor not present\n");
dbg_hid("class descriptor not present\n");
return NULL;
}
......@@ -755,19 +755,19 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
dbg("weird size of report descriptor (%u)", rsize);
dbg_hid("weird size of report descriptor (%u)\n", rsize);
return NULL;
}
if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
dbg("couldn't allocate rdesc memory");
dbg_hid("couldn't allocate rdesc memory\n");
return NULL;
}
hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
dbg("reading report descriptor failed");
dbg_hid("reading report descriptor failed\n");
kfree(rdesc);
return NULL;
}
......@@ -781,15 +781,13 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if (quirks & HID_QUIRK_SWAPPED_MIN_MAX)
hid_fixup_cypress_descriptor(rdesc, rsize);
#ifdef CONFIG_HID_DEBUG
printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
for (n = 0; n < rsize; n++)
printk(" %02x", (unsigned char) rdesc[n]);
printk("\n");
#endif
dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
dbg_hid_line("\n");
if (!(hid = hid_parse_report(rdesc, n))) {
dbg("parsing report descriptor failed");
dbg_hid("parsing report descriptor failed\n");
kfree(rdesc);
return NULL;
}
......@@ -861,7 +859,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
}
if (!usbhid->urbin) {
err("couldn't find an input interrupt endpoint");
err_hid("couldn't find an input interrupt endpoint");
goto fail;
}
......@@ -978,7 +976,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
int i;
char *c;
dbg("HID probe called for ifnum %d",
dbg_hid("HID probe called for ifnum %d\n",
intf->altsetting->desc.bInterfaceNumber);
if (!(hid = usb_hid_configure(intf)))
......
......@@ -78,7 +78,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
report->field[0]->value[1] = 0x08;
report->field[0]->value[2] = x;
report->field[0]->value[3] = y;
dbg("(x, y)=(%04x, %04x)", x, y);
dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
usbhid_submit_report(hid, report, USB_DIR_OUT);
break;
......@@ -93,7 +93,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
report->field[0]->value[1] = 0x00;
report->field[0]->value[2] = left;
report->field[0]->value[3] = right;
dbg("(left, right)=(%04x, %04x)", left, right);
dbg_hid("(left, right)=(%04x, %04x)\n", left, right);
usbhid_submit_report(hid, report, USB_DIR_OUT);
break;
}
......@@ -113,20 +113,20 @@ int hid_lgff_init(struct hid_device* hid)
/* Find the report to use */
if (list_empty(report_list)) {
err("No output report found");
err_hid("No output report found");
return -1;
}
/* Check that the report looks ok */
report = list_entry(report_list->next, struct hid_report, list);
if (!report) {
err("NULL output report");
err_hid("NULL output report");
return -1;
}
field = report->field[0];
if (!field) {
err("NULL field");
err_hid("NULL field");
return -1;
}
......
......@@ -493,7 +493,7 @@ static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor,
}
if (bl_entry != NULL)
dbg("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
bl_entry->quirks, bl_entry->idVendor,
bl_entry->idProduct);
......@@ -521,13 +521,13 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
int list_edited = 0;
if (!idVendor) {
dbg("Cannot add a quirk with idVendor = 0");
dbg_hid("Cannot add a quirk with idVendor = 0\n");
return -EINVAL;
}
q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL);
if (!q_new) {
dbg("Could not allocate quirks_list_struct");
dbg_hid("Could not allocate quirks_list_struct\n");
return -ENOMEM;
}
......@@ -643,7 +643,7 @@ static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
bl_entry = &hid_blacklist[n];
if (bl_entry != NULL)
dbg("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
bl_entry->quirks, bl_entry->idVendor,
bl_entry->idProduct);
return bl_entry;
......
......@@ -70,7 +70,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef
tmff->rumble->value[0] = left;
tmff->rumble->value[1] = right;
dbg("(left,right)=(%08x, %08x)", left, right);
dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
return 0;
......
......@@ -21,10 +21,6 @@
*/
/* #define DEBUG */
#define debug(format, arg...) pr_debug("hid-zpff: " format "\n" , ## arg)
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/hid.h>
......@@ -49,14 +45,14 @@ static int hid_zpff_play(struct input_dev *dev, void *data,
left = effect->u.rumble.strong_magnitude;
right = effect->u.rumble.weak_magnitude;
debug("called with 0x%04x 0x%04x", left, right);
dbg_hid("called with 0x%04x 0x%04x\n", left, right);
left = left * 0x7f / 0xffff;
right = right * 0x7f / 0xffff;
zpff->report->field[2]->value[0] = left;
zpff->report->field[3]->value[0] = right;
debug("running with 0x%02x 0x%02x", left, right);
dbg_hid("running with 0x%02x 0x%02x\n", left, right);
usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
return 0;
......
......@@ -779,7 +779,7 @@ int hiddev_connect(struct hid_device *hid)
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
err("Not able to get a minor for this device.");
err_hid("Not able to get a minor for this device.");
kfree(hiddev);
return -1;
}
......
......@@ -125,7 +125,7 @@ static void usb_kbd_irq(struct urb *urb)
resubmit:
i = usb_submit_urb (urb, GFP_ATOMIC);
if (i)
err ("can't resubmit intr, %s-%s/input0, status %d",
err_hid ("can't resubmit intr, %s-%s/input0, status %d",
kbd->usbdev->bus->bus_name,
kbd->usbdev->devpath, i);
}
......@@ -151,7 +151,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type,
*(kbd->leds) = kbd->newleds;
kbd->led->dev = kbd->usbdev;
if (usb_submit_urb(kbd->led, GFP_ATOMIC))
err("usb_submit_urb(leds) failed");
err_hid("usb_submit_urb(leds) failed");
return 0;
}
......@@ -169,7 +169,7 @@ static void usb_kbd_led(struct urb *urb)
*(kbd->leds) = kbd->newleds;
kbd->led->dev = kbd->usbdev;
if (usb_submit_urb(kbd->led, GFP_ATOMIC))
err("usb_submit_urb(leds) failed");
err_hid("usb_submit_urb(leds) failed");
}
static int usb_kbd_open(struct input_dev *dev)
......
......@@ -488,6 +488,11 @@ struct hid_descriptor {
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
/* HID core API */
#ifdef CONFIG_HID_DEBUG
extern int hid_debug;
#endif
extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
extern int hidinput_connect(struct hid_device *);
......@@ -523,14 +528,19 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
#else
static inline int hid_ff_init(struct hid_device *hid) { return -1; }
#endif
#ifdef DEBUG
#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \
__FILE__ , ## arg)
#ifdef CONFIG_HID_DEBUG
#define dbg_hid(format, arg...) if (hid_debug) \
printk(KERN_DEBUG "%s: " format ,\
__FILE__ , ## arg)
#define dbg_hid_line(format, arg...) if (hid_debug) \
printk(format, ## arg)
#else
#define dbg(format, arg...) do {} while (0)
#define dbg_hid(format, arg...) do {} while (0)
#define dbg_hid_line dbg_hid
#endif
#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
__FILE__ , ## arg)
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment