Commit 93c10132a7ac160df3175b53f7ee857625412165
Committed by
Jiri Kosina
1 parent
fea6f1833b
Exists in
master
and in
7 other branches
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 <jirislaby@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Showing 17 changed files with 159 additions and 126 deletions Side-by-side Diff
- 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
drivers/hid/hid-a4tech.c
drivers/hid/hid-apple.c
... | ... | @@ -309,6 +309,7 @@ |
309 | 309 | { |
310 | 310 | unsigned long quirks = id->driver_data; |
311 | 311 | struct apple_sc *asc; |
312 | + unsigned int connect_mask = HID_CONNECT_DEFAULT; | |
312 | 313 | int ret; |
313 | 314 | |
314 | 315 | /* return something else or move to hid layer? device will reside |
315 | 316 | |
... | ... | @@ -328,18 +329,18 @@ |
328 | 329 | |
329 | 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 | 332 | ret = hid_parse(hdev); |
337 | 333 | if (ret) { |
338 | 334 | dev_err(&hdev->dev, "parse failed\n"); |
339 | 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 | 344 | if (ret) { |
344 | 345 | dev_err(&hdev->dev, "hw start failed\n"); |
345 | 346 | goto err_free; |
drivers/hid/hid-belkin.c
... | ... | @@ -54,16 +54,14 @@ |
54 | 54 | |
55 | 55 | hid_set_drvdata(hdev, (void *)quirks); |
56 | 56 | |
57 | - if (quirks & BELKIN_HIDDEV) | |
58 | - hdev->quirks |= HID_QUIRK_HIDDEV; | |
59 | - | |
60 | 57 | ret = hid_parse(hdev); |
61 | 58 | if (ret) { |
62 | 59 | dev_err(&hdev->dev, "parse failed\n"); |
63 | 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 | 65 | if (ret) { |
68 | 66 | dev_err(&hdev->dev, "hw start failed\n"); |
69 | 67 | goto err_free; |
drivers/hid/hid-core.c
... | ... | @@ -1113,6 +1113,80 @@ |
1113 | 1113 | } |
1114 | 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 | 1190 | static bool hid_match_one_id(struct hid_device *hdev, |
1117 | 1191 | const struct hid_device_id *id) |
1118 | 1192 | { |
... | ... | @@ -1238,7 +1312,7 @@ |
1238 | 1312 | } else { /* default probe */ |
1239 | 1313 | ret = hid_parse(hdev); |
1240 | 1314 | if (!ret) |
1241 | - ret = hid_hw_start(hdev); | |
1315 | + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | |
1242 | 1316 | } |
1243 | 1317 | if (ret) |
1244 | 1318 | hdev->driver = NULL; |
drivers/hid/hid-cypress.c
drivers/hid/hid-dell.c
drivers/hid/hid-input.c
... | ... | @@ -700,7 +700,7 @@ |
700 | 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 | 705 | struct hid_report *report; |
706 | 706 | struct hid_input *hidinput = NULL; |
707 | 707 | |
708 | 708 | |
... | ... | @@ -708,19 +708,20 @@ |
708 | 708 | int i, j, k; |
709 | 709 | int max_report_type = HID_OUTPUT_REPORT; |
710 | 710 | |
711 | - if (hid->quirks & HID_QUIRK_IGNORE_HIDINPUT) | |
712 | - return -1; | |
713 | - | |
714 | 711 | INIT_LIST_HEAD(&hid->inputs); |
715 | 712 | |
716 | - for (i = 0; i < hid->maxcollection; i++) | |
717 | - if (hid->collection[i].type == HID_COLLECTION_APPLICATION || | |
718 | - hid->collection[i].type == HID_COLLECTION_PHYSICAL) | |
719 | - if (IS_INPUT_APPLICATION(hid->collection[i].usage)) | |
720 | - break; | |
713 | + if (!force) { | |
714 | + for (i = 0; i < hid->maxcollection; i++) { | |
715 | + struct hid_collection *col = &hid->collection[i]; | |
716 | + if (col->type == HID_COLLECTION_APPLICATION || | |
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) | |
723 | - return -1; | |
722 | + if (i == hid->maxcollection) | |
723 | + return -1; | |
724 | + } | |
724 | 725 | |
725 | 726 | if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) |
726 | 727 | max_report_type = HID_INPUT_REPORT; |
drivers/hid/hid-logitech.c
drivers/hid/hid-microsoft.c
... | ... | @@ -154,8 +154,6 @@ |
154 | 154 | |
155 | 155 | hid_set_drvdata(hdev, (void *)quirks); |
156 | 156 | |
157 | - if (quirks & MS_HIDINPUT) | |
158 | - hdev->quirks |= HID_QUIRK_HIDINPUT; | |
159 | 157 | if (quirks & MS_NOGET) |
160 | 158 | hdev->quirks |= HID_QUIRK_NOGET; |
161 | 159 | |
... | ... | @@ -165,7 +163,8 @@ |
165 | 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 | 168 | if (ret) { |
170 | 169 | dev_err(&hdev->dev, "hw start failed\n"); |
171 | 170 | goto err_free; |
drivers/hid/hid-petalynx.c
drivers/hid/hid-samsung.c
... | ... | @@ -52,15 +52,14 @@ |
52 | 52 | { |
53 | 53 | int ret; |
54 | 54 | |
55 | - hdev->quirks |= HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT; | |
56 | - | |
57 | 55 | ret = hid_parse(hdev); |
58 | 56 | if (ret) { |
59 | 57 | dev_err(&hdev->dev, "parse failed\n"); |
60 | 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 | 63 | if (ret) { |
65 | 64 | dev_err(&hdev->dev, "hw start failed\n"); |
66 | 65 | goto err_free; |
drivers/hid/hid-sony.c
... | ... | @@ -57,15 +57,14 @@ |
57 | 57 | { |
58 | 58 | int ret; |
59 | 59 | |
60 | - hdev->quirks |= HID_QUIRK_HIDDEV; | |
61 | - | |
62 | 60 | ret = hid_parse(hdev); |
63 | 61 | if (ret) { |
64 | 62 | dev_err(&hdev->dev, "parse failed\n"); |
65 | 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 | 68 | if (ret) { |
70 | 69 | dev_err(&hdev->dev, "hw start failed\n"); |
71 | 70 | goto err_free; |
drivers/hid/usbhid/hid-core.c
... | ... | @@ -44,8 +44,6 @@ |
44 | 44 | #define DRIVER_DESC "USB HID core driver" |
45 | 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 | 48 | * Module parameters. |
51 | 49 | */ |
... | ... | @@ -670,70 +668,6 @@ |
670 | 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 | 671 | static int usbhid_parse(struct hid_device *hid) |
738 | 672 | { |
739 | 673 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); |
740 | 674 | |
... | ... | @@ -923,10 +857,12 @@ |
923 | 857 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; |
924 | 858 | usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); |
925 | 859 | |
926 | - ret = usbhid_start_finish(hid); | |
927 | - if (ret) | |
928 | - goto fail; | |
860 | + usbhid_init_reports(hid); | |
861 | + hid_dump_device(hid); | |
929 | 862 | |
863 | + if (hid->quirks & HID_QUIRK_RESET_LEDS) | |
864 | + usbhid_set_leds(hid); | |
865 | + | |
930 | 866 | return 0; |
931 | 867 | |
932 | 868 | fail: |
933 | 869 | |
... | ... | @@ -1000,7 +936,9 @@ |
1000 | 936 | usb_set_intfdata(intf, hid); |
1001 | 937 | hid->ll_driver = &usb_hid_driver; |
1002 | 938 | hid->hid_output_raw_report = usbhid_output_raw_report; |
939 | + hid->ff_init = hid_ff_init; | |
1003 | 940 | #ifdef CONFIG_USB_HIDDEV |
941 | + hid->hiddev_connect = hiddev_connect; | |
1004 | 942 | hid->hiddev_hid_event = hiddev_hid_event; |
1005 | 943 | hid->hiddev_report_event = hiddev_report_event; |
1006 | 944 | #endif |
drivers/hid/usbhid/hiddev.c
... | ... | @@ -790,21 +790,23 @@ |
790 | 790 | /* |
791 | 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 | 795 | struct hiddev *hiddev; |
796 | 796 | struct usbhid_device *usbhid = hid->driver_data; |
797 | - int i; | |
798 | 797 | int retval; |
799 | 798 | |
800 | - for (i = 0; i < hid->maxcollection; i++) | |
801 | - if (hid->collection[i].type == | |
802 | - HID_COLLECTION_APPLICATION && | |
803 | - !IS_INPUT_APPLICATION(hid->collection[i].usage)) | |
804 | - break; | |
799 | + if (!force) { | |
800 | + unsigned int i; | |
801 | + for (i = 0; i < hid->maxcollection; i++) | |
802 | + if (hid->collection[i].type == | |
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 | - return -1; | |
807 | + if (i == hid->maxcollection) | |
808 | + return -1; | |
809 | + } | |
808 | 810 | |
809 | 811 | if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) |
810 | 812 | return -1; |
include/linux/hid.h
... | ... | @@ -247,6 +247,19 @@ |
247 | 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 | 263 | * HID device quirks. |
251 | 264 | */ |
252 | 265 | |
253 | 266 | |
... | ... | @@ -258,13 +271,10 @@ |
258 | 271 | #define HID_QUIRK_INVERT 0x00000001 |
259 | 272 | #define HID_QUIRK_NOTOUCH 0x00000002 |
260 | 273 | #define HID_QUIRK_NOGET 0x00000008 |
261 | -#define HID_QUIRK_HIDDEV 0x00000010 | |
262 | 274 | #define HID_QUIRK_BADPAD 0x00000020 |
263 | 275 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
264 | 276 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
265 | 277 | #define HID_QUIRK_RESET_LEDS 0x00100000 |
266 | -#define HID_QUIRK_HIDINPUT 0x00200000 | |
267 | -#define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 | |
268 | 278 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 |
269 | 279 | |
270 | 280 | /* |
271 | 281 | |
... | ... | @@ -439,7 +449,11 @@ |
439 | 449 | |
440 | 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 | 455 | /* hiddev event handler */ |
456 | + int (*hiddev_connect)(struct hid_device *, unsigned int); | |
443 | 457 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, |
444 | 458 | struct hid_usage *, __s32); |
445 | 459 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); |
... | ... | @@ -610,7 +624,7 @@ |
610 | 624 | |
611 | 625 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); |
612 | 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 | 628 | extern void hidinput_disconnect(struct hid_device *); |
615 | 629 | |
616 | 630 | int hid_set_field(struct hid_field *, unsigned, __s32); |
... | ... | @@ -619,6 +633,7 @@ |
619 | 633 | void hid_output_report(struct hid_report *report, __u8 *data); |
620 | 634 | struct hid_device *hid_allocate_device(void); |
621 | 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 | 639 | * hid_map_usage - map usage input bits |
625 | 640 | |
626 | 641 | |
... | ... | @@ -700,14 +715,22 @@ |
700 | 715 | * hid_hw_start - start underlaying HW |
701 | 716 | * |
702 | 717 | * @hdev: hid device |
718 | + * @connect_mask: which outputs to connect, see HID_CONNECT_* | |
703 | 719 | * |
704 | 720 | * Call this in probe function *after* hid_parse. This will setup HW buffers |
705 | 721 | * and start the device (if not deffered to device open). hid_hw_stop must be |
706 | 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 @@ |
749 | 772 | #endif |
750 | 773 | |
751 | 774 | #else |
752 | -static inline int hid_ff_init(struct hid_device *hid) { return -1; } | |
775 | +#define hid_ff_init NULL | |
753 | 776 | #endif |
754 | 777 | |
755 | 778 | #ifdef CONFIG_HID_DEBUG |
include/linux/hiddev.h
... | ... | @@ -217,7 +217,7 @@ |
217 | 217 | struct hid_report; |
218 | 218 | |
219 | 219 | #ifdef CONFIG_USB_HIDDEV |
220 | -int hiddev_connect(struct hid_device *); | |
220 | +int hiddev_connect(struct hid_device *hid, unsigned int force); | |
221 | 221 | void hiddev_disconnect(struct hid_device *); |
222 | 222 | void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, |
223 | 223 | struct hid_usage *usage, __s32 value); |
... | ... | @@ -225,7 +225,9 @@ |
225 | 225 | int __init hiddev_init(void); |
226 | 226 | void hiddev_exit(void); |
227 | 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 | 231 | static inline void hiddev_disconnect(struct hid_device *hid) { } |
230 | 232 | static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, |
231 | 233 | struct hid_usage *usage, __s32 value) { } |