From 93c10132a7ac160df3175b53f7ee857625412165 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 27 Jun 2008 00:04:24 +0200 Subject: HID: move connect quirks 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 Signed-off-by: Jiri Kosina --- drivers/hid/hid-a4tech.c | 2 +- drivers/hid/hid-apple.c | 13 ++++---- drivers/hid/hid-belkin.c | 6 ++-- drivers/hid/hid-core.c | 76 ++++++++++++++++++++++++++++++++++++++++++- drivers/hid/hid-cypress.c | 2 +- drivers/hid/hid-dell.c | 2 +- drivers/hid/hid-input.c | 23 ++++++------- drivers/hid/hid-logitech.c | 2 +- drivers/hid/hid-microsoft.c | 5 ++- drivers/hid/hid-petalynx.c | 2 +- drivers/hid/hid-samsung.c | 5 ++- drivers/hid/hid-sony.c | 5 ++- drivers/hid/usbhid/hid-core.c | 76 ++++--------------------------------------- drivers/hid/usbhid/hiddev.c | 20 +++++++----- 14 files changed, 125 insertions(+), 114 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index 26e16083a1f..ebca00e6c10 100644 --- a/drivers/hid/hid-a4tech.c +++ b/drivers/hid/hid-a4tech.c @@ -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; diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 2a68661fcea..f0b177844cf 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -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; diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c index 050b9892d7e..12c8a9ba6ed 100644 --- a/drivers/hid/hid-belkin.c +++ b/drivers/hid/hid-belkin.c @@ -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; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ea5f8bc900e..699547ce257 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -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 = ""; + } + + 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; diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c index a1e13f15f0a..5d69d27b935 100644 --- a/drivers/hid/hid-cypress.c +++ b/drivers/hid/hid-cypress.c @@ -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; diff --git a/drivers/hid/hid-dell.c b/drivers/hid/hid-dell.c index 5d1d54cfa87..788faa6b6ca 100644 --- a/drivers/hid/hid-dell.c +++ b/drivers/hid/hid-dell.c @@ -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; diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 0a68935c20b..7f183b7147e 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -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; diff --git a/drivers/hid/hid-logitech.c b/drivers/hid/hid-logitech.c index b2aaebe1ac0..732258241c0 100644 --- a/drivers/hid/hid-logitech.c +++ b/drivers/hid/hid-logitech.c @@ -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; diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 1fa8b813d44..d718b1607d0 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -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; diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c index 4109244f1d7..10945fe12d5 100644 --- a/drivers/hid/hid-petalynx.c +++ b/drivers/hid/hid-petalynx.c @@ -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; diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index 8771bfae02f..15f3c049245 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c @@ -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; diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 97668c68f0a..3af8095a7de 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -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; diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index b41d0110a75..0513b60728d 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -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 diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 842e9edb888..babd65dd46a 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -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; -- cgit v1.2.3