summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2009-06-26 15:27:36 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2009-06-26 15:27:36 +1000
commit8957949bda9341565f67c272b302f8eb4cf71e25 (patch)
treeca01965163c03d1492de08da552eefd98c3a11de
parent4e2b271e9a2c041059cafdcc1aaa084bb1cfcb37 (diff)
Revert "HID: use debugfs for events/reports dumping"
This reverts commit cd667ce24796700e1a0e6e7528efc61c96ff832e.
-rw-r--r--drivers/hid/hid-core.c42
-rw-r--r--drivers/hid/hid-debug.c239
-rw-r--r--include/linux/hid-debug.h18
-rw-r--r--include/linux/hid.h26
4 files changed, 49 insertions, 276 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index b8dfa43c6bb3..17190653785c 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -46,7 +46,7 @@
int hid_debug = 0;
module_param_named(debug, hid_debug, int, 0600);
-MODULE_PARM_DESC(debug, "toggle HID debugging messages");
+MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data dumping)");
EXPORT_SYMBOL_GPL(hid_debug);
/*
@@ -859,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(hid, usage, value);
+ hid_dump_input(usage, value);
if (hdrv && hdrv->event && hid_match_usage(hid, usage)) {
ret = hdrv->event(hid, field, usage, value);
@@ -981,7 +981,7 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
{
unsigned size = field->report_size;
- hid_dump_input(field->report->device, field->usage + offset, value);
+ hid_dump_input(field->usage + offset, value);
if (offset >= field->report_count) {
dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
@@ -1075,7 +1075,6 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
struct hid_report_enum *report_enum = hid->report_enum + type;
struct hid_driver *hdrv = hid->driver;
struct hid_report *report;
- char *buf;
unsigned int i;
int ret;
@@ -1087,36 +1086,18 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
return -1;
}
- 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);
+ dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
report = hid_get_report(report_enum, data);
if (!report)
return -1;
/* dump the report */
- 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);
+ 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");
-nomem:
if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
ret = hdrv->raw_event(hid, report, data, size);
if (ret != 0)
@@ -1778,9 +1759,6 @@ 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);
@@ -1869,8 +1847,8 @@ 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");
+ printk(KERN_WARNING "HID: hid_debug parameter has been deprecated. "
+ "Debugging data are now provided via debugfs\n");
ret = bus_register(&hid_bus_type);
if (ret) {
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 3e425f78ba3a..6561d7d87276 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -28,10 +28,6 @@
#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>
@@ -347,86 +343,49 @@ static const struct hid_usage_entry hid_usage_table[] = {
{ 0, 0, NULL }
};
-/* 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) {
+static void 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) {
- if (!f) {
- snprintf(buf, HID_DEBUG_BUFSIZE, "%s",
- p->description);
- return buf;
- }
- else {
+ if (!f)
+ printk("%s", p->description);
+ else
seq_printf(f, "%s", p->description);
- return NULL;
- }
+ return;
}
if (!f)
- snprintf(buf, HID_DEBUG_BUFSIZE, "%04x", page);
+ printk("%04x", page);
else
seq_printf(f, "%04x", page);
- return buf;
}
-char *hid_resolv_usage(unsigned usage, struct seq_file *f) {
+void 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 (!f) {
- len = strlen(buf);
- snprintf(buf+len, max(0, HID_DEBUG_BUFSIZE - len), ".");
- len++;
- }
- else {
+ resolv_usage_page(usage >> 16, f);
+ if (!f)
+ printk(".");
+ 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)) {
if (!f)
- snprintf(buf + len,
- max(0,HID_DEBUG_BUFSIZE - len - 1),
- "%s", p->description);
+ printk("%s", p->description);
else
seq_printf(f,
"%s",
p->description);
- return buf;
+ return;
}
break;
}
if (!f)
- snprintf(buf + len, max(0, HID_DEBUG_BUFSIZE - len - 1),
- "%04x", usage & 0xffff);
+ printk("%04x", usage & 0xffff);
else
seq_printf(f, "%04x", usage & 0xffff);
- return buf;
}
EXPORT_SYMBOL_GPL(hid_resolv_usage);
@@ -557,37 +516,13 @@ void hid_dump_device(struct hid_device *device, struct seq_file *f)
}
EXPORT_SYMBOL_GPL(hid_dump_device);
-/* 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)
+void hid_dump_input(struct hid_usage *usage, __s32 value) {
+ if (hid_debug < 2)
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, NULL);
+ printk(" = %d\n", value);
}
EXPORT_SYMBOL_GPL(hid_dump_input);
@@ -892,7 +827,6 @@ void hid_dump_input_mapping(struct hid_device *hid, struct seq_file *f)
}
-
static int hid_debug_rdesc_show(struct seq_file *f, void *p)
{
struct hid_device *hdev = f->private;
@@ -916,126 +850,6 @@ 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;
- 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,
@@ -1043,31 +857,16 @@ static const struct file_operations hid_debug_rdesc_fops = {
.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);
}
diff --git a/include/linux/hid-debug.h b/include/linux/hid-debug.h
index ec08ac1ad687..516e12c33235 100644
--- a/include/linux/hid-debug.h
+++ b/include/linux/hid-debug.h
@@ -24,27 +24,14 @@
#ifdef CONFIG_DEBUG_FS
-void hid_dump_input(struct hid_device *, struct hid_usage *, __s32);
+void hid_dump_input(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_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 *);
-
-#define HID_DEBUG_BUFSIZE 512
-
-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;
-};
#else
@@ -57,7 +44,6 @@ struct hid_debug_list {
#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
diff --git a/include/linux/hid.h b/include/linux/hid.h
index a0ebdace7baa..ca5935df9fa6 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -487,6 +487,10 @@ struct hid_device { /* device report descriptor */
char phys[64]; /* Device physical location */
char uniq[64]; /* Device unique identifier (serial #) */
+ /* debugfs */
+ struct dentry *debug_dir;
+ struct dentry *debug_rdesc;
+
void *driver_data;
/* temporary hid_ff handling (until moved to the drivers) */
@@ -500,14 +504,6 @@ 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)
@@ -665,7 +661,9 @@ 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 *);
@@ -821,9 +819,21 @@ 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 */