HID: move connect quirks
authorJiri Slaby <jirislaby@gmail.com>
Thu, 26 Jun 2008 22:04:24 +0000 (00:04 +0200)
committerJiri Kosina <jkosina@suse.cz>
Tue, 14 Oct 2008 21:50:56 +0000 (23:50 +0200)
Move connecting from usbhid to the hid layer and fix also hidp in
that manner.
This removes all the ignore/force hidinput/hiddev connecting quirks.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
17 files changed:
drivers/hid/hid-a4tech.c
drivers/hid/hid-apple.c
drivers/hid/hid-belkin.c
drivers/hid/hid-core.c
drivers/hid/hid-cypress.c
drivers/hid/hid-dell.c
drivers/hid/hid-input.c
drivers/hid/hid-logitech.c
drivers/hid/hid-microsoft.c
drivers/hid/hid-petalynx.c
drivers/hid/hid-samsung.c
drivers/hid/hid-sony.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hiddev.c
include/linux/hid.h
include/linux/hiddev.h
net/bluetooth/hidp/core.c

index 26e16083a1f124ed12dcc56c2862cac74b9e2a49..ebca00e6c103f742b22a9044d9d057ef456487c3 100644 (file)
@@ -107,7 +107,7 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id)
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index 2a68661fcea8df2d93fe6b4f606f5b2bccb051e2..f0b177844cf80c6ba9d689c2189726b477996380 100644 (file)
@@ -309,6 +309,7 @@ static int apple_probe(struct hid_device *hdev,
 {
        unsigned long quirks = id->driver_data;
        struct apple_sc *asc;
+       unsigned int connect_mask = HID_CONNECT_DEFAULT;
        int ret;
 
        /* return something else or move to hid layer? device will reside
@@ -328,18 +329,18 @@ static int apple_probe(struct hid_device *hdev,
 
        hid_set_drvdata(hdev, asc);
 
-       if (quirks & APPLE_HIDDEV)
-               hdev->quirks |= HID_QUIRK_HIDDEV;
-       if (quirks & APPLE_IGNORE_HIDINPUT)
-               hdev->quirks |= HID_QUIRK_IGNORE_HIDINPUT;
-
        ret = hid_parse(hdev);
        if (ret) {
                dev_err(&hdev->dev, "parse failed\n");
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       if (quirks & APPLE_HIDDEV)
+               connect_mask |= HID_CONNECT_HIDDEV_FORCE;
+       if (quirks & APPLE_IGNORE_HIDINPUT)
+               connect_mask &= ~HID_CONNECT_HIDINPUT;
+
+       ret = hid_hw_start(hdev, connect_mask);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index 050b9892d7efdc673173a3dce2392ff648c76e96..12c8a9ba6ed69badc7340d770954b249c29d1076 100644 (file)
@@ -54,16 +54,14 @@ static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
        hid_set_drvdata(hdev, (void *)quirks);
 
-       if (quirks & BELKIN_HIDDEV)
-               hdev->quirks |= HID_QUIRK_HIDDEV;
-
        ret = hid_parse(hdev);
        if (ret) {
                dev_err(&hdev->dev, "parse failed\n");
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
+               ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0));
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index ea5f8bc900e00aaa50fe5d70b984ffd1699c63a6..699547ce257f4d23d9ee04397b6b2af5ff4f4090 100644 (file)
@@ -1113,6 +1113,80 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
 }
 EXPORT_SYMBOL_GPL(hid_input_report);
 
+int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
+{
+       static const char *types[] = { "Device", "Pointer", "Mouse", "Device",
+               "Joystick", "Gamepad", "Keyboard", "Keypad",
+               "Multi-Axis Controller"
+       };
+       const char *type, *bus;
+       char buf[64];
+       unsigned int i;
+       int len;
+
+       if (hdev->bus != BUS_USB)
+               connect_mask &= ~HID_CONNECT_HIDDEV;
+
+       if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev,
+                               connect_mask & HID_CONNECT_HIDINPUT_FORCE))
+               hdev->claimed |= HID_CLAIMED_INPUT;
+       if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect &&
+                       !hdev->hiddev_connect(hdev,
+                               connect_mask & HID_CONNECT_HIDDEV_FORCE))
+               hdev->claimed |= HID_CLAIMED_HIDDEV;
+       if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev))
+               hdev->claimed |= HID_CLAIMED_HIDRAW;
+
+       if (!hdev->claimed) {
+               dev_err(&hdev->dev, "claimed by neither input, hiddev nor "
+                               "hidraw\n");
+               return -ENODEV;
+       }
+
+       if ((hdev->claimed & HID_CLAIMED_INPUT) &&
+                       (connect_mask & HID_CONNECT_FF) && hdev->ff_init)
+               hdev->ff_init(hdev);
+
+       len = 0;
+       if (hdev->claimed & HID_CLAIMED_INPUT)
+               len += sprintf(buf + len, "input");
+       if (hdev->claimed & HID_CLAIMED_HIDDEV)
+               len += sprintf(buf + len, "%shiddev%d", len ? "," : "",
+                               hdev->minor);
+       if (hdev->claimed & HID_CLAIMED_HIDRAW)
+               len += sprintf(buf + len, "%shidraw%d", len ? "," : "",
+                               ((struct hidraw *)hdev->hidraw)->minor);
+
+       type = "Device";
+       for (i = 0; i < hdev->maxcollection; i++) {
+               struct hid_collection *col = &hdev->collection[i];
+               if (col->type == HID_COLLECTION_APPLICATION &&
+                  (col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK &&
+                  (col->usage & 0xffff) < ARRAY_SIZE(types)) {
+                       type = types[col->usage & 0xffff];
+                       break;
+               }
+       }
+
+       switch (hdev->bus) {
+       case BUS_USB:
+               bus = "USB";
+               break;
+       case BUS_BLUETOOTH:
+               bus = "BLUETOOTH";
+               break;
+       default:
+               bus = "<UNKNOWN>";
+       }
+
+       dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n",
+                       buf, bus, hdev->version >> 8, hdev->version & 0xff,
+                       type, hdev->name, hdev->phys);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(hid_connect);
+
 static bool hid_match_one_id(struct hid_device *hdev,
                const struct hid_device_id *id)
 {
@@ -1238,7 +1312,7 @@ static int hid_device_probe(struct device *dev)
                } else { /* default probe */
                        ret = hid_parse(hdev);
                        if (!ret)
-                               ret = hid_hw_start(hdev);
+                               ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
                }
                if (ret)
                        hdev->driver = NULL;
index a1e13f15f0a72e9fa83b112ade71e208b847602a..5d69d27b935d629b2d04c39b982957fe4f533fe6 100644 (file)
@@ -110,7 +110,7 @@ static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id)
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index 5d1d54cfa87e152ca35a310987b3af3e4c893486..788faa6b6cac8b058aaef1f417f51274e861d5aa 100644 (file)
@@ -34,7 +34,7 @@ static int dell_probe(struct hid_device *hdev, const struct hid_device_id *id)
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index 0a68935c20b8c43fb3ae1f652455d2e6a285070e..7f183b7147e119b9ac1ea0e98d8c81bce662aaf3 100644 (file)
@@ -700,7 +700,7 @@ static void hidinput_close(struct input_dev *dev)
  * Read all reports and initialize the absolute field values.
  */
 
-int hidinput_connect(struct hid_device *hid)
+int hidinput_connect(struct hid_device *hid, unsigned int force)
 {
        struct hid_report *report;
        struct hid_input *hidinput = NULL;
@@ -708,19 +708,20 @@ int hidinput_connect(struct hid_device *hid)
        int i, j, k;
        int max_report_type = HID_OUTPUT_REPORT;
 
-       if (hid->quirks & HID_QUIRK_IGNORE_HIDINPUT)
-               return -1;
-
        INIT_LIST_HEAD(&hid->inputs);
 
-       for (i = 0; i < hid->maxcollection; i++)
-               if (hid->collection[i].type == HID_COLLECTION_APPLICATION ||
-                   hid->collection[i].type == HID_COLLECTION_PHYSICAL)
-                       if (IS_INPUT_APPLICATION(hid->collection[i].usage))
-                               break;
+       if (!force) {
+               for (i = 0; i < hid->maxcollection; i++) {
+                       struct hid_collection *col = &hid->collection[i];
+                       if (col->type == HID_COLLECTION_APPLICATION ||
+                                       col->type == HID_COLLECTION_PHYSICAL)
+                               if (IS_INPUT_APPLICATION(col->usage))
+                                       break;
+               }
 
-       if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0)
-               return -1;
+               if (i == hid->maxcollection)
+                       return -1;
+       }
 
        if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
                max_report_type = HID_INPUT_REPORT;
index b2aaebe1ac052ba0b6a22cbf30cec57c730a2a37..732258241c05d100699d3024ae38591c5d350999 100644 (file)
@@ -237,7 +237,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index 1fa8b813d441b6602b7fda966a5b3d55bfa4c5b1..d718b1607d0f78f505419b911a0fb86df62e1e17 100644 (file)
@@ -154,8 +154,6 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
        hid_set_drvdata(hdev, (void *)quirks);
 
-       if (quirks & MS_HIDINPUT)
-               hdev->quirks |= HID_QUIRK_HIDINPUT;
        if (quirks & MS_NOGET)
                hdev->quirks |= HID_QUIRK_NOGET;
 
@@ -165,7 +163,8 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ?
+                               HID_CONNECT_HIDINPUT_FORCE : 0));
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index 4109244f1d7278dd6101b59744256a167276821d..10945fe12d50eda52239e8c5e35ce0b42a8231ea 100644 (file)
@@ -80,7 +80,7 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index 8771bfae02f5284fa40c7179ad4ad8d1a1f0d3b9..15f3c04924506008eb6d3f85a2c9a21393fa87c3 100644 (file)
@@ -52,15 +52,14 @@ static int samsung_probe(struct hid_device *hdev,
 {
        int ret;
 
-       hdev->quirks |= HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT;
-
        ret = hid_parse(hdev);
        if (ret) {
                dev_err(&hdev->dev, "parse failed\n");
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) |
+                       HID_CONNECT_HIDDEV_FORCE);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index 97668c68f0a6a2abf48965f3747599434e42f062..3af8095a7de19639a1018bf3817118d28501081a 100644 (file)
@@ -57,15 +57,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
        int ret;
 
-       hdev->quirks |= HID_QUIRK_HIDDEV;
-
        ret = hid_parse(hdev);
        if (ret) {
                dev_err(&hdev->dev, "parse failed\n");
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
+                       HID_CONNECT_HIDDEV_FORCE);
        if (ret) {
                dev_err(&hdev->dev, "hw start failed\n");
                goto err_free;
index b41d0110a75eff1349e58769824e0e35a4d99b4c..0513b60728d328e4279464ca7b81e72623b1ea33 100644 (file)
@@ -44,8 +44,6 @@
 #define DRIVER_DESC "USB HID core driver"
 #define DRIVER_LICENSE "GPL"
 
-static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
-                               "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
 /*
  * Module parameters.
  */
@@ -670,70 +668,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
        usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
 }
 
-static int usbhid_start_finish(struct hid_device *hid)
-{
-       struct usb_interface *intf = to_usb_interface(hid->dev.parent);
-       char path[64], *type;
-       unsigned int i;
-
-       usbhid_init_reports(hid);
-       hid_dump_device(hid);
-       if (hid->quirks & HID_QUIRK_RESET_LEDS)
-               usbhid_set_leds(hid);
-
-       if (!hidinput_connect(hid))
-               hid->claimed |= HID_CLAIMED_INPUT;
-       if (!hiddev_connect(hid))
-               hid->claimed |= HID_CLAIMED_HIDDEV;
-       if (!hidraw_connect(hid))
-               hid->claimed |= HID_CLAIMED_HIDRAW;
-
-       if (!hid->claimed) {
-               printk(KERN_ERR "HID device claimed by neither input, hiddev "
-                               "nor hidraw\n");
-               return -ENODEV;
-       }
-
-       if ((hid->claimed & HID_CLAIMED_INPUT))
-               hid_ff_init(hid);
-
-       printk(KERN_INFO);
-
-       if (hid->claimed & HID_CLAIMED_INPUT)
-               printk("input");
-       if ((hid->claimed & HID_CLAIMED_INPUT) &&
-                       ((hid->claimed & HID_CLAIMED_HIDDEV) ||
-                               hid->claimed & HID_CLAIMED_HIDRAW))
-               printk(",");
-       if (hid->claimed & HID_CLAIMED_HIDDEV)
-               printk("hiddev%d", hid->minor);
-       if ((hid->claimed & HID_CLAIMED_INPUT) &&
-                       (hid->claimed & HID_CLAIMED_HIDDEV) &&
-                       (hid->claimed & HID_CLAIMED_HIDRAW))
-               printk(",");
-       if (hid->claimed & HID_CLAIMED_HIDRAW)
-               printk("hidraw%d", ((struct hidraw *)hid->hidraw)->minor);
-
-       type = "Device";
-       for (i = 0; i < hid->maxcollection; i++) {
-               if (hid->collection[i].type == HID_COLLECTION_APPLICATION &&
-                   (hid->collection[i].usage & HID_USAGE_PAGE) ==
-                                               HID_UP_GENDESK &&
-                   (hid->collection[i].usage & 0xffff) <
-                                               ARRAY_SIZE(hid_types)) {
-                       type = hid_types[hid->collection[i].usage & 0xffff];
-                       break;
-               }
-       }
-
-       usb_make_path(interface_to_usbdev(intf), path, 63);
-
-       printk(": USB HID v%x.%02x %s [%s] on %s\n",
-               hid->version >> 8, hid->version & 0xff, type, hid->name, path);
-
-       return 0;
-}
-
 static int usbhid_parse(struct hid_device *hid)
 {
        struct usb_interface *intf = to_usb_interface(hid->dev.parent);
@@ -923,9 +857,11 @@ static int usbhid_start(struct hid_device *hid)
        usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
        usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
-       ret = usbhid_start_finish(hid);
-       if (ret)
-               goto fail;
+       usbhid_init_reports(hid);
+       hid_dump_device(hid);
+
+       if (hid->quirks & HID_QUIRK_RESET_LEDS)
+               usbhid_set_leds(hid);
 
        return 0;
 
@@ -1000,7 +936,9 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
        usb_set_intfdata(intf, hid);
        hid->ll_driver = &usb_hid_driver;
        hid->hid_output_raw_report = usbhid_output_raw_report;
+       hid->ff_init = hid_ff_init;
 #ifdef CONFIG_USB_HIDDEV
+       hid->hiddev_connect = hiddev_connect;
        hid->hiddev_hid_event = hiddev_hid_event;
        hid->hiddev_report_event = hiddev_report_event;
 #endif
index 842e9edb888ed889c27c19fd2ca705c3da38010f..babd65dd46ad4eefa066c4e842288144f2941ab8 100644 (file)
@@ -790,21 +790,23 @@ static struct usb_class_driver hiddev_class = {
 /*
  * This is where hid.c calls us to connect a hid device to the hiddev driver
  */
-int hiddev_connect(struct hid_device *hid)
+int hiddev_connect(struct hid_device *hid, unsigned int force)
 {
        struct hiddev *hiddev;
        struct usbhid_device *usbhid = hid->driver_data;
-       int i;
        int retval;
 
-       for (i = 0; i < hid->maxcollection; i++)
-               if (hid->collection[i].type ==
-                   HID_COLLECTION_APPLICATION &&
-                   !IS_INPUT_APPLICATION(hid->collection[i].usage))
-                       break;
+       if (!force) {
+               unsigned int i;
+               for (i = 0; i < hid->maxcollection; i++)
+                       if (hid->collection[i].type ==
+                           HID_COLLECTION_APPLICATION &&
+                           !IS_INPUT_APPLICATION(hid->collection[i].usage))
+                               break;
 
-       if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0)
-               return -1;
+               if (i == hid->maxcollection)
+                       return -1;
+       }
 
        if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
                return -1;
index 43aa51a7fa95e68e5b303840f4b2aead01570e06..043209f7bfcf964606c63639af735edd1a2dfb3b 100644 (file)
@@ -246,6 +246,19 @@ struct hid_item {
 #define HID_OUTPUT_REPORT      1
 #define HID_FEATURE_REPORT     2
 
+/*
+ * HID connect requests
+ */
+
+#define HID_CONNECT_HIDINPUT           0x01
+#define HID_CONNECT_HIDINPUT_FORCE     0x02
+#define HID_CONNECT_HIDRAW             0x04
+#define HID_CONNECT_HIDDEV             0x08
+#define HID_CONNECT_HIDDEV_FORCE       0x10
+#define HID_CONNECT_FF                 0x20
+#define HID_CONNECT_DEFAULT    (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \
+               HID_CONNECT_HIDDEV|HID_CONNECT_FF)
+
 /*
  * HID device quirks.
  */
@@ -258,13 +271,10 @@ struct hid_item {
 #define HID_QUIRK_INVERT                       0x00000001
 #define HID_QUIRK_NOTOUCH                      0x00000002
 #define HID_QUIRK_NOGET                                0x00000008
-#define HID_QUIRK_HIDDEV                       0x00000010
 #define HID_QUIRK_BADPAD                       0x00000020
 #define HID_QUIRK_MULTI_INPUT                  0x00000040
 #define HID_QUIRK_SKIP_OUTPUT_REPORTS          0x00010000
 #define HID_QUIRK_RESET_LEDS                   0x00100000
-#define HID_QUIRK_HIDINPUT                     0x00200000
-#define HID_QUIRK_IGNORE_HIDINPUT              0x01000000
 #define HID_QUIRK_FULLSPEED_INTERVAL           0x10000000
 
 /*
@@ -439,7 +449,11 @@ struct hid_device {                                                        /* device report descriptor */
 
        void *driver_data;
 
+       /* temporary hid_ff handling (until moved to the drivers) */
+       int (*ff_init)(struct hid_device *);
+
        /* hiddev event handler */
+       int (*hiddev_connect)(struct hid_device *, unsigned int);
        void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
                                  struct hid_usage *, __s32);
        void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
@@ -610,7 +624,7 @@ extern void hid_unregister_driver(struct hid_driver *);
 
 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 *);
+extern int hidinput_connect(struct hid_device *hid, unsigned int force);
 extern void hidinput_disconnect(struct hid_device *);
 
 int hid_set_field(struct hid_field *, unsigned, __s32);
@@ -619,6 +633,7 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
 void hid_output_report(struct hid_report *report, __u8 *data);
 struct hid_device *hid_allocate_device(void);
 int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
+int hid_connect(struct hid_device *hid, unsigned int connect_mask);
 
 /**
  * hid_map_usage - map usage input bits
@@ -700,14 +715,22 @@ static inline int __must_check hid_parse(struct hid_device *hdev)
  * hid_hw_start - start underlaying HW
  *
  * @hdev: hid device
+ * @connect_mask: which outputs to connect, see HID_CONNECT_*
  *
  * Call this in probe function *after* hid_parse. This will setup HW buffers
  * and start the device (if not deffered to device open). hid_hw_stop must be
  * called if this was successfull.
  */
-static inline int __must_check hid_hw_start(struct hid_device *hdev)
+static inline int __must_check hid_hw_start(struct hid_device *hdev,
+               unsigned int connect_mask)
 {
-       return hdev->ll_driver->start(hdev);
+       int ret = hdev->ll_driver->start(hdev);
+       if (ret || !connect_mask)
+               return ret;
+       ret = hid_connect(hdev, connect_mask);
+       if (ret)
+               hdev->ll_driver->stop(hdev);
+       return ret;
 }
 
 /**
@@ -749,7 +772,7 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
 #endif
 
 #else
-static inline int hid_ff_init(struct hid_device *hid) { return -1; }
+#define hid_ff_init    NULL
 #endif
 
 #ifdef CONFIG_HID_DEBUG
index a416b904ba900c2bae4453547bb8f01f818fe251..6ae77b3468f9af83bddfba7bf0db3d8ca3674789 100644 (file)
@@ -217,7 +217,7 @@ struct hid_field;
 struct hid_report;
 
 #ifdef CONFIG_USB_HIDDEV
-int hiddev_connect(struct hid_device *);
+int hiddev_connect(struct hid_device *hid, unsigned int force);
 void hiddev_disconnect(struct hid_device *);
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
                      struct hid_usage *usage, __s32 value);
@@ -225,7 +225,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report);
 int __init hiddev_init(void);
 void hiddev_exit(void);
 #else
-static inline int hiddev_connect(struct hid_device *hid) { return -1; }
+static inline int hiddev_connect(struct hid_device *hid,
+               unsigned int force)
+{ return -1; }
 static inline void hiddev_disconnect(struct hid_device *hid) { }
 static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
                      struct hid_usage *usage, __s32 value) { }
index f3d830747b969326b583d2e0d5268f670efd7db1..acdeab3d980707fbd7740344abd4f7ffe335c75d 100644 (file)
@@ -724,9 +724,6 @@ static int hidp_start(struct hid_device *hid)
                        report_list, list)
                hidp_send_report(session, report);
 
-       if (hidinput_connect(hid) == 0)
-               hid->claimed |= HID_CLAIMED_INPUT;
-
        return 0;
 }