ACPICA: Update function header
[powerpc.git] / drivers / hid / hid-core.c
index 689ae16..49f18f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  USB HID support for Linux
+ *  HID support for Linux
  *
  *  Copyright (c) 1999 Andreas Gal
  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
@@ -31,8 +31,6 @@
 #undef DEBUG
 #undef DEBUG_DATA
 
-#include <linux/usb.h>
-
 #include <linux/hid.h>
 #include <linux/hiddev.h>
 
 
 #define DRIVER_VERSION "v2.6"
 #define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik"
-#define DRIVER_DESC "USB HID core driver"
+#define DRIVER_DESC "HID core driver"
 #define DRIVER_LICENSE "GPL"
 
-/*
- * Module parameters.
- */
-
-static unsigned int hid_mousepoll_interval;
-module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
-MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
-
 /*
  * Register a new report for a device.
  */
@@ -538,7 +528,7 @@ static void hid_free_report(struct hid_report *report)
  * Free a device structure, all reports, and all fields.
  */
 
-static void hid_free_device(struct hid_device *device)
+void hid_free_device(struct hid_device *device)
 {
        unsigned i,j;
 
@@ -553,8 +543,10 @@ static void hid_free_device(struct hid_device *device)
        }
 
        kfree(device->rdesc);
+       kfree(device->collection);
        kfree(device);
 }
+EXPORT_SYMBOL_GPL(hid_free_device);
 
 /*
  * Fetch a report description item from the data stream. We support long
@@ -629,7 +621,7 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
  * enumerated, fields are attached to these reports.
  */
 
-static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
+struct hid_device *hid_parse_report(__u8 *start, unsigned size)
 {
        struct hid_device *device;
        struct hid_parser *parser;
@@ -657,7 +649,7 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
        for (i = 0; i < HID_REPORT_TYPES; i++)
                INIT_LIST_HEAD(&device->report_enum[i].report_list);
 
-       if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) {
+       if (!(device->rdesc = kmalloc(size, GFP_KERNEL))) {
                kfree(device->collection);
                kfree(device);
                return NULL;
@@ -719,6 +711,7 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
        kfree(parser);
        return NULL;
 }
+EXPORT_SYMBOL_GPL(hid_parse_report);
 
 /*
  * Convert a signed n-bit integer to signed 32-bit integer. Common
@@ -767,10 +760,10 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
        WARN_ON(n > 32);
 
        report += offset >> 3;  /* adjust byte index */
-       offset &= 7;            /* now only need bit offset into one byte */
+       offset &= 7;            /* now only need bit offset into one byte */
        x = get_unaligned((u64 *) report);
        x = le64_to_cpu(x);
-       x = (x >> offset) & ((1ULL << n) - 1);  /* extract bit field */
+       x = (x >> offset) & ((1ULL << n) - 1);  /* extract bit field */
        return (u32) x;
 }
 
@@ -819,8 +812,8 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s
        hid_dump_input(usage, value);
        if (hid->claimed & HID_CLAIMED_INPUT)
                hidinput_hid_event(hid, field, usage, value);
-       if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt)
-               hiddev_hid_event(hid, field, usage, value);
+       if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event)
+               hid->hiddev_hid_event(hid, field, usage, value);
 }
 
 /*
@@ -829,7 +822,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s
  * reporting to the layer).
  */
 
-static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt)
+void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt)
 {
        unsigned n;
        unsigned count = field->report_count;
@@ -875,7 +868,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u
 exit:
        kfree(value);
 }
-
+EXPORT_SYMBOL_GPL(hid_input_field);
 
 /*
  * Output the field into the report.
@@ -888,6 +881,10 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
        unsigned size = field->report_size;
        unsigned n;
 
+       /* make sure the unused bits in the last byte are zeros */
+       if (count > 0 && size > 0)
+               data[(count*size-1)/8] = 0;
+
        for (n = 0; n < count; n++) {
                if (field->logical_minimum < 0) /* signed values */
                        implement(data, offset + n * size, size, s32ton(field->value[n], size));
@@ -900,7 +897,7 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
  * Create a report.
  */
 
-static void hid_output_report(struct hid_report *report, __u8 *data)
+void hid_output_report(struct hid_report *report, __u8 *data)
 {
        unsigned n;
 
@@ -910,6 +907,7 @@ static void hid_output_report(struct hid_report *report, __u8 *data)
        for (n = 0; n < report->maxfield; n++)
                hid_output_field(report->field[n], data);
 }
+EXPORT_SYMBOL_GPL(hid_output_report);
 
 /*
  * Set a field value. The report this field belongs to has to be
@@ -937,4 +935,66 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
        field->value[offset] = value;
        return 0;
 }
+EXPORT_SYMBOL_GPL(hid_set_field);
+
+int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt)
+{
+       struct hid_report_enum *report_enum = hid->report_enum + type;
+       struct hid_report *report;
+       int n, rsize;
+
+       if (!hid)
+               return -ENODEV;
+
+       if (!size) {
+               dbg("empty report");
+               return -1;
+       }
+
+#ifdef DEBUG_DATA
+       printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
+#endif
+
+       n = 0;                          /* Normally report number is 0 */
+       if (report_enum->numbered) {    /* Device uses numbered reports, data[0] is report number */
+               n = *data++;
+               size--;
+       }
+
+#ifdef DEBUG_DATA
+       {
+               int i;
+               printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size);
+               for (i = 0; i < size; i++)
+                       printk(" %02x", data[i]);
+               printk("\n");
+       }
+#endif
+
+       if (!(report = report_enum->report_id_hash[n])) {
+               dbg("undefined report_id %d received", n);
+               return -1;
+       }
+
+       rsize = ((report->size - 1) >> 3) + 1;
+
+       if (size < rsize) {
+               dbg("report %d is too short, (%d < %d)", report->id, size, rsize);
+               return -1;
+       }
+
+       if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
+               hid->hiddev_report_event(hid, report);
+
+       for (n = 0; n < report->maxfield; n++)
+               hid_input_field(hid, report->field[n], data, interrupt);
+
+       if (hid->claimed & HID_CLAIMED_INPUT)
+               hidinput_report_event(hid, report);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(hid_input_report);
+
+MODULE_LICENSE(DRIVER_LICENSE);