diff options
-rw-r--r-- | drivers/hid/hid-a4tech.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-apple.c | 13 | ||||
-rw-r--r-- | drivers/hid/hid-belkin.c | 6 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 76 | ||||
-rw-r--r-- | drivers/hid/hid-cypress.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-dell.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 23 | ||||
-rw-r--r-- | drivers/hid/hid-logitech.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-microsoft.c | 5 | ||||
-rw-r--r-- | drivers/hid/hid-petalynx.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-samsung.c | 5 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 5 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 76 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 20 | ||||
-rw-r--r-- | include/linux/hid.h | 37 | ||||
-rw-r--r-- | include/linux/hiddev.h | 6 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 3 |
17 files changed, 159 insertions, 126 deletions
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index 26e16083a1f1..ebca00e6c103 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) | |||
107 | goto err_free; | 107 | goto err_free; |
108 | } | 108 | } |
109 | 109 | ||
110 | ret = hid_hw_start(hdev); | 110 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
111 | if (ret) { | 111 | if (ret) { |
112 | dev_err(&hdev->dev, "hw start failed\n"); | 112 | dev_err(&hdev->dev, "hw start failed\n"); |
113 | goto err_free; | 113 | goto err_free; |
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 2a68661fcea8..f0b177844cf8 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, | |||
309 | { | 309 | { |
310 | unsigned long quirks = id->driver_data; | 310 | unsigned long quirks = id->driver_data; |
311 | struct apple_sc *asc; | 311 | struct apple_sc *asc; |
312 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | ||
312 | int ret; | 313 | int ret; |
313 | 314 | ||
314 | /* return something else or move to hid layer? device will reside | 315 | /* return something else or move to hid layer? device will reside |
@@ -328,18 +329,18 @@ static int apple_probe(struct hid_device *hdev, | |||
328 | 329 | ||
329 | hid_set_drvdata(hdev, asc); | 330 | hid_set_drvdata(hdev, asc); |
330 | 331 | ||
331 | if (quirks & APPLE_HIDDEV) | ||
332 | hdev->quirks |= HID_QUIRK_HIDDEV; | ||
333 | if (quirks & APPLE_IGNORE_HIDINPUT) | ||
334 | hdev->quirks |= HID_QUIRK_IGNORE_HIDINPUT; | ||
335 | |||
336 | ret = hid_parse(hdev); | 332 | ret = hid_parse(hdev); |
337 | if (ret) { | 333 | if (ret) { |
338 | dev_err(&hdev->dev, "parse failed\n"); | 334 | dev_err(&hdev->dev, "parse failed\n"); |
339 | goto err_free; | 335 | goto err_free; |
340 | } | 336 | } |
341 | 337 | ||
342 | ret = hid_hw_start(hdev); | 338 | if (quirks & APPLE_HIDDEV) |
339 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; | ||
340 | if (quirks & APPLE_IGNORE_HIDINPUT) | ||
341 | connect_mask &= ~HID_CONNECT_HIDINPUT; | ||
342 | |||
343 | ret = hid_hw_start(hdev, connect_mask); | ||
343 | if (ret) { | 344 | if (ret) { |
344 | dev_err(&hdev->dev, "hw start failed\n"); | 345 | dev_err(&hdev->dev, "hw start failed\n"); |
345 | goto err_free; | 346 | goto err_free; |
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c index 050b9892d7ef..12c8a9ba6ed6 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) | |||
54 | 54 | ||
55 | hid_set_drvdata(hdev, (void *)quirks); | 55 | hid_set_drvdata(hdev, (void *)quirks); |
56 | 56 | ||
57 | if (quirks & BELKIN_HIDDEV) | ||
58 | hdev->quirks |= HID_QUIRK_HIDDEV; | ||
59 | |||
60 | ret = hid_parse(hdev); | 57 | ret = hid_parse(hdev); |
61 | if (ret) { | 58 | if (ret) { |
62 | dev_err(&hdev->dev, "parse failed\n"); | 59 | dev_err(&hdev->dev, "parse failed\n"); |
63 | goto err_free; | 60 | goto err_free; |
64 | } | 61 | } |
65 | 62 | ||
66 | ret = hid_hw_start(hdev); | 63 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | |
64 | ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0)); | ||
67 | if (ret) { | 65 | if (ret) { |
68 | dev_err(&hdev->dev, "hw start failed\n"); | 66 | dev_err(&hdev->dev, "hw start failed\n"); |
69 | goto err_free; | 67 | goto err_free; |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ea5f8bc900e0..699547ce257f 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 | |||
1113 | } | 1113 | } |
1114 | EXPORT_SYMBOL_GPL(hid_input_report); | 1114 | EXPORT_SYMBOL_GPL(hid_input_report); |
1115 | 1115 | ||
1116 | int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | ||
1117 | { | ||
1118 | static const char *types[] = { "Device", "Pointer", "Mouse", "Device", | ||
1119 | "Joystick", "Gamepad", "Keyboard", "Keypad", | ||
1120 | "Multi-Axis Controller" | ||
1121 | }; | ||
1122 | const char *type, *bus; | ||
1123 | char buf[64]; | ||
1124 | unsigned int i; | ||
1125 | int len; | ||
1126 | |||
1127 | if (hdev->bus != BUS_USB) | ||
1128 | connect_mask &= ~HID_CONNECT_HIDDEV; | ||
1129 | |||
1130 | if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, | ||
1131 | connect_mask & HID_CONNECT_HIDINPUT_FORCE)) | ||
1132 | hdev->claimed |= HID_CLAIMED_INPUT; | ||
1133 | if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect && | ||
1134 | !hdev->hiddev_connect(hdev, | ||
1135 | connect_mask & HID_CONNECT_HIDDEV_FORCE)) | ||
1136 | hdev->claimed |= HID_CLAIMED_HIDDEV; | ||
1137 | if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) | ||
1138 | hdev->claimed |= HID_CLAIMED_HIDRAW; | ||
1139 | |||
1140 | if (!hdev->claimed) { | ||
1141 | dev_err(&hdev->dev, "claimed by neither input, hiddev nor " | ||
1142 | "hidraw\n"); | ||
1143 | return -ENODEV; | ||
1144 | } | ||
1145 | |||
1146 | if ((hdev->claimed & HID_CLAIMED_INPUT) && | ||
1147 | (connect_mask & HID_CONNECT_FF) && hdev->ff_init) | ||
1148 | hdev->ff_init(hdev); | ||
1149 | |||
1150 | len = 0; | ||
1151 | if (hdev->claimed & HID_CLAIMED_INPUT) | ||
1152 | len += sprintf(buf + len, "input"); | ||
1153 | if (hdev->claimed & HID_CLAIMED_HIDDEV) | ||
1154 | len += sprintf(buf + len, "%shiddev%d", len ? "," : "", | ||
1155 | hdev->minor); | ||
1156 | if (hdev->claimed & HID_CLAIMED_HIDRAW) | ||
1157 | len += sprintf(buf + len, "%shidraw%d", len ? "," : "", | ||
1158 | ((struct hidraw *)hdev->hidraw)->minor); | ||
1159 | |||
1160 | type = "Device"; | ||
1161 | for (i = 0; i < hdev->maxcollection; i++) { | ||
1162 | struct hid_collection *col = &hdev->collection[i]; | ||
1163 | if (col->type == HID_COLLECTION_APPLICATION && | ||
1164 | (col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK && | ||
1165 | (col->usage & 0xffff) < ARRAY_SIZE(types)) { | ||
1166 | type = types[col->usage & 0xffff]; | ||
1167 | break; | ||
1168 | } | ||
1169 | } | ||
1170 | |||
1171 | switch (hdev->bus) { | ||
1172 | case BUS_USB: | ||
1173 | bus = "USB"; | ||
1174 | break; | ||
1175 | case BUS_BLUETOOTH: | ||
1176 | bus = "BLUETOOTH"; | ||
1177 | break; | ||
1178 | default: | ||
1179 | bus = "<UNKNOWN>"; | ||
1180 | } | ||
1181 | |||
1182 | dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n", | ||
1183 | buf, bus, hdev->version >> 8, hdev->version & 0xff, | ||
1184 | type, hdev->name, hdev->phys); | ||
1185 | |||
1186 | return 0; | ||
1187 | } | ||
1188 | EXPORT_SYMBOL_GPL(hid_connect); | ||
1189 | |||
1116 | static bool hid_match_one_id(struct hid_device *hdev, | 1190 | static bool hid_match_one_id(struct hid_device *hdev, |
1117 | const struct hid_device_id *id) | 1191 | const struct hid_device_id *id) |
1118 | { | 1192 | { |
@@ -1238,7 +1312,7 @@ static int hid_device_probe(struct device *dev) | |||
1238 | } else { /* default probe */ | 1312 | } else { /* default probe */ |
1239 | ret = hid_parse(hdev); | 1313 | ret = hid_parse(hdev); |
1240 | if (!ret) | 1314 | if (!ret) |
1241 | ret = hid_hw_start(hdev); | 1315 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
1242 | } | 1316 | } |
1243 | if (ret) | 1317 | if (ret) |
1244 | hdev->driver = NULL; | 1318 | hdev->driver = NULL; |
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c index a1e13f15f0a7..5d69d27b935d 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) | |||
110 | goto err_free; | 110 | goto err_free; |
111 | } | 111 | } |
112 | 112 | ||
113 | ret = hid_hw_start(hdev); | 113 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
114 | if (ret) { | 114 | if (ret) { |
115 | dev_err(&hdev->dev, "hw start failed\n"); | 115 | dev_err(&hdev->dev, "hw start failed\n"); |
116 | goto err_free; | 116 | goto err_free; |
diff --git a/drivers/hid/hid-dell.c b/drivers/hid/hid-dell.c index 5d1d54cfa87e..788faa6b6cac 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) | |||
34 | goto err_free; | 34 | goto err_free; |
35 | } | 35 | } |
36 | 36 | ||
37 | ret = hid_hw_start(hdev); | 37 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
38 | if (ret) { | 38 | if (ret) { |
39 | dev_err(&hdev->dev, "hw start failed\n"); | 39 | dev_err(&hdev->dev, "hw start failed\n"); |
40 | goto err_free; | 40 | goto err_free; |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 0a68935c20b8..7f183b7147e1 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) | |||
700 | * Read all reports and initialize the absolute field values. | 700 | * Read all reports and initialize the absolute field values. |
701 | */ | 701 | */ |
702 | 702 | ||
703 | int hidinput_connect(struct hid_device *hid) | 703 | int hidinput_connect(struct hid_device *hid, unsigned int force) |
704 | { | 704 | { |
705 | struct hid_report *report; | 705 | struct hid_report *report; |
706 | struct hid_input *hidinput = NULL; | 706 | struct hid_input *hidinput = NULL; |
@@ -708,19 +708,20 @@ int hidinput_connect(struct hid_device *hid) | |||
708 | int i, j, k; | 708 | int i, j, k; |
709 | int max_report_type = HID_OUTPUT_REPORT; | 709 | int max_report_type = HID_OUTPUT_REPORT; |
710 | 710 | ||
711 | if (hid->quirks & HID_QUIRK_IGNORE_HIDINPUT) | ||
712 | return -1; | ||
713 | |||
714 | INIT_LIST_HEAD(&hid->inputs); | 711 | INIT_LIST_HEAD(&hid->inputs); |
715 | 712 | ||
716 | for (i = 0; i < hid->maxcollection; i++) | 713 | if (!force) { |
717 | if (hid->collection[i].type == HID_COLLECTION_APPLICATION || | 714 | for (i = 0; i < hid->maxcollection; i++) { |
718 | hid->collection[i].type == HID_COLLECTION_PHYSICAL) | 715 | struct hid_collection *col = &hid->collection[i]; |
719 | if (IS_INPUT_APPLICATION(hid->collection[i].usage)) | 716 | if (col->type == HID_COLLECTION_APPLICATION || |
720 | break; | 717 | col->type == HID_COLLECTION_PHYSICAL) |
718 | if (IS_INPUT_APPLICATION(col->usage)) | ||
719 | break; | ||
720 | } | ||
721 | 721 | ||
722 | if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0) | 722 | if (i == hid->maxcollection) |
723 | return -1; | 723 | return -1; |
724 | } | ||
724 | 725 | ||
725 | if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) | 726 | if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) |
726 | max_report_type = HID_INPUT_REPORT; | 727 | max_report_type = HID_INPUT_REPORT; |
diff --git a/drivers/hid/hid-logitech.c b/drivers/hid/hid-logitech.c index b2aaebe1ac05..732258241c05 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) | |||
237 | goto err_free; | 237 | goto err_free; |
238 | } | 238 | } |
239 | 239 | ||
240 | ret = hid_hw_start(hdev); | 240 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
241 | if (ret) { | 241 | if (ret) { |
242 | dev_err(&hdev->dev, "hw start failed\n"); | 242 | dev_err(&hdev->dev, "hw start failed\n"); |
243 | goto err_free; | 243 | goto err_free; |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 1fa8b813d441..d718b1607d0f 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) | |||
154 | 154 | ||
155 | hid_set_drvdata(hdev, (void *)quirks); | 155 | hid_set_drvdata(hdev, (void *)quirks); |
156 | 156 | ||
157 | if (quirks & MS_HIDINPUT) | ||
158 | hdev->quirks |= HID_QUIRK_HIDINPUT; | ||
159 | if (quirks & MS_NOGET) | 157 | if (quirks & MS_NOGET) |
160 | hdev->quirks |= HID_QUIRK_NOGET; | 158 | hdev->quirks |= HID_QUIRK_NOGET; |
161 | 159 | ||
@@ -165,7 +163,8 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
165 | goto err_free; | 163 | goto err_free; |
166 | } | 164 | } |
167 | 165 | ||
168 | ret = hid_hw_start(hdev); | 166 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ? |
167 | HID_CONNECT_HIDINPUT_FORCE : 0)); | ||
169 | if (ret) { | 168 | if (ret) { |
170 | dev_err(&hdev->dev, "hw start failed\n"); | 169 | dev_err(&hdev->dev, "hw start failed\n"); |
171 | goto err_free; | 170 | goto err_free; |
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c index 4109244f1d72..10945fe12d50 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) | |||
80 | goto err_free; | 80 | goto err_free; |
81 | } | 81 | } |
82 | 82 | ||
83 | ret = hid_hw_start(hdev); | 83 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
84 | if (ret) { | 84 | if (ret) { |
85 | dev_err(&hdev->dev, "hw start failed\n"); | 85 | dev_err(&hdev->dev, "hw start failed\n"); |
86 | goto err_free; | 86 | goto err_free; |
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index 8771bfae02f5..15f3c0492450 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, | |||
52 | { | 52 | { |
53 | int ret; | 53 | int ret; |
54 | 54 | ||
55 | hdev->quirks |= HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT; | ||
56 | |||
57 | ret = hid_parse(hdev); | 55 | ret = hid_parse(hdev); |
58 | if (ret) { | 56 | if (ret) { |
59 | dev_err(&hdev->dev, "parse failed\n"); | 57 | dev_err(&hdev->dev, "parse failed\n"); |
60 | goto err_free; | 58 | goto err_free; |
61 | } | 59 | } |
62 | 60 | ||
63 | ret = hid_hw_start(hdev); | 61 | ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) | |
62 | HID_CONNECT_HIDDEV_FORCE); | ||
64 | if (ret) { | 63 | if (ret) { |
65 | dev_err(&hdev->dev, "hw start failed\n"); | 64 | dev_err(&hdev->dev, "hw start failed\n"); |
66 | goto err_free; | 65 | goto err_free; |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 97668c68f0a6..3af8095a7de1 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) | |||
57 | { | 57 | { |
58 | int ret; | 58 | int ret; |
59 | 59 | ||
60 | hdev->quirks |= HID_QUIRK_HIDDEV; | ||
61 | |||
62 | ret = hid_parse(hdev); | 60 | ret = hid_parse(hdev); |
63 | if (ret) { | 61 | if (ret) { |
64 | dev_err(&hdev->dev, "parse failed\n"); | 62 | dev_err(&hdev->dev, "parse failed\n"); |
65 | goto err_free; | 63 | goto err_free; |
66 | } | 64 | } |
67 | 65 | ||
68 | ret = hid_hw_start(hdev); | 66 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | |
67 | HID_CONNECT_HIDDEV_FORCE); | ||
69 | if (ret) { | 68 | if (ret) { |
70 | dev_err(&hdev->dev, "hw start failed\n"); | 69 | dev_err(&hdev->dev, "hw start failed\n"); |
71 | goto err_free; | 70 | goto err_free; |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index b41d0110a75e..0513b60728d3 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -44,8 +44,6 @@ | |||
44 | #define DRIVER_DESC "USB HID core driver" | 44 | #define DRIVER_DESC "USB HID core driver" |
45 | #define DRIVER_LICENSE "GPL" | 45 | #define DRIVER_LICENSE "GPL" |
46 | 46 | ||
47 | static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", | ||
48 | "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; | ||
49 | /* | 47 | /* |
50 | * Module parameters. | 48 | * Module parameters. |
51 | */ | 49 | */ |
@@ -670,70 +668,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) | |||
670 | usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); | 668 | usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); |
671 | } | 669 | } |
672 | 670 | ||
673 | static int usbhid_start_finish(struct hid_device *hid) | ||
674 | { | ||
675 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | ||
676 | char path[64], *type; | ||
677 | unsigned int i; | ||
678 | |||
679 | usbhid_init_reports(hid); | ||
680 | hid_dump_device(hid); | ||
681 | if (hid->quirks & HID_QUIRK_RESET_LEDS) | ||
682 | usbhid_set_leds(hid); | ||
683 | |||
684 | if (!hidinput_connect(hid)) | ||
685 | hid->claimed |= HID_CLAIMED_INPUT; | ||
686 | if (!hiddev_connect(hid)) | ||
687 | hid->claimed |= HID_CLAIMED_HIDDEV; | ||
688 | if (!hidraw_connect(hid)) | ||
689 | hid->claimed |= HID_CLAIMED_HIDRAW; | ||
690 | |||
691 | if (!hid->claimed) { | ||
692 | printk(KERN_ERR "HID device claimed by neither input, hiddev " | ||
693 | "nor hidraw\n"); | ||
694 | return -ENODEV; | ||
695 | } | ||
696 | |||
697 | if ((hid->claimed & HID_CLAIMED_INPUT)) | ||
698 | hid_ff_init(hid); | ||
699 | |||
700 | printk(KERN_INFO); | ||
701 | |||
702 | if (hid->claimed & HID_CLAIMED_INPUT) | ||
703 | printk("input"); | ||
704 | if ((hid->claimed & HID_CLAIMED_INPUT) && | ||
705 | ((hid->claimed & HID_CLAIMED_HIDDEV) || | ||
706 | hid->claimed & HID_CLAIMED_HIDRAW)) | ||
707 | printk(","); | ||
708 | if (hid->claimed & HID_CLAIMED_HIDDEV) | ||
709 | printk("hiddev%d", hid->minor); | ||
710 | if ((hid->claimed & HID_CLAIMED_INPUT) && | ||
711 | (hid->claimed & HID_CLAIMED_HIDDEV) && | ||
712 | (hid->claimed & HID_CLAIMED_HIDRAW)) | ||
713 | printk(","); | ||
714 | if (hid->claimed & HID_CLAIMED_HIDRAW) | ||
715 | printk("hidraw%d", ((struct hidraw *)hid->hidraw)->minor); | ||
716 | |||
717 | type = "Device"; | ||
718 | for (i = 0; i < hid->maxcollection; i++) { | ||
719 | if (hid->collection[i].type == HID_COLLECTION_APPLICATION && | ||
720 | (hid->collection[i].usage & HID_USAGE_PAGE) == | ||
721 | HID_UP_GENDESK && | ||
722 | (hid->collection[i].usage & 0xffff) < | ||
723 | ARRAY_SIZE(hid_types)) { | ||
724 | type = hid_types[hid->collection[i].usage & 0xffff]; | ||
725 | break; | ||
726 | } | ||
727 | } | ||
728 | |||
729 | usb_make_path(interface_to_usbdev(intf), path, 63); | ||
730 | |||
731 | printk(": USB HID v%x.%02x %s [%s] on %s\n", | ||
732 | hid->version >> 8, hid->version & 0xff, type, hid->name, path); | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int usbhid_parse(struct hid_device *hid) | 671 | static int usbhid_parse(struct hid_device *hid) |
738 | { | 672 | { |
739 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | 673 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); |
@@ -923,9 +857,11 @@ static int usbhid_start(struct hid_device *hid) | |||
923 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; | 857 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; |
924 | usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); | 858 | usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); |
925 | 859 | ||
926 | ret = usbhid_start_finish(hid); | 860 | usbhid_init_reports(hid); |
927 | if (ret) | 861 | hid_dump_device(hid); |
928 | goto fail; | 862 | |
863 | if (hid->quirks & HID_QUIRK_RESET_LEDS) | ||
864 | usbhid_set_leds(hid); | ||
929 | 865 | ||
930 | return 0; | 866 | return 0; |
931 | 867 | ||
@@ -1000,7 +936,9 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1000 | usb_set_intfdata(intf, hid); | 936 | usb_set_intfdata(intf, hid); |
1001 | hid->ll_driver = &usb_hid_driver; | 937 | hid->ll_driver = &usb_hid_driver; |
1002 | hid->hid_output_raw_report = usbhid_output_raw_report; | 938 | hid->hid_output_raw_report = usbhid_output_raw_report; |
939 | hid->ff_init = hid_ff_init; | ||
1003 | #ifdef CONFIG_USB_HIDDEV | 940 | #ifdef CONFIG_USB_HIDDEV |
941 | hid->hiddev_connect = hiddev_connect; | ||
1004 | hid->hiddev_hid_event = hiddev_hid_event; | 942 | hid->hiddev_hid_event = hiddev_hid_event; |
1005 | hid->hiddev_report_event = hiddev_report_event; | 943 | hid->hiddev_report_event = hiddev_report_event; |
1006 | #endif | 944 | #endif |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 842e9edb888e..babd65dd46ad 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -790,21 +790,23 @@ static struct usb_class_driver hiddev_class = { | |||
790 | /* | 790 | /* |
791 | * This is where hid.c calls us to connect a hid device to the hiddev driver | 791 | * This is where hid.c calls us to connect a hid device to the hiddev driver |
792 | */ | 792 | */ |
793 | int hiddev_connect(struct hid_device *hid) | 793 | int hiddev_connect(struct hid_device *hid, unsigned int force) |
794 | { | 794 | { |
795 | struct hiddev *hiddev; | 795 | struct hiddev *hiddev; |
796 | struct usbhid_device *usbhid = hid->driver_data; | 796 | struct usbhid_device *usbhid = hid->driver_data; |
797 | int i; | ||
798 | int retval; | 797 | int retval; |
799 | 798 | ||
800 | for (i = 0; i < hid->maxcollection; i++) | 799 | if (!force) { |
801 | if (hid->collection[i].type == | 800 | unsigned int i; |
802 | HID_COLLECTION_APPLICATION && | 801 | for (i = 0; i < hid->maxcollection; i++) |
803 | !IS_INPUT_APPLICATION(hid->collection[i].usage)) | 802 | if (hid->collection[i].type == |
804 | break; | 803 | HID_COLLECTION_APPLICATION && |
804 | !IS_INPUT_APPLICATION(hid->collection[i].usage)) | ||
805 | break; | ||
805 | 806 | ||
806 | if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0) | 807 | if (i == hid->maxcollection) |
807 | return -1; | 808 | return -1; |
809 | } | ||
808 | 810 | ||
809 | if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) | 811 | if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) |
810 | return -1; | 812 | return -1; |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 43aa51a7fa95..043209f7bfcf 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -247,6 +247,19 @@ struct hid_item { | |||
247 | #define HID_FEATURE_REPORT 2 | 247 | #define HID_FEATURE_REPORT 2 |
248 | 248 | ||
249 | /* | 249 | /* |
250 | * HID connect requests | ||
251 | */ | ||
252 | |||
253 | #define HID_CONNECT_HIDINPUT 0x01 | ||
254 | #define HID_CONNECT_HIDINPUT_FORCE 0x02 | ||
255 | #define HID_CONNECT_HIDRAW 0x04 | ||
256 | #define HID_CONNECT_HIDDEV 0x08 | ||
257 | #define HID_CONNECT_HIDDEV_FORCE 0x10 | ||
258 | #define HID_CONNECT_FF 0x20 | ||
259 | #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ | ||
260 | HID_CONNECT_HIDDEV|HID_CONNECT_FF) | ||
261 | |||
262 | /* | ||
250 | * HID device quirks. | 263 | * HID device quirks. |
251 | */ | 264 | */ |
252 | 265 | ||
@@ -258,13 +271,10 @@ struct hid_item { | |||
258 | #define HID_QUIRK_INVERT 0x00000001 | 271 | #define HID_QUIRK_INVERT 0x00000001 |
259 | #define HID_QUIRK_NOTOUCH 0x00000002 | 272 | #define HID_QUIRK_NOTOUCH 0x00000002 |
260 | #define HID_QUIRK_NOGET 0x00000008 | 273 | #define HID_QUIRK_NOGET 0x00000008 |
261 | #define HID_QUIRK_HIDDEV 0x00000010 | ||
262 | #define HID_QUIRK_BADPAD 0x00000020 | 274 | #define HID_QUIRK_BADPAD 0x00000020 |
263 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | 275 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
264 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 276 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
265 | #define HID_QUIRK_RESET_LEDS 0x00100000 | 277 | #define HID_QUIRK_RESET_LEDS 0x00100000 |
266 | #define HID_QUIRK_HIDINPUT 0x00200000 | ||
267 | #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 | ||
268 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 | 278 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 |
269 | 279 | ||
270 | /* | 280 | /* |
@@ -439,7 +449,11 @@ struct hid_device { /* device report descriptor */ | |||
439 | 449 | ||
440 | void *driver_data; | 450 | void *driver_data; |
441 | 451 | ||
452 | /* temporary hid_ff handling (until moved to the drivers) */ | ||
453 | int (*ff_init)(struct hid_device *); | ||
454 | |||
442 | /* hiddev event handler */ | 455 | /* hiddev event handler */ |
456 | int (*hiddev_connect)(struct hid_device *, unsigned int); | ||
443 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, | 457 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, |
444 | struct hid_usage *, __s32); | 458 | struct hid_usage *, __s32); |
445 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); | 459 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); |
@@ -610,7 +624,7 @@ extern void hid_unregister_driver(struct hid_driver *); | |||
610 | 624 | ||
611 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | 625 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); |
612 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); | 626 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); |
613 | extern int hidinput_connect(struct hid_device *); | 627 | extern int hidinput_connect(struct hid_device *hid, unsigned int force); |
614 | extern void hidinput_disconnect(struct hid_device *); | 628 | extern void hidinput_disconnect(struct hid_device *); |
615 | 629 | ||
616 | int hid_set_field(struct hid_field *, unsigned, __s32); | 630 | 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 | |||
619 | void hid_output_report(struct hid_report *report, __u8 *data); | 633 | void hid_output_report(struct hid_report *report, __u8 *data); |
620 | struct hid_device *hid_allocate_device(void); | 634 | struct hid_device *hid_allocate_device(void); |
621 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); | 635 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); |
636 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); | ||
622 | 637 | ||
623 | /** | 638 | /** |
624 | * hid_map_usage - map usage input bits | 639 | * hid_map_usage - map usage input bits |
@@ -700,14 +715,22 @@ static inline int __must_check hid_parse(struct hid_device *hdev) | |||
700 | * hid_hw_start - start underlaying HW | 715 | * hid_hw_start - start underlaying HW |
701 | * | 716 | * |
702 | * @hdev: hid device | 717 | * @hdev: hid device |
718 | * @connect_mask: which outputs to connect, see HID_CONNECT_* | ||
703 | * | 719 | * |
704 | * Call this in probe function *after* hid_parse. This will setup HW buffers | 720 | * Call this in probe function *after* hid_parse. This will setup HW buffers |
705 | * and start the device (if not deffered to device open). hid_hw_stop must be | 721 | * and start the device (if not deffered to device open). hid_hw_stop must be |
706 | * called if this was successfull. | 722 | * called if this was successfull. |
707 | */ | 723 | */ |
708 | static inline int __must_check hid_hw_start(struct hid_device *hdev) | 724 | static inline int __must_check hid_hw_start(struct hid_device *hdev, |
725 | unsigned int connect_mask) | ||
709 | { | 726 | { |
710 | return hdev->ll_driver->start(hdev); | 727 | int ret = hdev->ll_driver->start(hdev); |
728 | if (ret || !connect_mask) | ||
729 | return ret; | ||
730 | ret = hid_connect(hdev, connect_mask); | ||
731 | if (ret) | ||
732 | hdev->ll_driver->stop(hdev); | ||
733 | return ret; | ||
711 | } | 734 | } |
712 | 735 | ||
713 | /** | 736 | /** |
@@ -749,7 +772,7 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; } | |||
749 | #endif | 772 | #endif |
750 | 773 | ||
751 | #else | 774 | #else |
752 | static inline int hid_ff_init(struct hid_device *hid) { return -1; } | 775 | #define hid_ff_init NULL |
753 | #endif | 776 | #endif |
754 | 777 | ||
755 | #ifdef CONFIG_HID_DEBUG | 778 | #ifdef CONFIG_HID_DEBUG |
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h index a416b904ba90..6ae77b3468f9 100644 --- a/include/linux/hiddev.h +++ b/include/linux/hiddev.h | |||
@@ -217,7 +217,7 @@ struct hid_field; | |||
217 | struct hid_report; | 217 | struct hid_report; |
218 | 218 | ||
219 | #ifdef CONFIG_USB_HIDDEV | 219 | #ifdef CONFIG_USB_HIDDEV |
220 | int hiddev_connect(struct hid_device *); | 220 | int hiddev_connect(struct hid_device *hid, unsigned int force); |
221 | void hiddev_disconnect(struct hid_device *); | 221 | void hiddev_disconnect(struct hid_device *); |
222 | void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, | 222 | void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, |
223 | struct hid_usage *usage, __s32 value); | 223 | struct hid_usage *usage, __s32 value); |
@@ -225,7 +225,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report); | |||
225 | int __init hiddev_init(void); | 225 | int __init hiddev_init(void); |
226 | void hiddev_exit(void); | 226 | void hiddev_exit(void); |
227 | #else | 227 | #else |
228 | static inline int hiddev_connect(struct hid_device *hid) { return -1; } | 228 | static inline int hiddev_connect(struct hid_device *hid, |
229 | unsigned int force) | ||
230 | { return -1; } | ||
229 | static inline void hiddev_disconnect(struct hid_device *hid) { } | 231 | static inline void hiddev_disconnect(struct hid_device *hid) { } |
230 | static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, | 232 | static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, |
231 | struct hid_usage *usage, __s32 value) { } | 233 | struct hid_usage *usage, __s32 value) { } |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index f3d830747b96..acdeab3d9807 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -724,9 +724,6 @@ static int hidp_start(struct hid_device *hid) | |||
724 | report_list, list) | 724 | report_list, list) |
725 | hidp_send_report(session, report); | 725 | hidp_send_report(session, report); |
726 | 726 | ||
727 | if (hidinput_connect(hid) == 0) | ||
728 | hid->claimed |= HID_CLAIMED_INPUT; | ||
729 | |||
730 | return 0; | 727 | return 0; |
731 | } | 728 | } |
732 | 729 | ||