]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branches 'upstream', 'upstream-fixes' and 'debugfs' into for-linus
authorJiri Kosina <jkosina@suse.cz>
Sun, 13 Sep 2009 18:09:41 +0000 (20:09 +0200)
committerJiri Kosina <jkosina@suse.cz>
Sun, 13 Sep 2009 18:09:41 +0000 (20:09 +0200)
36 files changed:
drivers/hid/Kconfig
drivers/hid/Makefile
drivers/hid/hid-a4tech.c
drivers/hid/hid-apple.c
drivers/hid/hid-belkin.c
drivers/hid/hid-cherry.c
drivers/hid/hid-chicony.c
drivers/hid/hid-core.c
drivers/hid/hid-cypress.c
drivers/hid/hid-debug.c
drivers/hid/hid-ezkey.c
drivers/hid/hid-gyration.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hid-kensington.c
drivers/hid/hid-kye.c
drivers/hid/hid-lg.c
drivers/hid/hid-lgff.c
drivers/hid/hid-microsoft.c
drivers/hid/hid-monterey.c
drivers/hid/hid-ntrig.c
drivers/hid/hid-petalynx.c
drivers/hid/hid-pl.c
drivers/hid/hid-samsung.c
drivers/hid/hid-sjoy.c
drivers/hid/hid-sony.c
drivers/hid/hid-sunplus.c
drivers/hid/hid-tmff.c
drivers/hid/hid-topseed.c
drivers/hid/hid-twinhan.c [new file with mode: 0644]
drivers/hid/hid-wacom.c
drivers/hid/hid-zpff.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hiddev.c
include/linux/hid-debug.h
include/linux/hid.h

index 7831a0318d3ca5bad508d0a74d884c5013eabced..111afbe8de038e949cab63cdf936c63bc4002381 100644 (file)
@@ -31,21 +31,6 @@ config HID
 
          If unsure, say Y.
 
-config HID_DEBUG
-       bool "HID debugging support"
-       default y
-       depends on HID
-       ---help---
-       This option lets the HID layer output diagnostics about its internal
-       state, resolve HID usages, dump HID fields, etc. Individual HID drivers
-       use this debugging facility to output information about individual HID
-       devices, etc.
-
-       This feature is useful for those who are either debugging the HID parser
-       or any HID hardware device.
-
-       If unsure, say Y.
-
 config HIDRAW
        bool "/dev/hidraw raw HID device support"
        depends on HID
@@ -152,6 +137,13 @@ config HID_GYRATION
        ---help---
        Support for Gyration remote control.
 
+config HID_TWINHAN
+       tristate "Twinhan" if EMBEDDED
+       depends on USB_HID
+       default !EMBEDDED
+       ---help---
+       Support for Twinhan IR remote control.
+
 config HID_KENSINGTON
        tristate "Kensington" if EMBEDDED
        depends on USB_HID
@@ -176,6 +168,7 @@ config LOGITECH_FF
          - Logitech WingMan Cordless RumblePad 2
          - Logitech WingMan Force 3D
          - Logitech Formula Force EX
+         - Logitech WingMan Formula Force GP
          - Logitech MOMO Force wheel
 
          and if you want to enable force feedback for them.
@@ -314,9 +307,9 @@ config THRUSTMASTER_FF
        depends on HID_THRUSTMASTER
        select INPUT_FF_MEMLESS
        ---help---
-         Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
-         a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel and
-         want to enable force feedback support for it.
+         Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3,
+         a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT
+         Rumble Force or Force Feedback Wheel.
 
 config HID_WACOM
        tristate "Wacom Bluetooth devices support" if EMBEDDED
index db35151673b17f25f453bb7cf2b7018eb580b4dd..0de2dff5542c9c59255f546fa8b2b512d9312c9e 100644 (file)
@@ -3,9 +3,12 @@
 #
 hid-objs                       := hid-core.o hid-input.o
 
+ifdef CONFIG_DEBUG_FS
+       hid-objs                += hid-debug.o
+endif
+
 obj-$(CONFIG_HID)              += hid.o
 
-hid-$(CONFIG_HID_DEBUG)                += hid-debug.o
 hid-$(CONFIG_HIDRAW)           += hidraw.o
 
 hid-logitech-objs              := hid-lg.o
@@ -40,6 +43,7 @@ obj-$(CONFIG_HID_SUNPLUS)     += hid-sunplus.o
 obj-$(CONFIG_HID_GREENASIA)    += hid-gaff.o
 obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
 obj-$(CONFIG_HID_TOPSEED)      += hid-topseed.o
+obj-$(CONFIG_HID_TWINHAN)      += hid-twinhan.o
 obj-$(CONFIG_HID_ZEROPLUS)     += hid-zpff.o
 obj-$(CONFIG_HID_WACOM)                += hid-wacom.o
 
index 42ea359e94cffcb4b2fe626664fc9e671e870848..df474c699fb8007603c884a2e06f4b4540a20ed6 100644 (file)
@@ -145,12 +145,12 @@ static struct hid_driver a4_driver = {
        .remove = a4_remove,
 };
 
-static int a4_init(void)
+static int __init a4_init(void)
 {
        return hid_register_driver(&a4_driver);
 }
 
-static void a4_exit(void)
+static void __exit a4_exit(void)
 {
        hid_unregister_driver(&a4_driver);
 }
index 303ccce05bb3b4c44cacb0d349ac1ccbfb3812b9..4b96e7a898cfea7224007a87af7817c3d66528fa 100644 (file)
@@ -451,7 +451,7 @@ static struct hid_driver apple_driver = {
        .input_mapped = apple_input_mapped,
 };
 
-static int apple_init(void)
+static int __init apple_init(void)
 {
        int ret;
 
@@ -462,7 +462,7 @@ static int apple_init(void)
        return ret;
 }
 
-static void apple_exit(void)
+static void __exit apple_exit(void)
 {
        hid_unregister_driver(&apple_driver);
 }
index 2f6723133a4b7d4eb45f50b45ea50185493f8c8c..4ce7aa3a519f9ccc52d7b1cdcfe3df8f8d16bce1 100644 (file)
@@ -88,12 +88,12 @@ static struct hid_driver belkin_driver = {
        .probe = belkin_probe,
 };
 
-static int belkin_init(void)
+static int __init belkin_init(void)
 {
        return hid_register_driver(&belkin_driver);
 }
 
-static void belkin_exit(void)
+static void __exit belkin_exit(void)
 {
        hid_unregister_driver(&belkin_driver);
 }
index ab8209e7e45ca41fe691d97cd24bc8011db2179e..7e597d7f770fedb35284ef5a3d827cf01872559f 100644 (file)
@@ -70,12 +70,12 @@ static struct hid_driver ch_driver = {
        .input_mapping = ch_input_mapping,
 };
 
-static int ch_init(void)
+static int __init ch_init(void)
 {
        return hid_register_driver(&ch_driver);
 }
 
-static void ch_exit(void)
+static void __exit ch_exit(void)
 {
        hid_unregister_driver(&ch_driver);
 }
index 7f91076d8493ae5b653f01f6814028cab391b357..8965ad93d51003c47fd3ac570b897f6ee065de03 100644 (file)
@@ -63,12 +63,12 @@ static struct hid_driver ch_driver = {
        .input_mapping = ch_input_mapping,
 };
 
-static int ch_init(void)
+static int __init ch_init(void)
 {
        return hid_register_driver(&ch_driver);
 }
 
-static void ch_exit(void)
+static void __exit ch_exit(void)
 {
        hid_unregister_driver(&ch_driver);
 }
index 047844df992a91ac997bf092048e1a12ede9a40e..342b7d36d7bbb91d57f33d04f7c00f61dca2ca0b 100644 (file)
 #define DRIVER_DESC "HID core driver"
 #define DRIVER_LICENSE "GPL"
 
-#ifdef CONFIG_HID_DEBUG
 int hid_debug = 0;
 module_param_named(debug, hid_debug, int, 0600);
-MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data dumping)");
+MODULE_PARM_DESC(debug, "toggle HID debugging messages");
 EXPORT_SYMBOL_GPL(hid_debug);
-#endif
 
 /*
  * Register a new report for a device.
@@ -861,7 +859,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field,
        struct hid_driver *hdrv = hid->driver;
        int ret;
 
-       hid_dump_input(usage, value);
+       hid_dump_input(hid, usage, value);
 
        if (hdrv && hdrv->event && hid_match_usage(hid, usage)) {
                ret = hdrv->event(hid, field, usage, value);
@@ -983,11 +981,10 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
 {
        unsigned size = field->report_size;
 
-       hid_dump_input(field->usage + offset, value);
+       hid_dump_input(field->report->device, field->usage + offset, value);
 
        if (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) {
@@ -1078,6 +1075,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
        struct hid_report_enum *report_enum;
        struct hid_driver *hdrv;
        struct hid_report *report;
+       char *buf;
        unsigned int i;
        int ret;
 
@@ -1091,18 +1089,38 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
                return -1;
        }
 
-       dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
+       buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE,
+                       interrupt ? GFP_ATOMIC : GFP_KERNEL);
+
+       if (!buf) {
+               report = hid_get_report(report_enum, data);
+               goto nomem;
+       }
+
+       snprintf(buf, HID_DEBUG_BUFSIZE - 1,
+                       "\nreport (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
+       hid_debug_event(hid, buf);
 
        report = hid_get_report(report_enum, data);
-       if (!report)
+       if (!report) {
+               kfree(buf);
                return -1;
+       }
 
        /* dump the report */
-       dbg_hid("report %d (size %u) = ", report->id, size);
-       for (i = 0; i < size; i++)
-               dbg_hid_line(" %02x", data[i]);
-       dbg_hid_line("\n");
+       snprintf(buf, HID_DEBUG_BUFSIZE - 1,
+                       "report %d (size %u) = ", report->id, size);
+       hid_debug_event(hid, buf);
+       for (i = 0; i < size; i++) {
+               snprintf(buf, HID_DEBUG_BUFSIZE - 1,
+                               " %02x", data[i]);
+               hid_debug_event(hid, buf);
+       }
+       hid_debug_event(hid, "\n");
+
+       kfree(buf);
 
+nomem:
        if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
                ret = hdrv->raw_event(hid, report, data, size);
                if (ret != 0)
@@ -1292,6 +1310,7 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
@@ -1311,9 +1330,12 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
@@ -1621,12 +1643,8 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
@@ -1693,6 +1711,11 @@ static bool hid_ignore(struct hid_device *hdev)
                                hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST)
                        return true;
                break;
+       case USB_VENDOR_ID_SOUNDGRAPH:
+               if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
+                   hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST)
+                       return true;
+               break;
        }
 
        if (hdev->type == HID_TYPE_USBMOUSE &&
@@ -1724,6 +1747,8 @@ int hid_add_device(struct hid_device *hdev)
        if (!ret)
                hdev->status |= HID_STAT_ADDED;
 
+       hid_debug_register(hdev, dev_name(&hdev->dev));
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(hid_add_device);
@@ -1760,6 +1785,9 @@ struct hid_device *hid_allocate_device(void)
        for (i = 0; i < HID_REPORT_TYPES; i++)
                INIT_LIST_HEAD(&hdev->report_enum[i].report_list);
 
+       init_waitqueue_head(&hdev->debug_wait);
+       INIT_LIST_HEAD(&hdev->debug_list);
+
        return hdev;
 err:
        put_device(&hdev->dev);
@@ -1771,6 +1799,7 @@ static void hid_remove_device(struct hid_device *hdev)
 {
        if (hdev->status & HID_STAT_ADDED) {
                device_del(&hdev->dev);
+               hid_debug_unregister(hdev);
                hdev->status &= ~HID_STAT_ADDED;
        }
 }
@@ -1846,6 +1875,10 @@ static int __init hid_init(void)
 {
        int ret;
 
+       if (hid_debug)
+               printk(KERN_WARNING "HID: hid_debug is now used solely for parser and driver debugging.\n"
+                               "HID: debugfs is now used for inspecting the device (report descriptor, reports)\n");
+
        ret = bus_register(&hid_bus_type);
        if (ret) {
                printk(KERN_ERR "HID: can't register hid bus\n");
@@ -1856,6 +1889,8 @@ static int __init hid_init(void)
        if (ret)
                goto err_bus;
 
+       hid_debug_init();
+
        return 0;
 err_bus:
        bus_unregister(&hid_bus_type);
@@ -1865,6 +1900,7 @@ err:
 
 static void __exit hid_exit(void)
 {
+       hid_debug_exit();
        hidraw_exit();
        bus_unregister(&hid_bus_type);
 }
index 9d6d3b91773bbbcbed9858c8e73b89627277aae9..62e9cb10e88cffe7d9310bf6d839fb81ed114378 100644 (file)
@@ -141,12 +141,12 @@ static struct hid_driver cp_driver = {
        .probe = cp_probe,
 };
 
-static int cp_init(void)
+static int __init cp_init(void)
 {
        return hid_register_driver(&cp_driver);
 }
 
-static void cp_exit(void)
+static void __exit cp_exit(void)
 {
        hid_unregister_driver(&cp_driver);
 }
index 04359ed64b8763b70553d052d9386c907329c193..6abd0369aedba0125f935dc357f292d5e6850017 100644 (file)
@@ -1,9 +1,9 @@
 /*
  *  (c) 1999 Andreas Gal               <gal@cs.uni-magdeburg.de>
  *  (c) 2000-2001 Vojtech Pavlik       <vojtech@ucw.cz>
- *  (c) 2007 Jiri Kosina
+ *  (c) 2007-2009 Jiri Kosina
  *
- *  Some debug stuff for the HID parser.
+ *  HID debugging support
  */
 
 /*
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+
 #include <linux/hid.h>
 #include <linux/hid-debug.h>
 
+static struct dentry *hid_debug_root;
+
 struct hid_usage_entry {
        unsigned  page;
        unsigned  usage;
@@ -339,72 +347,120 @@ static const struct hid_usage_entry hid_usage_table[] = {
   { 0, 0, NULL }
 };
 
-static void resolv_usage_page(unsigned page) {
+/* Either output directly into simple seq_file, or (if f == NULL)
+ * allocate a separate buffer that will then be passed to the 'events'
+ * ringbuffer.
+ *
+ * This is because these functions can be called both for "one-shot"
+ * "rdesc" while resolving, or for blocking "events".
+ *
+ * This holds both for resolv_usage_page() and hid_resolv_usage().
+ */
+static char *resolv_usage_page(unsigned page, struct seq_file *f) {
        const struct hid_usage_entry *p;
+       char *buf = NULL;
+
+       if (!f) {
+               buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
+               if (!buf)
+                       return ERR_PTR(-ENOMEM);
+       }
 
        for (p = hid_usage_table; p->description; p++)
                if (p->page == page) {
-                       printk("%s", p->description);
-                       return;
+                       if (!f) {
+                               snprintf(buf, HID_DEBUG_BUFSIZE, "%s",
+                                               p->description);
+                               return buf;
+                       }
+                       else {
+                               seq_printf(f, "%s", p->description);
+                               return NULL;
+                       }
                }
-       printk("%04x", page);
+       if (!f)
+               snprintf(buf, HID_DEBUG_BUFSIZE, "%04x", page);
+       else
+               seq_printf(f, "%04x", page);
+       return buf;
 }
 
-void hid_resolv_usage(unsigned usage) {
+char *hid_resolv_usage(unsigned usage, struct seq_file *f) {
        const struct hid_usage_entry *p;
+       char *buf = NULL;
+       int len = 0;
+
+       buf = resolv_usage_page(usage >> 16, f);
+       if (IS_ERR(buf)) {
+               printk(KERN_ERR "error allocating HID debug buffer\n");
+               return NULL;
+       }
 
-       if (!hid_debug)
-               return;
 
-       resolv_usage_page(usage >> 16);
-       printk(".");
+       if (!f) {
+               len = strlen(buf);
+               snprintf(buf+len, max(0, HID_DEBUG_BUFSIZE - len), ".");
+               len++;
+       }
+       else {
+               seq_printf(f, ".");
+       }
        for (p = hid_usage_table; p->description; p++)
                if (p->page == (usage >> 16)) {
                        for(++p; p->description && p->usage != 0; p++)
                                if (p->usage == (usage & 0xffff)) {
-                                       printk("%s", p->description);
-                                       return;
+                                       if (!f)
+                                               snprintf(buf + len,
+                                                       max(0,HID_DEBUG_BUFSIZE - len - 1),
+                                                       "%s", p->description);
+                                       else
+                                               seq_printf(f,
+                                                       "%s",
+                                                       p->description);
+                                       return buf;
                                }
                        break;
                }
-       printk("%04x", usage & 0xffff);
+       if (!f)
+               snprintf(buf + len, max(0, HID_DEBUG_BUFSIZE - len - 1),
+                               "%04x", usage & 0xffff);
+       else
+               seq_printf(f, "%04x", usage & 0xffff);
+       return buf;
 }
 EXPORT_SYMBOL_GPL(hid_resolv_usage);
 
-static void tab(int n) {
-       printk(KERN_DEBUG "%*s", n, "");
+static void tab(int n, struct seq_file *f) {
+       seq_printf(f, "%*s", n, "");
 }
 
-void hid_dump_field(struct hid_field *field, int n) {
+void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
        int j;
 
-       if (!hid_debug)
-               return;
-
        if (field->physical) {
-               tab(n);
-               printk("Physical(");
-               hid_resolv_usage(field->physical); printk(")\n");
+               tab(n, f);
+               seq_printf(f, "Physical(");
+               hid_resolv_usage(field->physical, f); seq_printf(f, ")\n");
        }
        if (field->logical) {
-               tab(n);
-               printk("Logical(");
-               hid_resolv_usage(field->logical); printk(")\n");
+               tab(n, f);
+               seq_printf(f, "Logical(");
+               hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
        }
-       tab(n); printk("Usage(%d)\n", field->maxusage);
+       tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
        for (j = 0; j < field->maxusage; j++) {
-               tab(n+2); hid_resolv_usage(field->usage[j].hid); printk("\n");
+               tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
        }
        if (field->logical_minimum != field->logical_maximum) {
-               tab(n); printk("Logical Minimum(%d)\n", field->logical_minimum);
-               tab(n); printk("Logical Maximum(%d)\n", field->logical_maximum);
+               tab(n, f); seq_printf(f, "Logical Minimum(%d)\n", field->logical_minimum);
+               tab(n, f); seq_printf(f, "Logical Maximum(%d)\n", field->logical_maximum);
        }
        if (field->physical_minimum != field->physical_maximum) {
-               tab(n); printk("Physical Minimum(%d)\n", field->physical_minimum);
-               tab(n); printk("Physical Maximum(%d)\n", field->physical_maximum);
+               tab(n, f); seq_printf(f, "Physical Minimum(%d)\n", field->physical_minimum);
+               tab(n, f); seq_printf(f, "Physical Maximum(%d)\n", field->physical_maximum);
        }
        if (field->unit_exponent) {
-               tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent);
+               tab(n, f); seq_printf(f, "Unit Exponent(%d)\n", field->unit_exponent);
        }
        if (field->unit) {
                static const char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
@@ -425,77 +481,75 @@ void hid_dump_field(struct hid_field *field, int n) {
                data >>= 4;
 
                if(sys > 4) {
-                       tab(n); printk("Unit(Invalid)\n");
+                       tab(n, f); seq_printf(f, "Unit(Invalid)\n");
                }
                else {
                        int earlier_unit = 0;
 
-                       tab(n); printk("Unit(%s : ", systems[sys]);
+                       tab(n, f); seq_printf(f, "Unit(%s : ", systems[sys]);
 
                        for (i=1 ; i<sizeof(__u32)*2 ; i++) {
                                char nibble = data & 0xf;
                                data >>= 4;
                                if (nibble != 0) {
                                        if(earlier_unit++ > 0)
-                                               printk("*");
-                                       printk("%s", units[sys][i]);
+                                               seq_printf(f, "*");
+                                       seq_printf(f, "%s", units[sys][i]);
                                        if(nibble != 1) {
                                                /* This is a _signed_ nibble(!) */
 
                                                int val = nibble & 0x7;
                                                if(nibble & 0x08)
                                                        val = -((0x7 & ~val) +1);
-                                               printk("^%d", val);
+                                               seq_printf(f, "^%d", val);
                                        }
                                }
                        }
-                       printk(")\n");
+                       seq_printf(f, ")\n");
                }
        }
-       tab(n); printk("Report Size(%u)\n", field->report_size);
-       tab(n); printk("Report Count(%u)\n", field->report_count);
-       tab(n); printk("Report Offset(%u)\n", field->report_offset);
+       tab(n, f); seq_printf(f, "Report Size(%u)\n", field->report_size);
+       tab(n, f); seq_printf(f, "Report Count(%u)\n", field->report_count);
+       tab(n, f); seq_printf(f, "Report Offset(%u)\n", field->report_offset);
 
-       tab(n); printk("Flags( ");
+       tab(n, f); seq_printf(f, "Flags( ");
        j = field->flags;
-       printk("%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
-       printk("%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
-       printk("%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
-       printk("%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
-       printk("%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
-       printk("%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : "");
-       printk("%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
-       printk("%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
-       printk("%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
-       printk(")\n");
+       seq_printf(f, "%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
+       seq_printf(f, "%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
+       seq_printf(f, "%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
+       seq_printf(f, "%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
+       seq_printf(f, "%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
+       seq_printf(f, "%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : "");
+       seq_printf(f, "%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
+       seq_printf(f, "%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
+       seq_printf(f, "%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
+       seq_printf(f, ")\n");
 }
 EXPORT_SYMBOL_GPL(hid_dump_field);
 
-void hid_dump_device(struct hid_device *device) {
+void hid_dump_device(struct hid_device *device, struct seq_file *f)
+{
        struct hid_report_enum *report_enum;
        struct hid_report *report;
        struct list_head *list;
        unsigned i,k;
        static const 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;
                while (list != &report_enum->report_list) {
                        report = (struct hid_report *) list;
-                       tab(2);
-                       printk("%s", table[i]);
+                       tab(2, f);
+                       seq_printf(f, "%s", table[i]);
                        if (report->id)
-                               printk("(%d)", report->id);
-                       printk("[%s]", table[report->type]);
-                       printk("\n");
+                               seq_printf(f, "(%d)", report->id);
+                       seq_printf(f, "[%s]", table[report->type]);
+                       seq_printf(f, "\n");
                        for (k = 0; k < report->maxfield; k++) {
-                               tab(4);
-                               printk("Field(%d)\n", k);
-                               hid_dump_field(report->field[k], 6);
+                               tab(4, f);
+                               seq_printf(f, "Field(%d)\n", k);
+                               hid_dump_field(report->field[k], 6, f);
                        }
                        list = list->next;
                }
@@ -503,13 +557,37 @@ 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 < 2)
+/* enqueue string to 'events' ring buffer */
+void hid_debug_event(struct hid_device *hdev, char *buf)
+{
+       int i;
+       struct hid_debug_list *list;
+
+       list_for_each_entry(list, &hdev->debug_list, node) {
+               for (i = 0; i <= strlen(buf); i++)
+                       list->hid_debug_buf[(list->tail + i) % (HID_DEBUG_BUFSIZE - 1)] =
+                               buf[i];
+               list->tail = (list->tail + i) % (HID_DEBUG_BUFSIZE - 1);
+        }
+}
+EXPORT_SYMBOL_GPL(hid_debug_event);
+
+void hid_dump_input(struct hid_device *hdev, struct hid_usage *usage, __s32 value)
+{
+       char *buf;
+       int len;
+
+       buf = hid_resolv_usage(usage->hid, NULL);
+       if (!buf)
                return;
+       len = strlen(buf);
+       snprintf(buf + len, HID_DEBUG_BUFSIZE - len - 1, " = %d\n", value);
+
+       hid_debug_event(hdev, buf);
+
+       kfree(buf);
+        wake_up_interruptible(&hdev->debug_wait);
 
-       printk(KERN_DEBUG "hid-debug: input ");
-       hid_resolv_usage(usage->hid);
-       printk(" = %d\n", value);
 }
 EXPORT_SYMBOL_GPL(hid_dump_input);
 
@@ -786,12 +864,221 @@ static const char **names[EV_MAX + 1] = {
        [EV_SND] = sounds,                      [EV_REP] = repeats,
 };
 
-void hid_resolv_event(__u8 type, __u16 code) {
+void hid_resolv_event(__u8 type, __u16 code, struct seq_file *f) {
 
-       if (!hid_debug)
-               return;
-
-       printk("%s.%s", events[type] ? events[type] : "?",
+       seq_printf(f, "%s.%s", events[type] ? events[type] : "?",
                names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
 }
-EXPORT_SYMBOL_GPL(hid_resolv_event);
+
+void hid_dump_input_mapping(struct hid_device *hid, struct seq_file *f)
+{
+       int i, j, k;
+       struct hid_report *report;
+       struct hid_usage *usage;
+
+       for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
+               list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
+                       for (i = 0; i < report->maxfield; i++) {
+                               for ( j = 0; j < report->field[i]->maxusage; j++) {
+                                       usage = report->field[i]->usage + j;
+                                       hid_resolv_usage(usage->hid, f);
+                                       seq_printf(f, " ---> ");
+                                       hid_resolv_event(usage->type, usage->code, f);
+                                       seq_printf(f, "\n");
+                               }
+                       }
+               }
+       }
+
+}
+
+
+static int hid_debug_rdesc_show(struct seq_file *f, void *p)
+{
+       struct hid_device *hdev = f->private;
+       int i;
+
+       /* dump HID report descriptor */
+       for (i = 0; i < hdev->rsize; i++)
+               seq_printf(f, "%02x ", hdev->rdesc[i]);
+       seq_printf(f, "\n\n");
+
+       /* dump parsed data and input mappings */
+       hid_dump_device(hdev, f);
+       seq_printf(f, "\n");
+       hid_dump_input_mapping(hdev, f);
+
+       return 0;
+}
+
+static int hid_debug_rdesc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, hid_debug_rdesc_show, inode->i_private);
+}
+
+static int hid_debug_events_open(struct inode *inode, struct file *file)
+{
+       int err = 0;
+       struct hid_debug_list *list;
+
+       if (!(list = kzalloc(sizeof(struct hid_debug_list), GFP_KERNEL))) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       if (!(list->hid_debug_buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_KERNEL))) {
+               err = -ENOMEM;
+               kfree(list);
+               goto out;
+       }
+       list->hdev = (struct hid_device *) inode->i_private;
+       file->private_data = list;
+       mutex_init(&list->read_mutex);
+
+       list_add_tail(&list->node, &list->hdev->debug_list);
+
+out:
+       return err;
+}
+
+static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
+               size_t count, loff_t *ppos)
+{
+       struct hid_debug_list *list = file->private_data;
+       int ret = 0, len;
+       DECLARE_WAITQUEUE(wait, current);
+
+       while (ret == 0) {
+               mutex_lock(&list->read_mutex);
+               if (list->head == list->tail) {
+                       add_wait_queue(&list->hdev->debug_wait, &wait);
+                       set_current_state(TASK_INTERRUPTIBLE);
+
+                       while (list->head == list->tail) {
+                               if (file->f_flags & O_NONBLOCK) {
+                                       ret = -EAGAIN;
+                                       break;
+                               }
+                               if (signal_pending(current)) {
+                                       ret = -ERESTARTSYS;
+                                       break;
+                               }
+
+                               if (!list->hdev || !list->hdev->debug) {
+                                       ret = -EIO;
+                                       break;
+                               }
+
+                               /* allow O_NONBLOCK from other threads */
+                               mutex_unlock(&list->read_mutex);
+                               schedule();
+                               mutex_lock(&list->read_mutex);
+                               set_current_state(TASK_INTERRUPTIBLE);
+                       }
+
+                       set_current_state(TASK_RUNNING);
+                       remove_wait_queue(&list->hdev->debug_wait, &wait);
+               }
+
+               if (ret)
+                       goto out;
+
+               /* pass the ringbuffer contents to userspace */
+copy_rest:
+               if (list->tail == list->head)
+                       goto out;
+               if (list->tail > list->head) {
+                       len = list->tail - list->head;
+
+                       if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
+                               ret = -EFAULT;
+                               goto out;
+                       }
+                       ret += len;
+                       list->head += len;
+               } else {
+                       len = HID_DEBUG_BUFSIZE - list->head;
+
+                       if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
+                               ret = -EFAULT;
+                               goto out;
+                       }
+                       list->head = 0;
+                       ret += len;
+                       goto copy_rest;
+               }
+
+       }
+out:
+       mutex_unlock(&list->read_mutex);
+       return ret;
+}
+
+static unsigned int hid_debug_events_poll(struct file *file, poll_table *wait)
+{
+       struct hid_debug_list *list = file->private_data;
+
+       poll_wait(file, &list->hdev->debug_wait, wait);
+       if (list->head != list->tail)
+               return POLLIN | POLLRDNORM;
+       if (!list->hdev->debug)
+               return POLLERR | POLLHUP;
+       return 0;
+}
+
+static int hid_debug_events_release(struct inode *inode, struct file *file)
+{
+       struct hid_debug_list *list = file->private_data;
+
+       list_del(&list->node);
+       kfree(list->hid_debug_buf);
+       kfree(list);
+
+       return 0;
+}
+
+static const struct file_operations hid_debug_rdesc_fops = {
+       .open           = hid_debug_rdesc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static const struct file_operations hid_debug_events_fops = {
+       .owner =        THIS_MODULE,
+       .open           = hid_debug_events_open,
+       .read           = hid_debug_events_read,
+       .poll           = hid_debug_events_poll,
+       .release        = hid_debug_events_release,
+};
+
+
+void hid_debug_register(struct hid_device *hdev, const char *name)
+{
+       hdev->debug_dir = debugfs_create_dir(name, hid_debug_root);
+       hdev->debug_rdesc = debugfs_create_file("rdesc", 0400,
+                       hdev->debug_dir, hdev, &hid_debug_rdesc_fops);
+       hdev->debug_events = debugfs_create_file("events", 0400,
+                       hdev->debug_dir, hdev, &hid_debug_events_fops);
+       hdev->debug = 1;
+}
+
+void hid_debug_unregister(struct hid_device *hdev)
+{
+       hdev->debug = 0;
+       wake_up_interruptible(&hdev->debug_wait);
+       debugfs_remove(hdev->debug_rdesc);
+       debugfs_remove(hdev->debug_events);
+       debugfs_remove(hdev->debug_dir);
+}
+
+void hid_debug_init(void)
+{
+       hid_debug_root = debugfs_create_dir("hid", NULL);
+}
+
+void hid_debug_exit(void)
+{
+       debugfs_remove_recursive(hid_debug_root);
+}
+
index 0a1fe054799ba2899efb74ab8dbb984be13609f9..ca1163e9d42d68a09d186265328eccbd122468f4 100644 (file)
@@ -78,12 +78,12 @@ static struct hid_driver ez_driver = {
        .event = ez_event,
 };
 
-static int ez_init(void)
+static int __init ez_init(void)
 {
        return hid_register_driver(&ez_driver);
 }
 
-static void ez_exit(void)
+static void __exit ez_exit(void)
 {
        hid_unregister_driver(&ez_driver);
 }
index d42d222097a80e7cfa049165676b0283c19ac3f7..cab13e8c7d292c7ed93a06b8a58acc6072d50fd3 100644 (file)
@@ -81,12 +81,12 @@ static struct hid_driver gyration_driver = {
        .event = gyration_event,
 };
 
-static int gyration_init(void)
+static int __init gyration_init(void)
 {
        return hid_register_driver(&gyration_driver);
 }
 
-static void gyration_exit(void)
+static void __exit gyration_exit(void)
 {
        hid_unregister_driver(&gyration_driver);
 }
index 6301010379215ca35eb07ea07c2be124e6fb50e6..adbef5d069c4adf3678f5001079c3d9099d7035a 100644 (file)
 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D     0xc283
 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO     0xc286
 #define USB_DEVICE_ID_LOGITECH_WHEEL   0xc294
+#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG     0xc293
 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL      0xc295
 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL       0xc299
 #define USB_DEVICE_ID_LOGITECH_ELITE_KBD       0xc30a
 #define USB_VENDOR_ID_PETALYNX         0x18b1
 #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE   0x0037
 
+#define USB_VENDOR_ID_PHILIPS       0x0471
+#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
+
 #define USB_VENDOR_ID_PLAYDOTCOM       0x0b43
 #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII     0x0003
 
 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER      0x0268
 
 #define USB_VENDOR_ID_SOUNDGRAPH       0x15c2
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD      0x0038
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2     0x0036
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3     0x0034
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4     0x0044
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5     0x0045
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST    0x0034
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST     0x0046
 
 #define USB_VENDOR_ID_SUN              0x0430
 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE       0xcdab
 #define USB_VENDOR_ID_TURBOX           0x062a
 #define USB_DEVICE_ID_TURBOX_KEYBOARD  0x0201
 
+#define USB_VENDOR_ID_TWINHAN           0x6253
+#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
+
 #define USB_VENDOR_ID_UCLOGIC          0x5543
 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209    0x0042
 
index 7f183b7147e119b9ac1ea0e98d8c81bce662aaf3..5862b0f3b55d1de24413744cde877ca33031212a 100644 (file)
@@ -159,17 +159,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
        field->hidinput = hidinput;
 
-       dbg_hid("Mapping: ");
-       hid_resolv_usage(usage->hid);
-       dbg_hid_line(" ---> ");
-
        if (field->flags & HID_MAIN_ITEM_CONSTANT)
                goto ignore;
 
        /* only LED usages are supported in output fields */
        if (field->report_type == HID_OUTPUT_REPORT &&
                        (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
-               dbg_hid_line(" [non-LED output field] ");
                goto ignore;
        }
 
@@ -561,15 +556,9 @@ mapped:
                set_bit(MSC_SCAN, input->mscbit);
        }
 
-       hid_resolv_event(usage->type, usage->code);
-
-       dbg_hid_line("\n");
-
-       return;
-
 ignore:
-       dbg_hid_line("IGNORED\n");
        return;
+
 }
 
 void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
index 7353bd79cbe9b525ab90475b30222ffb7b24e729..a5b4016e9bd7b54d34543048d9d7344bbb66704d 100644 (file)
@@ -48,12 +48,12 @@ static struct hid_driver ks_driver = {
        .input_mapping = ks_input_mapping,
 };
 
-static int ks_init(void)
+static int __init ks_init(void)
 {
        return hid_register_driver(&ks_driver);
 }
 
-static void ks_exit(void)
+static void __exit ks_exit(void)
 {
        hid_unregister_driver(&ks_driver);
 }
index 72ee3fec56d9b887a45b83ceb405febfbf8baa8f..f8871712b7b53cbbe4e5dac5c7b651691a38c99d 100644 (file)
@@ -54,12 +54,12 @@ static struct hid_driver kye_driver = {
        .report_fixup = kye_report_fixup,
 };
 
-static int kye_init(void)
+static int __init kye_init(void)
 {
        return hid_register_driver(&kye_driver);
 }
 
-static void kye_exit(void)
+static void __exit kye_exit(void)
 {
        hid_unregister_driver(&kye_driver);
 }
index 7afbaa0efd1812fedeeaeea934467138c5efb417..0f870a3243ed1ef2a9870c4a32c63b7519975c03 100644 (file)
@@ -299,6 +299,8 @@ static const struct hid_device_id lg_devices[] = {
                .driver_data = LG_FF },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
                .driver_data = LG_FF },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
+               .driver_data = LG_FF },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
                .driver_data = LG_FF2 },
        { }
@@ -315,12 +317,12 @@ static struct hid_driver lg_driver = {
        .probe = lg_probe,
 };
 
-static int lg_init(void)
+static int __init lg_init(void)
 {
        return hid_register_driver(&lg_driver);
 }
 
-static void lg_exit(void)
+static void __exit lg_exit(void)
 {
        hid_unregister_driver(&lg_driver);
 }
index 56099709581cc689ec88210672ca30a7982cf833..987abebe08296a4f37770e2164e623012d4cac95 100644 (file)
@@ -67,6 +67,7 @@ static const struct dev_type devices[] = {
        { 0x046d, 0xc219, ff_rumble },
        { 0x046d, 0xc283, ff_joystick },
        { 0x046d, 0xc286, ff_joystick_ac },
+       { 0x046d, 0xc293, ff_joystick },
        { 0x046d, 0xc294, ff_wheel },
        { 0x046d, 0xc295, ff_joystick },
        { 0x046d, 0xca03, ff_wheel },
@@ -150,11 +151,6 @@ int lgff_init(struct hid_device* hid)
 
        /* Check that the report looks ok */
        report = list_entry(report_list->next, struct hid_report, list);
-       if (!report) {
-               err_hid("NULL output report");
-               return -1;
-       }
-
        field = report->field[0];
        if (!field) {
                err_hid("NULL field");
index 5e9e37a0506dd96adc8164855fdfac69c7e6fd1e..359cc447c6c600d61387e5b8cc6679dc1d4d6b75 100644 (file)
@@ -197,12 +197,12 @@ static struct hid_driver ms_driver = {
        .probe = ms_probe,
 };
 
-static int ms_init(void)
+static int __init ms_init(void)
 {
        return hid_register_driver(&ms_driver);
 }
 
-static void ms_exit(void)
+static void __exit ms_exit(void)
 {
        hid_unregister_driver(&ms_driver);
 }
index 240f87618be6edef76b34b14f87b890da82d16db..2cd05aa244b9cfb78739bb1c0f7c5da71f43f0ff 100644 (file)
@@ -65,12 +65,12 @@ static struct hid_driver mr_driver = {
        .input_mapping = mr_input_mapping,
 };
 
-static int mr_init(void)
+static int __init mr_init(void)
 {
        return hid_register_driver(&mr_driver);
 }
 
-static void mr_exit(void)
+static void __exit mr_exit(void)
 {
        hid_unregister_driver(&mr_driver);
 }
index 75ed9d2c1a36a563dc36b29515d6acb1ba7478b9..49ce69d7bba754ee37e62ec386ab48385879b52a 100644 (file)
@@ -27,6 +27,9 @@
 struct ntrig_data {
        __s32 x, y, id, w, h;
        char reading_a_point, found_contact_id;
+       char pen_active;
+       char finger_active;
+       char inverted;
 };
 
 /*
@@ -63,10 +66,7 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
        case HID_UP_DIGITIZER:
                switch (usage->hid) {
                /* we do not want to map these for now */
-               case HID_DG_INVERT: /* value is always 0 */
-               case HID_DG_ERASER: /* value is always 0 */
                case HID_DG_CONTACTID: /* value is useless */
-               case HID_DG_BARRELSWITCH:  /* doubtful */
                case HID_DG_INPUTMODE:
                case HID_DG_DEVICEINDEX:
                case HID_DG_CONTACTCOUNT:
@@ -125,6 +125,18 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 
         if (hid->claimed & HID_CLAIMED_INPUT) {
                switch (usage->hid) {
+
+               case HID_DG_INRANGE:
+                       if (field->application & 0x3)
+                               nd->pen_active = (value != 0);
+                       else
+                               nd->finger_active = (value != 0);
+                       return 0;
+
+               case HID_DG_INVERT:
+                       nd->inverted = value;
+                       return 0;
+
                case HID_GD_X:
                        nd->x = value;
                        nd->reading_a_point = 1;
@@ -147,7 +159,11 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
                         * report received in a finger event. We want
                         * to emit a normal (X, Y) position
                         */
-                       if (! nd->found_contact_id) {
+                       if (!nd->found_contact_id) {
+                               if (nd->pen_active && nd->finger_active) {
+                                       input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
+                                       input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
+                               }
                                input_event(input, EV_ABS, ABS_X, nd->x);
                                input_event(input, EV_ABS, ABS_Y, nd->y);
                        }
@@ -159,6 +175,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
                         * to emit a normal (X, Y) position
                         */
                        if (! nd->found_contact_id) {
+                               if (nd->pen_active && nd->finger_active) {
+                                       input_report_key(input,
+                                                       nd->inverted ? BTN_TOOL_RUBBER : BTN_TOOL_PEN
+                                                       , 0);
+                                       input_report_key(input,
+                                                       nd->inverted ? BTN_TOOL_RUBBER : BTN_TOOL_PEN
+                                                       , 1);
+                               }
                                input_event(input, EV_ABS, ABS_X, nd->x);
                                input_event(input, EV_ABS, ABS_Y, nd->y);
                                input_event(input, EV_ABS, ABS_PRESSURE, value);
@@ -233,6 +257,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
        if (ret)
                kfree (nd);
+
        return ret;
 }
 
@@ -265,12 +290,12 @@ static struct hid_driver ntrig_driver = {
        .event = ntrig_event,
 };
 
-static int ntrig_init(void)
+static int __init ntrig_init(void)
 {
        return hid_register_driver(&ntrig_driver);
 }
 
-static void ntrig_exit(void)
+static void __exit ntrig_exit(void)
 {
        hid_unregister_driver(&ntrig_driver);
 }
index 2e83e8ff891a47aff5086e89b9b37c5d1767af6b..500fbd0652dc4be5354743dab0961aef43cf6989 100644 (file)
@@ -105,12 +105,12 @@ static struct hid_driver pl_driver = {
        .probe = pl_probe,
 };
 
-static int pl_init(void)
+static int __init pl_init(void)
 {
        return hid_register_driver(&pl_driver);
 }
 
-static void pl_exit(void)
+static void __exit pl_exit(void)
 {
        hid_unregister_driver(&pl_driver);
 }
index 4db9a3483760f6ade53829076198f105161e1cd4..c6d7dbc935b18b2f7445f948f2a6f5f0f0132fab 100644 (file)
@@ -217,12 +217,12 @@ static struct hid_driver pl_driver = {
        .probe = pl_probe,
 };
 
-static int pl_init(void)
+static int __init pl_init(void)
 {
        return hid_register_driver(&pl_driver);
 }
 
-static void pl_exit(void)
+static void __exit pl_exit(void)
 {
        hid_unregister_driver(&pl_driver);
 }
index 07083aa6c19ae615a81338c77855d143162df113..5b222eed06929806f76b3896a0b23ae471120d25 100644 (file)
 /*
  * Samsung IrDA remote controller (reports as Cypress USB Mouse).
  *
+ * There are several variants for 0419:0001:
+ *
+ * 1. 184 byte report descriptor
  * Vendor specific report #4 has a size of 48 bit,
  * and therefore is not accepted when inspecting the descriptors.
  * As a workaround we reinterpret the report as:
  *   Variable type, count 6, size 8 bit, log. maximum 255
  * The burden to reconstruct the data is moved into user space.
+ *
+ * 2. 203 byte report descriptor
+ * Report #4 has an array field with logical range 0..18 instead of 1..15.
+ *
+ * 3. 135 byte report descriptor
+ * Report #4 has an array field with logical range 0..17 instead of 1..14.
  */
 static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
                unsigned int rsize)
 {
-       if (rsize >= 182 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
+       if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
                        rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
                        rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
                        rdesc[182] == 0x40) {
-               dev_info(&hdev->dev, "fixing up Samsung IrDA report "
-                               "descriptor\n");
+               dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
+                               "descriptor\n", 184);
                rdesc[176] = 0xff;
                rdesc[178] = 0x08;
                rdesc[180] = 0x06;
                rdesc[182] = 0x42;
+       } else
+       if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
+                       rdesc[194] == 0x25 && rdesc[195] == 0x12) {
+               dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
+                               "descriptor\n", 203);
+               rdesc[193] = 0x1;
+               rdesc[195] = 0xf;
+       } else
+       if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
+                       rdesc[126] == 0x25 && rdesc[127] == 0x11) {
+               dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
+                               "descriptor\n", 135);
+               rdesc[125] = 0x1;
+               rdesc[127] = 0xe;
        }
 }
 
@@ -51,6 +74,7 @@ static int samsung_probe(struct hid_device *hdev,
                const struct hid_device_id *id)
 {
        int ret;
+       unsigned int cmask = HID_CONNECT_DEFAULT;
 
        ret = hid_parse(hdev);
        if (ret) {
@@ -58,8 +82,13 @@ static int samsung_probe(struct hid_device *hdev,
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) |
-                       HID_CONNECT_HIDDEV_FORCE);
+       if (hdev->rsize == 184) {
+               /* disable hidinput, force hiddev */
+               cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
+                       HID_CONNECT_HIDDEV_FORCE;
+       }
+
+       ret = hid_hw_start(hdev, cmask);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
@@ -83,12 +112,12 @@ static struct hid_driver samsung_driver = {
        .probe = samsung_probe,
 };
 
-static int samsung_init(void)
+static int __init samsung_init(void)
 {
        return hid_register_driver(&samsung_driver);
 }
 
-static void samsung_exit(void)
+static void __exit samsung_exit(void)
 {
        hid_unregister_driver(&samsung_driver);
 }
index eab169e5c3719c139181f6e498cce6394224b151..203c438b016f38bd099df7f675a839438118f881 100644 (file)
@@ -163,12 +163,12 @@ static struct hid_driver sjoy_driver = {
        .probe = sjoy_probe,
 };
 
-static int sjoy_init(void)
+static int __init sjoy_init(void)
 {
        return hid_register_driver(&sjoy_driver);
 }
 
-static void sjoy_exit(void)
+static void __exit sjoy_exit(void)
 {
        hid_unregister_driver(&sjoy_driver);
 }
index c2599388a3504ce4df3bb110f976dfab47581cf5..4e8450228a24f8e097dd7c7f073815f5873b7c1c 100644 (file)
@@ -135,12 +135,12 @@ static struct hid_driver sony_driver = {
        .report_fixup = sony_report_fixup,
 };
 
-static int sony_init(void)
+static int __init sony_init(void)
 {
        return hid_register_driver(&sony_driver);
 }
 
-static void sony_exit(void)
+static void __exit sony_exit(void)
 {
        hid_unregister_driver(&sony_driver);
 }
index e0a8fd36a85b70e174d4763ea50e9d709bb456fd..438107d9f1b2a3b5d11be27c2f9e1deca5690108 100644 (file)
@@ -65,12 +65,12 @@ static struct hid_driver sp_driver = {
        .input_mapping = sp_input_mapping,
 };
 
-static int sp_init(void)
+static int __init sp_init(void)
 {
        return hid_register_driver(&sp_driver);
 }
 
-static void sp_exit(void)
+static void __exit sp_exit(void)
 {
        hid_unregister_driver(&sp_driver);
 }
index fcd6ccd02fee28fb77d9775f962c38cdec516754..167ea746fb9c3e5d5faa7f5cbae033baa77bfad8 100644 (file)
@@ -243,7 +243,11 @@ err:
 static const struct hid_device_id tm_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300),
                .driver_data = (unsigned long)ff_rumble },
-       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304),
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304),   /* FireStorm Dual Power 2 (and 3) */
+               .driver_data = (unsigned long)ff_rumble },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323),   /* Dual Trigger 3-in-1 (PC Mode) */
+               .driver_data = (unsigned long)ff_rumble },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324),   /* Dual Trigger 3-in-1 (PS3 Mode) */
                .driver_data = (unsigned long)ff_rumble },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651),   /* FGT Rumble Force Wheel */
                .driver_data = (unsigned long)ff_rumble },
@@ -259,12 +263,12 @@ static struct hid_driver tm_driver = {
        .probe = tm_probe,
 };
 
-static int tm_init(void)
+static int __init tm_init(void)
 {
        return hid_register_driver(&tm_driver);
 }
 
-static void tm_exit(void)
+static void __exit tm_exit(void)
 {
        hid_unregister_driver(&tm_driver);
 }
index 152ccfabeba5cf59d523d59feeac2e0abde04f4a..6925eda1081a81755eb271dc38e2d1ca27deb991 100644 (file)
@@ -60,12 +60,12 @@ static struct hid_driver ts_driver = {
        .input_mapping = ts_input_mapping,
 };
 
-static int ts_init(void)
+static int __init ts_init(void)
 {
        return hid_register_driver(&ts_driver);
 }
 
-static void ts_exit(void)
+static void __exit ts_exit(void)
 {
        hid_unregister_driver(&ts_driver);
 }
diff --git a/drivers/hid/hid-twinhan.c b/drivers/hid/hid-twinhan.c
new file mode 100644 (file)
index 0000000..b05f602
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * HID driver for TwinHan IR remote control
+ *
+ * Based on hid-gyration.c
+ *
+ * Copyright (c) 2009 Bruno PrĂ©mont <bonbons@linux-vserver.org>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/*     Remote control key layout + listing:
+ *
+ *     Full Screen                              Power
+ *     KEY_SCREEN                          KEY_POWER2
+ *
+ *     1                     2                      3
+ *     KEY_NUMERIC_1   KEY_NUMERIC_2    KEY_NUMERIC_3
+ *
+ *     4                     5                      6
+ *     KEY_NUMERIC_4   KEY_NUMERIC_5    KEY_NUMERIC_6
+ *
+ *     7                     8                      9
+ *     KEY_NUMERIC_7   KEY_NUMERIC_8    KEY_NUMERIC_9
+ *
+ *     REC                   0               Favorite
+ *     KEY_RECORD      KEY_NUMERIC_0    KEY_FAVORITES
+ *
+ *     Rewind                                 Forward
+ *     KEY_REWIND           CH+           KEY_FORWARD
+ *                    KEY_CHANNELUP
+ *
+ *     VOL-                  >                   VOL+
+ *     KEY_VOLUMEDOWN    KEY_PLAY        KEY_VOLUMEUP
+ *
+ *                          CH-
+ *                   KEY_CHANNELDOWN
+ *     Recall                                    Stop
+ *     KEY_RESTART                           KEY_STOP
+ *
+ *     Timeshift/Pause     Mute                Cancel
+ *     KEY_PAUSE         KEY_MUTE          KEY_CANCEL
+ *
+ *     Capture            Preview                 EPG
+ *     KEY_PRINT        KEY_PROGRAM           KEY_EPG
+ *
+ *     Record List          Tab              Teletext
+ *     KEY_LIST            KEY_TAB           KEY_TEXT
+ */
+
+#define th_map_key_clear(c)    hid_map_usage_clear(hi, usage, bit, max, \
+                                       EV_KEY, (c))
+static int twinhan_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+               struct hid_field *field, struct hid_usage *usage,
+               unsigned long **bit, int *max)
+{
+       if ((usage->hid & HID_USAGE_PAGE) != HID_UP_KEYBOARD)
+               return 0;
+
+       switch (usage->hid & HID_USAGE) {
+       /* Map all keys from Twinhan Remote */
+       case 0x004: th_map_key_clear(KEY_TEXT);         break;
+       case 0x006: th_map_key_clear(KEY_RESTART);      break;
+       case 0x008: th_map_key_clear(KEY_EPG);          break;
+       case 0x00c: th_map_key_clear(KEY_REWIND);       break;
+       case 0x00e: th_map_key_clear(KEY_PROGRAM);      break;
+       case 0x00f: th_map_key_clear(KEY_LIST);         break;
+       case 0x010: th_map_key_clear(KEY_MUTE);         break;
+       case 0x011: th_map_key_clear(KEY_FORWARD);      break;
+       case 0x013: th_map_key_clear(KEY_PRINT);        break;
+       case 0x017: th_map_key_clear(KEY_PAUSE);        break;
+       case 0x019: th_map_key_clear(KEY_FAVORITES);    break;
+       case 0x01d: th_map_key_clear(KEY_SCREEN);       break;
+       case 0x01e: th_map_key_clear(KEY_NUMERIC_1);    break;
+       case 0x01f: th_map_key_clear(KEY_NUMERIC_2);    break;
+       case 0x020: th_map_key_clear(KEY_NUMERIC_3);    break;
+       case 0x021: th_map_key_clear(KEY_NUMERIC_4);    break;
+       case 0x022: th_map_key_clear(KEY_NUMERIC_5);    break;
+       case 0x023: th_map_key_clear(KEY_NUMERIC_6);    break;
+       case 0x024: th_map_key_clear(KEY_NUMERIC_7);    break;
+       case 0x025: th_map_key_clear(KEY_NUMERIC_8);    break;
+       case 0x026: th_map_key_clear(KEY_NUMERIC_9);    break;
+       case 0x027: th_map_key_clear(KEY_NUMERIC_0);    break;
+       case 0x028: th_map_key_clear(KEY_PLAY);         break;
+       case 0x029: th_map_key_clear(KEY_CANCEL);       break;
+       case 0x02b: th_map_key_clear(KEY_TAB);          break;
+       /* Power       = 0x0e0 + 0x0e1 + 0x0e2 + 0x03f */
+       case 0x03f: th_map_key_clear(KEY_POWER2);       break;
+       case 0x04a: th_map_key_clear(KEY_RECORD);       break;
+       case 0x04b: th_map_key_clear(KEY_CHANNELUP);    break;
+       case 0x04d: th_map_key_clear(KEY_STOP);         break;
+       case 0x04e: th_map_key_clear(KEY_CHANNELDOWN);  break;
+       /* Volume down = 0x0e1 + 0x051                 */
+       case 0x051: th_map_key_clear(KEY_VOLUMEDOWN);   break;
+       /* Volume up   = 0x0e1 + 0x052                 */
+       case 0x052: th_map_key_clear(KEY_VOLUMEUP);     break;
+       /* Kill the extra keys used for multi-key "power" and "volume" keys
+        * as well as continuously to release CTRL,ALT,META,... keys */
+       case 0x0e0:
+       case 0x0e1:
+       case 0x0e2:
+       case 0x0e3:
+       case 0x0e4:
+       case 0x0e5:
+       case 0x0e6:
+       case 0x0e7:
+       default:
+               return -1;
+       }
+       return 1;
+}
+
+static const struct hid_device_id twinhan_devices[] = {
+       { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
+       { }
+};
+MODULE_DEVICE_TABLE(hid, twinhan_devices);
+
+static struct hid_driver twinhan_driver = {
+       .name = "twinhan",
+       .id_table = twinhan_devices,
+       .input_mapping = twinhan_input_mapping,
+};
+
+static int twinhan_init(void)
+{
+       return hid_register_driver(&twinhan_driver);
+}
+
+static void twinhan_exit(void)
+{
+       hid_unregister_driver(&twinhan_driver);
+}
+
+module_init(twinhan_init);
+module_exit(twinhan_exit);
+MODULE_LICENSE("GPL");
index 1f9237f511e394f2ca44530ed8e4c189abe94303..7475421722428bac0015bc3335190fbbf931abde 100644 (file)
@@ -237,7 +237,7 @@ static struct hid_driver wacom_driver = {
        .raw_event = wacom_raw_event,
 };
 
-static int wacom_init(void)
+static int __init wacom_init(void)
 {
        int ret;
 
@@ -248,7 +248,7 @@ static int wacom_init(void)
        return ret;
 }
 
-static void wacom_exit(void)
+static void __exit wacom_exit(void)
 {
        hid_unregister_driver(&wacom_driver);
 }
index 57f710757bf425ac6b32fb49314121357e327b41..a79f0d78c6be23944e70b3d0f35f23f069ea1980 100644 (file)
@@ -152,12 +152,12 @@ static struct hid_driver zp_driver = {
        .probe = zp_probe,
 };
 
-static int zp_init(void)
+static int __init zp_init(void)
 {
        return hid_register_driver(&zp_driver);
 }
 
-static void zp_exit(void)
+static void __exit zp_exit(void)
 {
        hid_unregister_driver(&zp_driver);
 }
index 3c1fcb7640abe1458d52146f8456c16295ec531f..1b0e07a67d6d079c26848f42b28ce6835bdb6014 100644 (file)
@@ -4,8 +4,8 @@
  *  Copyright (c) 1999 Andreas Gal
  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- *  Copyright (c) 2006-2008 Jiri Kosina
  *  Copyright (c) 2007-2008 Oliver Neukum
+ *  Copyright (c) 2006-2009 Jiri Kosina
  */
 
 /*
@@ -489,7 +489,8 @@ static void hid_ctrl(struct urb *urb)
        wake_up(&usbhid->wait);
 }
 
-void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report,
+                                  unsigned char dir)
 {
        int head;
        struct usbhid_device *usbhid = hid->driver_data;
@@ -885,11 +886,6 @@ static int usbhid_parse(struct hid_device *hid)
                goto err;
        }
 
-       dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
-       for (n = 0; n < rsize; n++)
-               dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
-       dbg_hid_line("\n");
-
        ret = hid_parse_report(hid, rdesc, rsize);
        kfree(rdesc);
        if (ret) {
@@ -985,7 +981,6 @@ static int usbhid_start(struct hid_device *hid)
        INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
        setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
 
-       spin_lock_init(&usbhid->lock);
        spin_lock_init(&usbhid->lock);
 
        usbhid->intf = intf;
@@ -1004,7 +999,6 @@ static int usbhid_start(struct hid_device *hid)
        usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
        usbhid_init_reports(hid);
-       hid_dump_device(hid);
 
        set_bit(HID_STARTED, &usbhid->iofl);
 
index 215b2addddbb7c5be5e765dcbe0fd771146129db..4d1dc0cf1401eef835d06977299e8be2998e6e52 100644 (file)
@@ -44,7 +44,7 @@
 #define HIDDEV_MINOR_BASE      96
 #define HIDDEV_MINORS          16
 #endif
-#define HIDDEV_BUFFER_SIZE     64
+#define HIDDEV_BUFFER_SIZE     2048
 
 struct hiddev {
        int exist;
index 50d568ec178a67aa1dd6937935a249b354589125..53744fa1c8b7af4aac65c057a09518a5fec70f05 100644 (file)
@@ -2,7 +2,7 @@
 #define __HID_DEBUG_H
 
 /*
- *  Copyright (c) 2007 Jiri Kosina
+ *  Copyright (c) 2007-2009    Jiri Kosina
  */
 
 /*
  *
  */
 
-#ifdef CONFIG_HID_DEBUG
+#define HID_DEBUG_BUFSIZE 512
 
-void hid_dump_input(struct hid_usage *, __s32);
-void hid_dump_device(struct hid_device *);
-void hid_dump_field(struct hid_field *, int);
-void hid_resolv_usage(unsigned);
-void hid_resolv_event(__u8, __u16);
+#ifdef CONFIG_DEBUG_FS
+
+void hid_dump_input(struct hid_device *, struct hid_usage *, __s32);
+void hid_dump_device(struct hid_device *, struct seq_file *);
+void hid_dump_field(struct hid_field *, int, struct seq_file *);
+char *hid_resolv_usage(unsigned, struct seq_file *);
+void hid_debug_register(struct hid_device *, const char *);
+void hid_debug_unregister(struct hid_device *);
+void hid_debug_init(void);
+void hid_debug_exit(void);
+void hid_debug_event(struct hid_device *, char *);
 
-#else
 
-#define hid_dump_input(a,b)     do { } while (0)
-#define hid_dump_device(c)      do { } while (0)
-#define hid_dump_field(a,b)     do { } while (0)
-#define hid_resolv_usage(a)         do { } while (0)
-#define hid_resolv_event(a,b)       do { } while (0)
+struct hid_debug_list {
+       char *hid_debug_buf;
+       int head;
+       int tail;
+       struct fasync_struct *fasync;
+       struct hid_device *hdev;
+       struct list_head node;
+       struct mutex read_mutex;
+};
 
-#endif /* CONFIG_HID_DEBUG */
+#else
 
+#define hid_dump_input(a,b,c)          do { } while (0)
+#define hid_dump_device(a,b)           do { } while (0)
+#define hid_dump_field(a,b,c)          do { } while (0)
+#define hid_resolv_usage(a,b)          do { } while (0)
+#define hid_debug_register(a, b)       do { } while (0)
+#define hid_debug_unregister(a)                do { } while (0)
+#define hid_debug_init()               do { } while (0)
+#define hid_debug_exit()               do { } while (0)
+#define hid_debug_event(a,b)           do { } while (0)
+
+#endif
 
 #endif
 
index 53489fd4d7006e35e6fe7bc95a50a0a956aee8dd..a0ebdace7baa2fa496d2d8fc09cf1a2c0b6f1b60 100644 (file)
@@ -500,6 +500,14 @@ struct hid_device {                                                        /* device report descriptor */
 
        /* handler for raw output data, used by hidraw */
        int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
+
+       /* debugging support via debugfs */
+       unsigned short debug;
+       struct dentry *debug_dir;
+       struct dentry *debug_rdesc;
+       struct dentry *debug_events;
+       struct list_head debug_list;
+       wait_queue_head_t debug_wait;
 };
 
 static inline void *hid_get_drvdata(struct hid_device *hdev)
@@ -657,9 +665,7 @@ struct hid_ll_driver {
 
 /* HID core API */
 
-#ifdef CONFIG_HID_DEBUG
 extern int hid_debug;
-#endif
 
 extern int hid_add_device(struct hid_device *);
 extern void hid_destroy_device(struct hid_device *);
@@ -815,21 +821,9 @@ int hid_pidff_init(struct hid_device *hid);
 #define hid_pidff_init NULL
 #endif
 
-#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
-static inline int __attribute__((format(printf, 1, 2)))
-dbg_hid(const char *fmt, ...)
-{
-       return 0;
-}
-#define dbg_hid_line dbg_hid
-#endif /* HID_DEBUG */
-
 #define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
                __FILE__ , ## arg)
 #endif /* HID_FF */