Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-linus-2023110101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID updates from Jiri Kosina:

- fixes for crashes detected by CONFIG_KUNIT_ALL_TESTS in hid-uclogic
driver (Jinjie Ruan)

- HID selftests fixes and improvements (Benjamin Tissoires)

- probe error handling path fixes in hid-nvidia-shield driver
(Christophe JAILLET)

- cleanup of LED handling in hid-nintendo (Martino Fontana)

- big cleanup of logitech-hidpp probe code (Hans de Goede)

- Suspend/Resume fix for USB Thinkpad Compact Keyboard (Jamie Lentin)

- firmware detection improvement for Lenovo cptkbd (Mikhail
Khvainitski)

- IRQ shutdown and workqueue initialization fixes for hid-cp2112 driver
(Danny Kaehn)

- #ifdef CONFIG_PM removal from HID code (Thomas Weißschuh)

- other assorted device-ID additions and quirks

* tag 'for-linus-2023110101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (31 commits)
HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W
HID: logitech-hidpp: Stop IO before calling hid_connect()
HID: logitech-hidpp: Drop HIDPP_QUIRK_UNIFYING
HID: logitech-hidpp: Drop delayed_work_cb()
HID: logitech-hidpp: Fix connect event race
HID: logitech-hidpp: Remove unused connected param from *_connect()
HID: logitech-hidpp: Remove connected check for non-unifying devices
HID: logitech-hidpp: Add hidpp_non_unifying_init() helper
HID: logitech-hidpp: Move hidpp_overwrite_name() to before connect check
HID: logitech-hidpp: Move g920_get_config() to just before hidpp_ff_init()
HID: logitech-hidpp: Remove wtp_get_config() call from probe()
HID: logitech-hidpp: Move get_wireless_feature_index() check to hidpp_connect_event()
HID: logitech-hidpp: Revert "Don't restart communication if not necessary"
HID: logitech-hidpp: Don't restart IO, instead defer hid_connect() only
HID: rmi: remove #ifdef CONFIG_PM
HID: multitouch: remove #ifdef CONFIG_PM
HID: usbhid: remove #ifdef CONFIG_PM
HID: core: remove #ifdef CONFIG_PM from hid_driver
hid: lenovo: Resend all settings on reset_resume for compact keyboards
HID: uclogic: Fix a work->entry not empty bug in __queue_work()
...

+355 -257
+7 -3
drivers/hid/hid-cp2112.c
··· 1151 1151 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1152 1152 struct cp2112_device *dev = gpiochip_get_data(gc); 1153 1153 1154 - INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); 1155 - 1156 1154 if (!dev->gpio_poll) { 1157 1155 dev->gpio_poll = true; 1158 1156 schedule_delayed_work(&dev->gpio_poll_worker, 0); ··· 1166 1168 struct cp2112_device *dev = gpiochip_get_data(gc); 1167 1169 1168 1170 cp2112_gpio_irq_mask(d); 1169 - cancel_delayed_work_sync(&dev->gpio_poll_worker); 1171 + 1172 + if (!dev->irq_mask) { 1173 + dev->gpio_poll = false; 1174 + cancel_delayed_work_sync(&dev->gpio_poll_worker); 1175 + } 1170 1176 } 1171 1177 1172 1178 static int cp2112_gpio_irq_type(struct irq_data *d, unsigned int type) ··· 1308 1306 girq->default_type = IRQ_TYPE_NONE; 1309 1307 girq->handler = handle_simple_irq; 1310 1308 girq->threaded = true; 1309 + 1310 + INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); 1311 1311 1312 1312 ret = gpiochip_add_data(&dev->gc, dev); 1313 1313 if (ret < 0) {
+1
drivers/hid/hid-ids.h
··· 366 366 367 367 #define USB_VENDOR_ID_DELL 0x413c 368 368 #define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE 0x301a 369 + #define USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W 0x4503 369 370 370 371 #define USB_VENDOR_ID_DELORME 0x1163 371 372 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
+81 -41
drivers/hid/hid-lenovo.c
··· 51 51 int select_right; 52 52 int sensitivity; 53 53 int press_speed; 54 - u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ 54 + /* 0: Up 55 + * 1: Down (undecided) 56 + * 2: Scrolling 57 + * 3: Patched firmware, disable workaround 58 + */ 59 + u8 middlebutton_state; 55 60 bool fn_lock; 56 61 }; 57 62 ··· 526 521 int ret; 527 522 struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); 528 523 524 + /* 525 + * Tell the keyboard a driver understands it, and turn F7, F9, F11 into 526 + * regular keys 527 + */ 528 + ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); 529 + if (ret) 530 + hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 531 + 532 + /* Switch middle button to native mode */ 533 + ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); 534 + if (ret) 535 + hid_warn(hdev, "Failed to switch middle button: %d\n", ret); 536 + 529 537 ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); 530 538 if (ret) 531 539 hid_err(hdev, "Fn-lock setting failed: %d\n", ret); ··· 686 668 { 687 669 struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); 688 670 689 - /* "wheel" scroll events */ 690 - if (usage->type == EV_REL && (usage->code == REL_WHEEL || 691 - usage->code == REL_HWHEEL)) { 692 - /* Scroll events disable middle-click event */ 693 - cptkbd_data->middlebutton_state = 2; 694 - return 0; 695 - } 696 - 697 - /* Middle click events */ 698 - if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { 699 - if (value == 1) { 700 - cptkbd_data->middlebutton_state = 1; 701 - } else if (value == 0) { 702 - if (cptkbd_data->middlebutton_state == 1) { 703 - /* No scrolling inbetween, send middle-click */ 704 - input_event(field->hidinput->input, 705 - EV_KEY, BTN_MIDDLE, 1); 706 - input_sync(field->hidinput->input); 707 - input_event(field->hidinput->input, 708 - EV_KEY, BTN_MIDDLE, 0); 709 - input_sync(field->hidinput->input); 710 - } 711 - cptkbd_data->middlebutton_state = 0; 671 + if (cptkbd_data->middlebutton_state != 3) { 672 + /* REL_X and REL_Y events during middle button pressed 673 + * are only possible on patched, bug-free firmware 674 + * so set middlebutton_state to 3 675 + * to never apply workaround anymore 676 + */ 677 + if (cptkbd_data->middlebutton_state == 1 && 678 + usage->type == EV_REL && 679 + (usage->code == REL_X || usage->code == REL_Y)) { 680 + cptkbd_data->middlebutton_state = 3; 681 + /* send middle button press which was hold before */ 682 + input_event(field->hidinput->input, 683 + EV_KEY, BTN_MIDDLE, 1); 684 + input_sync(field->hidinput->input); 712 685 } 713 - return 1; 686 + 687 + /* "wheel" scroll events */ 688 + if (usage->type == EV_REL && (usage->code == REL_WHEEL || 689 + usage->code == REL_HWHEEL)) { 690 + /* Scroll events disable middle-click event */ 691 + cptkbd_data->middlebutton_state = 2; 692 + return 0; 693 + } 694 + 695 + /* Middle click events */ 696 + if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { 697 + if (value == 1) { 698 + cptkbd_data->middlebutton_state = 1; 699 + } else if (value == 0) { 700 + if (cptkbd_data->middlebutton_state == 1) { 701 + /* No scrolling inbetween, send middle-click */ 702 + input_event(field->hidinput->input, 703 + EV_KEY, BTN_MIDDLE, 1); 704 + input_sync(field->hidinput->input); 705 + input_event(field->hidinput->input, 706 + EV_KEY, BTN_MIDDLE, 0); 707 + input_sync(field->hidinput->input); 708 + } 709 + cptkbd_data->middlebutton_state = 0; 710 + } 711 + return 1; 712 + } 714 713 } 715 714 716 715 if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { ··· 1161 1126 } 1162 1127 hid_set_drvdata(hdev, cptkbd_data); 1163 1128 1164 - /* 1165 - * Tell the keyboard a driver understands it, and turn F7, F9, F11 into 1166 - * regular keys (Compact only) 1167 - */ 1168 - if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD || 1169 - hdev->product == USB_DEVICE_ID_LENOVO_CBTKBD) { 1170 - ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); 1171 - if (ret) 1172 - hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 1173 - } 1174 - 1175 - /* Switch middle button to native mode */ 1176 - ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); 1177 - if (ret) 1178 - hid_warn(hdev, "Failed to switch middle button: %d\n", ret); 1179 - 1180 1129 /* Set keyboard settings to known state */ 1181 1130 cptkbd_data->middlebutton_state = 0; 1182 1131 cptkbd_data->fn_lock = true; ··· 1283 1264 return ret; 1284 1265 } 1285 1266 1267 + #ifdef CONFIG_PM 1268 + static int lenovo_reset_resume(struct hid_device *hdev) 1269 + { 1270 + switch (hdev->product) { 1271 + case USB_DEVICE_ID_LENOVO_CUSBKBD: 1272 + case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: 1273 + if (hdev->type == HID_TYPE_USBMOUSE) 1274 + lenovo_features_set_cptkbd(hdev); 1275 + 1276 + break; 1277 + default: 1278 + break; 1279 + } 1280 + 1281 + return 0; 1282 + } 1283 + #endif 1284 + 1286 1285 static void lenovo_remove_tpkbd(struct hid_device *hdev) 1287 1286 { 1288 1287 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); ··· 1417 1380 .raw_event = lenovo_raw_event, 1418 1381 .event = lenovo_event, 1419 1382 .report_fixup = lenovo_report_fixup, 1383 + #ifdef CONFIG_PM 1384 + .reset_resume = lenovo_reset_resume, 1385 + #endif 1420 1386 }; 1421 1387 module_hid_driver(lenovo_driver); 1422 1388
+64 -112
drivers/hid/hid-logitech-hidpp.c
··· 69 69 #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) 70 70 #define HIDPP_QUIRK_DELAYED_INIT BIT(23) 71 71 #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) 72 - #define HIDPP_QUIRK_UNIFYING BIT(25) 73 - #define HIDPP_QUIRK_HIDPP_WHEELS BIT(26) 74 - #define HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS BIT(27) 75 - #define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS BIT(28) 76 - #define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(29) 77 - #define HIDPP_QUIRK_WIRELESS_STATUS BIT(30) 72 + #define HIDPP_QUIRK_HIDPP_WHEELS BIT(25) 73 + #define HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS BIT(26) 74 + #define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS BIT(27) 75 + #define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(28) 76 + #define HIDPP_QUIRK_WIRELESS_STATUS BIT(29) 78 77 79 78 /* These are just aliases for now */ 80 79 #define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS ··· 193 194 194 195 struct work_struct work; 195 196 struct kfifo delayed_work_fifo; 196 - atomic_t connected; 197 197 struct input_dev *delayed_input; 198 198 199 199 unsigned long quirks; ··· 232 234 #define HIDPP20_ERROR_BUSY 0x08 233 235 #define HIDPP20_ERROR_UNSUPPORTED 0x09 234 236 #define HIDPP20_ERROR 0xff 235 - 236 - static void hidpp_connect_event(struct hidpp_device *hidpp_dev); 237 237 238 238 static int __hidpp_send_report(struct hid_device *hdev, 239 239 struct hidpp_report *hidpp_report) ··· 444 448 ret = hidpp_send_message_sync(hidpp_dev, message, response); 445 449 kfree(message); 446 450 return ret; 447 - } 448 - 449 - static void delayed_work_cb(struct work_struct *work) 450 - { 451 - struct hidpp_device *hidpp = container_of(work, struct hidpp_device, 452 - work); 453 - hidpp_connect_event(hidpp); 454 451 } 455 452 456 453 static inline bool hidpp_match_answer(struct hidpp_report *question, ··· 1824 1835 /* -------------------------------------------------------------------------- */ 1825 1836 #define HIDPP_PAGE_WIRELESS_DEVICE_STATUS 0x1d4b 1826 1837 1827 - static int hidpp_set_wireless_feature_index(struct hidpp_device *hidpp) 1838 + static int hidpp_get_wireless_feature_index(struct hidpp_device *hidpp, u8 *feature_index) 1828 1839 { 1829 1840 u8 feature_type; 1830 1841 int ret; 1831 1842 1832 1843 ret = hidpp_root_get_feature(hidpp, 1833 1844 HIDPP_PAGE_WIRELESS_DEVICE_STATUS, 1834 - &hidpp->wireless_feature_index, 1835 - &feature_type); 1845 + feature_index, &feature_type); 1836 1846 1837 1847 return ret; 1838 1848 } ··· 3130 3142 return 0; 3131 3143 }; 3132 3144 3133 - static int wtp_connect(struct hid_device *hdev, bool connected) 3145 + static int wtp_connect(struct hid_device *hdev) 3134 3146 { 3135 3147 struct hidpp_device *hidpp = hid_get_drvdata(hdev); 3136 3148 struct wtp_data *wd = hidpp->private_data; ··· 3192 3204 #define M560_SUB_ID 0x0a 3193 3205 #define M560_BUTTON_MODE_REGISTER 0x35 3194 3206 3195 - static int m560_send_config_command(struct hid_device *hdev, bool connected) 3207 + static int m560_send_config_command(struct hid_device *hdev) 3196 3208 { 3197 3209 struct hidpp_report response; 3198 3210 struct hidpp_device *hidpp_dev; ··· 3387 3399 return 0; 3388 3400 }; 3389 3401 3390 - static int k400_connect(struct hid_device *hdev, bool connected) 3402 + static int k400_connect(struct hid_device *hdev) 3391 3403 { 3392 3404 struct hidpp_device *hidpp = hid_get_drvdata(hdev); 3393 3405 ··· 3882 3894 } 3883 3895 3884 3896 if (unlikely(hidpp_report_is_connect_event(hidpp, report))) { 3885 - atomic_set(&hidpp->connected, 3886 - !(report->rap.params[0] & (1 << 6))); 3887 3897 if (schedule_work(&hidpp->work) == 0) 3888 3898 dbg_hid("%s: connect event already queued\n", __func__); 3889 3899 return 1; ··· 4117 4131 return ret; 4118 4132 } 4119 4133 4120 - static void hidpp_overwrite_name(struct hid_device *hdev) 4134 + /* Get name + serial for USB and Bluetooth HID++ devices */ 4135 + static void hidpp_non_unifying_init(struct hidpp_device *hidpp) 4121 4136 { 4122 - struct hidpp_device *hidpp = hid_get_drvdata(hdev); 4137 + struct hid_device *hdev = hidpp->hid_dev; 4123 4138 char *name; 4124 4139 4125 - if (hidpp->protocol_major < 2) 4126 - return; 4140 + /* Bluetooth devices already have their serialnr set */ 4141 + if (hid_is_usb(hdev)) 4142 + hidpp_serial_init(hidpp); 4127 4143 4128 4144 name = hidpp_get_device_name(hidpp); 4129 - 4130 - if (!name) { 4131 - hid_err(hdev, "unable to retrieve the name of the device"); 4132 - } else { 4145 + if (name) { 4133 4146 dbg_hid("HID++: Got name: %s\n", name); 4134 4147 snprintf(hdev->name, sizeof(hdev->name), "%s", name); 4148 + kfree(name); 4135 4149 } 4136 - 4137 - kfree(name); 4138 4150 } 4139 4151 4140 4152 static int hidpp_input_open(struct input_dev *dev) ··· 4173 4189 return input_dev; 4174 4190 } 4175 4191 4176 - static void hidpp_connect_event(struct hidpp_device *hidpp) 4192 + static void hidpp_connect_event(struct work_struct *work) 4177 4193 { 4194 + struct hidpp_device *hidpp = container_of(work, struct hidpp_device, work); 4178 4195 struct hid_device *hdev = hidpp->hid_dev; 4179 - int ret = 0; 4180 - bool connected = atomic_read(&hidpp->connected); 4181 4196 struct input_dev *input; 4182 4197 char *name, *devm_name; 4198 + int ret; 4183 4199 4184 - if (!connected) { 4200 + /* Get device version to check if it is connected */ 4201 + ret = hidpp_root_get_protocol_version(hidpp); 4202 + if (ret) { 4203 + hid_info(hidpp->hid_dev, "Disconnected\n"); 4185 4204 if (hidpp->battery.ps) { 4186 4205 hidpp->battery.online = false; 4187 4206 hidpp->battery.status = POWER_SUPPLY_STATUS_UNKNOWN; ··· 4195 4208 } 4196 4209 4197 4210 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { 4198 - ret = wtp_connect(hdev, connected); 4211 + ret = wtp_connect(hdev); 4199 4212 if (ret) 4200 4213 return; 4201 4214 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) { 4202 - ret = m560_send_config_command(hdev, connected); 4215 + ret = m560_send_config_command(hdev); 4203 4216 if (ret) 4204 4217 return; 4205 4218 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) { 4206 - ret = k400_connect(hdev, connected); 4219 + ret = k400_connect(hdev); 4207 4220 if (ret) 4208 4221 return; 4209 4222 } ··· 4226 4239 return; 4227 4240 } 4228 4241 4229 - /* the device is already connected, we can ask for its name and 4230 - * protocol */ 4231 - if (!hidpp->protocol_major) { 4232 - ret = hidpp_root_get_protocol_version(hidpp); 4233 - if (ret) { 4234 - hid_err(hdev, "Can not get the protocol version.\n"); 4235 - return; 4236 - } 4242 + if (hidpp->protocol_major >= 2) { 4243 + u8 feature_index; 4244 + 4245 + if (!hidpp_get_wireless_feature_index(hidpp, &feature_index)) 4246 + hidpp->wireless_feature_index = feature_index; 4237 4247 } 4238 4248 4239 4249 if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) { ··· 4375 4391 { 4376 4392 struct hidpp_device *hidpp; 4377 4393 int ret; 4378 - bool connected; 4379 4394 unsigned int connect_mask = HID_CONNECT_DEFAULT; 4380 - struct hidpp_ff_private_data data; 4381 - bool will_restart = false; 4382 4395 4383 4396 /* report_fixup needs drvdata to be set before we call hid_parse */ 4384 4397 hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); ··· 4404 4423 return hid_hw_start(hdev, HID_CONNECT_DEFAULT); 4405 4424 } 4406 4425 4407 - if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE) 4408 - hidpp->quirks |= HIDPP_QUIRK_UNIFYING; 4409 - 4410 4426 if (id->group == HID_GROUP_LOGITECH_27MHZ_DEVICE && 4411 4427 hidpp_application_equals(hdev, HID_GD_MOUSE)) 4412 4428 hidpp->quirks |= HIDPP_QUIRK_HIDPP_WHEELS | ··· 4423 4445 return ret; 4424 4446 } 4425 4447 4426 - if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT || 4427 - hidpp->quirks & HIDPP_QUIRK_UNIFYING) 4428 - will_restart = true; 4429 - 4430 - INIT_WORK(&hidpp->work, delayed_work_cb); 4448 + INIT_WORK(&hidpp->work, hidpp_connect_event); 4431 4449 mutex_init(&hidpp->send_mutex); 4432 4450 init_waitqueue_head(&hidpp->wait); 4433 4451 ··· 4434 4460 hdev->name); 4435 4461 4436 4462 /* 4437 - * Plain USB connections need to actually call start and open 4438 - * on the transport driver to allow incoming data. 4463 + * First call hid_hw_start(hdev, 0) to allow IO without connecting any 4464 + * hid subdrivers (hid-input, hidraw). This allows retrieving the dev's 4465 + * name and serial number and store these in hdev->name and hdev->uniq, 4466 + * before the hid-input and hidraw drivers expose these to userspace. 4439 4467 */ 4440 - ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask); 4468 + ret = hid_hw_start(hdev, 0); 4441 4469 if (ret) { 4442 4470 hid_err(hdev, "hw start failed\n"); 4443 4471 goto hid_hw_start_fail; ··· 4455 4479 /* Allow incoming packets */ 4456 4480 hid_device_io_start(hdev); 4457 4481 4458 - if (hidpp->quirks & HIDPP_QUIRK_UNIFYING) 4482 + /* Get name + serial, store in hdev->name + hdev->uniq */ 4483 + if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE) 4459 4484 hidpp_unifying_init(hidpp); 4460 - else if (hid_is_usb(hidpp->hid_dev)) 4461 - hidpp_serial_init(hidpp); 4485 + else 4486 + hidpp_non_unifying_init(hidpp); 4462 4487 4463 - connected = hidpp_root_get_protocol_version(hidpp) == 0; 4464 - atomic_set(&hidpp->connected, connected); 4465 - if (!(hidpp->quirks & HIDPP_QUIRK_UNIFYING)) { 4466 - if (!connected) { 4467 - ret = -ENODEV; 4468 - hid_err(hdev, "Device not connected"); 4469 - goto hid_hw_init_fail; 4470 - } 4488 + if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) 4489 + connect_mask &= ~HID_CONNECT_HIDINPUT; 4471 4490 4472 - hidpp_overwrite_name(hdev); 4491 + /* Now export the actual inputs and hidraw nodes to the world */ 4492 + hid_device_io_stop(hdev); 4493 + ret = hid_connect(hdev, connect_mask); 4494 + if (ret) { 4495 + hid_err(hdev, "%s:hid_connect returned error %d\n", __func__, ret); 4496 + goto hid_hw_init_fail; 4473 4497 } 4474 4498 4475 - if (connected && hidpp->protocol_major >= 2) { 4476 - ret = hidpp_set_wireless_feature_index(hidpp); 4477 - if (ret == -ENOENT) 4478 - hidpp->wireless_feature_index = 0; 4479 - else if (ret) 4480 - goto hid_hw_init_fail; 4481 - ret = 0; 4482 - } 4483 - 4484 - if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { 4485 - ret = wtp_get_config(hidpp); 4486 - if (ret) 4487 - goto hid_hw_init_fail; 4488 - } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) { 4489 - ret = g920_get_config(hidpp, &data); 4490 - if (ret) 4491 - goto hid_hw_init_fail; 4492 - } 4493 - 4499 + /* Check for connected devices now that incoming packets will not be disabled again */ 4500 + hid_device_io_start(hdev); 4494 4501 schedule_work(&hidpp->work); 4495 4502 flush_work(&hidpp->work); 4496 4503 4497 - if (will_restart) { 4498 - /* Reset the HID node state */ 4499 - hid_device_io_stop(hdev); 4500 - hid_hw_close(hdev); 4501 - hid_hw_stop(hdev); 4502 - 4503 - if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) 4504 - connect_mask &= ~HID_CONNECT_HIDINPUT; 4505 - 4506 - /* Now export the actual inputs and hidraw nodes to the world */ 4507 - ret = hid_hw_start(hdev, connect_mask); 4508 - if (ret) { 4509 - hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); 4510 - goto hid_hw_start_fail; 4511 - } 4512 - } 4513 - 4514 4504 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { 4515 - ret = hidpp_ff_init(hidpp, &data); 4505 + struct hidpp_ff_private_data data; 4506 + 4507 + ret = g920_get_config(hidpp, &data); 4508 + if (!ret) 4509 + ret = hidpp_ff_init(hidpp, &data); 4510 + 4516 4511 if (ret) 4517 4512 hid_warn(hidpp->hid_dev, 4518 4513 "Unable to initialize force feedback support, errno %d\n", 4519 4514 ret); 4520 4515 } 4521 4516 4517 + /* 4518 + * This relies on logi_dj_ll_close() being a no-op so that DJ connection 4519 + * events will still be received. 4520 + */ 4521 + hid_hw_close(hdev); 4522 4522 return ret; 4523 4523 4524 4524 hid_hw_init_fail:
+3 -7
drivers/hid/hid-multitouch.c
··· 1802 1802 return 0; 1803 1803 } 1804 1804 1805 - #ifdef CONFIG_PM 1806 1805 static int mt_suspend(struct hid_device *hdev, pm_message_t state) 1807 1806 { 1808 1807 struct mt_device *td = hid_get_drvdata(hdev); ··· 1835 1836 1836 1837 return 0; 1837 1838 } 1838 - #endif 1839 1839 1840 1840 static void mt_remove(struct hid_device *hdev) 1841 1841 { ··· 2257 2259 .usage_table = mt_grabbed_usages, 2258 2260 .event = mt_event, 2259 2261 .report = mt_report, 2260 - #ifdef CONFIG_PM 2261 - .suspend = mt_suspend, 2262 - .reset_resume = mt_reset_resume, 2263 - .resume = mt_resume, 2264 - #endif 2262 + .suspend = pm_ptr(mt_suspend), 2263 + .reset_resume = pm_ptr(mt_reset_resume), 2264 + .resume = pm_ptr(mt_resume), 2265 2265 }; 2266 2266 module_hid_driver(mt_driver);
+76 -57
drivers/hid/hid-nintendo.c
··· 410 410 LED_FUNCTION_PLAYER4, 411 411 }; 412 412 #define JC_NUM_LEDS ARRAY_SIZE(joycon_player_led_names) 413 + #define JC_NUM_LED_PATTERNS 8 414 + /* Taken from https://www.nintendo.com/my/support/qa/detail/33822 */ 415 + static const enum led_brightness joycon_player_led_patterns[JC_NUM_LED_PATTERNS][JC_NUM_LEDS] = { 416 + { 1, 0, 0, 0 }, 417 + { 1, 1, 0, 0 }, 418 + { 1, 1, 1, 0 }, 419 + { 1, 1, 1, 1 }, 420 + { 1, 0, 0, 1 }, 421 + { 1, 0, 1, 0 }, 422 + { 1, 0, 1, 1 }, 423 + { 0, 1, 1, 0 }, 424 + }; 413 425 414 426 /* Each physical controller is associated with a joycon_ctlr struct */ 415 427 struct joycon_ctlr { ··· 709 697 710 698 hid_dbg(ctlr->hdev, "setting player leds\n"); 711 699 return joycon_send_subcmd(ctlr, req, 1, HZ/4); 700 + } 701 + 702 + static int joycon_set_home_led(struct joycon_ctlr *ctlr, enum led_brightness brightness) 703 + { 704 + struct joycon_subcmd_request *req; 705 + u8 buffer[sizeof(*req) + 5] = { 0 }; 706 + u8 *data; 707 + 708 + req = (struct joycon_subcmd_request *)buffer; 709 + req->subcmd_id = JC_SUBCMD_SET_HOME_LIGHT; 710 + data = req->data; 711 + data[0] = 0x01; 712 + data[1] = brightness << 4; 713 + data[2] = brightness | (brightness << 4); 714 + data[3] = 0x11; 715 + data[4] = 0x11; 716 + 717 + hid_dbg(ctlr->hdev, "setting home led brightness\n"); 718 + return joycon_send_subcmd(ctlr, req, 5, HZ/4); 712 719 } 713 720 714 721 static int joycon_request_spi_flash_read(struct joycon_ctlr *ctlr, ··· 1871 1840 return 0; 1872 1841 } 1873 1842 1843 + /* Because the subcommand sets all the leds at once, the brightness argument is ignored */ 1874 1844 static int joycon_player_led_brightness_set(struct led_classdev *led, 1875 1845 enum led_brightness brightness) 1876 1846 { ··· 1881 1849 int val = 0; 1882 1850 int i; 1883 1851 int ret; 1884 - int num; 1885 1852 1886 1853 ctlr = hid_get_drvdata(hdev); 1887 1854 if (!ctlr) { ··· 1888 1857 return -ENODEV; 1889 1858 } 1890 1859 1891 - /* determine which player led this is */ 1892 - for (num = 0; num < JC_NUM_LEDS; num++) { 1893 - if (&ctlr->leds[num] == led) 1894 - break; 1895 - } 1896 - if (num >= JC_NUM_LEDS) 1897 - return -EINVAL; 1860 + for (i = 0; i < JC_NUM_LEDS; i++) 1861 + val |= ctlr->leds[i].brightness << i; 1898 1862 1899 1863 mutex_lock(&ctlr->output_mutex); 1900 - for (i = 0; i < JC_NUM_LEDS; i++) { 1901 - if (i == num) 1902 - val |= brightness << i; 1903 - else 1904 - val |= ctlr->leds[i].brightness << i; 1905 - } 1906 1864 ret = joycon_set_player_leds(ctlr, 0, val); 1907 1865 mutex_unlock(&ctlr->output_mutex); 1908 1866 ··· 1904 1884 struct device *dev = led->dev->parent; 1905 1885 struct hid_device *hdev = to_hid_device(dev); 1906 1886 struct joycon_ctlr *ctlr; 1907 - struct joycon_subcmd_request *req; 1908 - u8 buffer[sizeof(*req) + 5] = { 0 }; 1909 - u8 *data; 1910 1887 int ret; 1911 1888 1912 1889 ctlr = hid_get_drvdata(hdev); ··· 1911 1894 hid_err(hdev, "No controller data\n"); 1912 1895 return -ENODEV; 1913 1896 } 1914 - 1915 - req = (struct joycon_subcmd_request *)buffer; 1916 - req->subcmd_id = JC_SUBCMD_SET_HOME_LIGHT; 1917 - data = req->data; 1918 - data[0] = 0x01; 1919 - data[1] = brightness << 4; 1920 - data[2] = brightness | (brightness << 4); 1921 - data[3] = 0x11; 1922 - data[4] = 0x11; 1923 - 1924 - hid_dbg(hdev, "setting home led brightness\n"); 1925 1897 mutex_lock(&ctlr->output_mutex); 1926 - ret = joycon_send_subcmd(ctlr, req, 5, HZ/4); 1898 + ret = joycon_set_home_led(ctlr, brightness); 1927 1899 mutex_unlock(&ctlr->output_mutex); 1928 - 1929 1900 return ret; 1930 1901 } 1931 1902 1932 - static DEFINE_MUTEX(joycon_input_num_mutex); 1903 + static DEFINE_SPINLOCK(joycon_input_num_spinlock); 1933 1904 static int joycon_leds_create(struct joycon_ctlr *ctlr) 1934 1905 { 1935 1906 struct hid_device *hdev = ctlr->hdev; 1936 1907 struct device *dev = &hdev->dev; 1937 1908 const char *d_name = dev_name(dev); 1938 1909 struct led_classdev *led; 1910 + int led_val = 0; 1939 1911 char *name; 1940 - int ret = 0; 1912 + int ret; 1941 1913 int i; 1942 - static int input_num = 1; 1914 + unsigned long flags; 1915 + int player_led_pattern; 1916 + static int input_num; 1943 1917 1944 - /* Set the default controller player leds based on controller number */ 1945 - mutex_lock(&joycon_input_num_mutex); 1946 - mutex_lock(&ctlr->output_mutex); 1947 - ret = joycon_set_player_leds(ctlr, 0, 0xF >> (4 - input_num)); 1948 - if (ret) 1949 - hid_warn(ctlr->hdev, "Failed to set leds; ret=%d\n", ret); 1950 - mutex_unlock(&ctlr->output_mutex); 1918 + /* 1919 + * Set the player leds based on controller number 1920 + * Because there is no standard concept of "player number", the pattern 1921 + * number will simply increase by 1 every time a controller is connected. 1922 + */ 1923 + spin_lock_irqsave(&joycon_input_num_spinlock, flags); 1924 + player_led_pattern = input_num++ % JC_NUM_LED_PATTERNS; 1925 + spin_unlock_irqrestore(&joycon_input_num_spinlock, flags); 1951 1926 1952 1927 /* configure the player LEDs */ 1953 1928 for (i = 0; i < JC_NUM_LEDS; i++) { ··· 1947 1938 d_name, 1948 1939 "green", 1949 1940 joycon_player_led_names[i]); 1950 - if (!name) { 1951 - mutex_unlock(&joycon_input_num_mutex); 1941 + if (!name) 1952 1942 return -ENOMEM; 1953 - } 1954 1943 1955 1944 led = &ctlr->leds[i]; 1956 1945 led->name = name; 1957 - led->brightness = ((i + 1) <= input_num) ? 1 : 0; 1946 + led->brightness = joycon_player_led_patterns[player_led_pattern][i]; 1958 1947 led->max_brightness = 1; 1959 1948 led->brightness_set_blocking = 1960 1949 joycon_player_led_brightness_set; 1961 1950 led->flags = LED_CORE_SUSPENDRESUME | LED_HW_PLUGGABLE; 1962 1951 1952 + led_val |= joycon_player_led_patterns[player_led_pattern][i] << i; 1953 + } 1954 + mutex_lock(&ctlr->output_mutex); 1955 + ret = joycon_set_player_leds(ctlr, 0, led_val); 1956 + mutex_unlock(&ctlr->output_mutex); 1957 + if (ret) { 1958 + hid_warn(hdev, "Failed to set players LEDs, skipping registration; ret=%d\n", ret); 1959 + goto home_led; 1960 + } 1961 + 1962 + for (i = 0; i < JC_NUM_LEDS; i++) { 1963 + led = &ctlr->leds[i]; 1963 1964 ret = devm_led_classdev_register(&hdev->dev, led); 1964 1965 if (ret) { 1965 - hid_err(hdev, "Failed registering %s LED\n", led->name); 1966 - mutex_unlock(&joycon_input_num_mutex); 1966 + hid_err(hdev, "Failed to register player %d LED; ret=%d\n", i + 1, ret); 1967 1967 return ret; 1968 1968 } 1969 1969 } 1970 1970 1971 - if (++input_num > 4) 1972 - input_num = 1; 1973 - mutex_unlock(&joycon_input_num_mutex); 1974 - 1971 + home_led: 1975 1972 /* configure the home LED */ 1976 1973 if (jc_type_has_right(ctlr)) { 1977 1974 name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s:%s", ··· 1993 1978 led->max_brightness = 0xF; 1994 1979 led->brightness_set_blocking = joycon_home_led_brightness_set; 1995 1980 led->flags = LED_CORE_SUSPENDRESUME | LED_HW_PLUGGABLE; 1981 + 1982 + /* Set the home LED to 0 as default state */ 1983 + mutex_lock(&ctlr->output_mutex); 1984 + ret = joycon_set_home_led(ctlr, 0); 1985 + mutex_unlock(&ctlr->output_mutex); 1986 + if (ret) { 1987 + hid_warn(hdev, "Failed to set home LED, skipping registration; ret=%d\n", ret); 1988 + return 0; 1989 + } 1990 + 1996 1991 ret = devm_led_classdev_register(&hdev->dev, led); 1997 1992 if (ret) { 1998 - hid_err(hdev, "Failed registering home led\n"); 1993 + hid_err(hdev, "Failed to register home LED; ret=%d\n", ret); 1999 1994 return ret; 2000 - } 2001 - /* Set the home LED to 0 as default state */ 2002 - ret = joycon_home_led_brightness_set(led, 0); 2003 - if (ret) { 2004 - hid_warn(hdev, "Failed to set home LED default, unregistering home LED"); 2005 - devm_led_classdev_unregister(&hdev->dev, led); 2006 1995 } 2007 1996 } 2008 1997
+11 -10
drivers/hid/hid-nvidia-shield.c
··· 915 915 return ERR_PTR(ret); 916 916 } 917 917 918 + static void thunderstrike_destroy(struct thunderstrike *ts) 919 + { 920 + led_classdev_unregister(&ts->led_dev); 921 + power_supply_unregister(ts->base.battery_dev.psy); 922 + if (ts->haptics_dev) 923 + input_unregister_device(ts->haptics_dev); 924 + ida_free(&thunderstrike_ida, ts->id); 925 + } 926 + 918 927 static int android_input_mapping(struct hid_device *hdev, struct hid_input *hi, 919 928 struct hid_field *field, 920 929 struct hid_usage *usage, unsigned long **bit, ··· 1083 1074 err_stop: 1084 1075 hid_hw_stop(hdev); 1085 1076 err_ts_create: 1086 - power_supply_unregister(ts->base.battery_dev.psy); 1087 - if (ts->haptics_dev) 1088 - input_unregister_device(ts->haptics_dev); 1089 - led_classdev_unregister(&ts->led_dev); 1090 - ida_free(&thunderstrike_ida, ts->id); 1077 + thunderstrike_destroy(ts); 1091 1078 return ret; 1092 1079 } 1093 1080 ··· 1095 1090 ts = container_of(dev, struct thunderstrike, base); 1096 1091 1097 1092 hid_hw_close(hdev); 1098 - power_supply_unregister(dev->battery_dev.psy); 1099 - if (ts->haptics_dev) 1100 - input_unregister_device(ts->haptics_dev); 1101 - led_classdev_unregister(&ts->led_dev); 1102 - ida_free(&thunderstrike_ida, ts->id); 1093 + thunderstrike_destroy(ts); 1103 1094 del_timer_sync(&ts->psy_stats_timer); 1104 1095 cancel_work_sync(&ts->hostcmd_req_work); 1105 1096 hid_hw_stop(hdev);
+1
drivers/hid/hid-quirks.c
··· 66 66 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, 67 67 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET }, 68 68 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, 69 + { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W), HID_QUIRK_ALWAYS_POLL }, 69 70 { HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET }, 70 71 { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT }, 71 72 { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT },
+3 -7
drivers/hid/hid-rmi.c
··· 436 436 input_sync(field->hidinput->input); 437 437 } 438 438 439 - #ifdef CONFIG_PM 440 439 static int rmi_suspend(struct hid_device *hdev, pm_message_t message) 441 440 { 442 441 struct rmi_data *data = hid_get_drvdata(hdev); ··· 482 483 hid_hw_close(hdev); 483 484 return ret; 484 485 } 485 - #endif /* CONFIG_PM */ 486 486 487 487 static int rmi_hid_reset(struct rmi_transport_dev *xport, u16 reset_addr) 488 488 { ··· 772 774 .report = rmi_report, 773 775 .input_mapping = rmi_input_mapping, 774 776 .input_configured = rmi_input_configured, 775 - #ifdef CONFIG_PM 776 - .suspend = rmi_suspend, 777 - .resume = rmi_post_resume, 778 - .reset_resume = rmi_post_resume, 779 - #endif 777 + .suspend = pm_ptr(rmi_suspend), 778 + .resume = pm_ptr(rmi_post_resume), 779 + .reset_resume = pm_ptr(rmi_post_resume), 780 780 }; 781 781 782 782 module_hid_driver(rmi_driver);
+7
drivers/hid/hid-uclogic-core-test.c
··· 56 56 }, 57 57 }; 58 58 59 + static void fake_work(struct work_struct *work) 60 + { 61 + 62 + } 63 + 59 64 static void hid_test_uclogic_exec_event_hook_test(struct kunit *test) 60 65 { 61 66 struct uclogic_params p = {0, }; ··· 81 76 filter->event = kunit_kzalloc(test, filter->size, GFP_KERNEL); 82 77 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filter->event); 83 78 memcpy(filter->event, &hook_events[n].event[0], filter->size); 79 + 80 + INIT_WORK(&filter->work, fake_work); 84 81 85 82 list_add_tail(&filter->list, &p.event_hooks->list); 86 83 }
+15 -1
drivers/hid/hid-uclogic-params-test.c
··· 174 174 KUNIT_EXPECT_EQ(test, params->frame_type, frame_type); 175 175 } 176 176 177 + struct fake_device { 178 + unsigned long quirks; 179 + }; 180 + 177 181 static void hid_test_uclogic_params_cleanup_event_hooks(struct kunit *test) 178 182 { 179 183 int res, n; 184 + struct hid_device *hdev; 185 + struct fake_device *fake_dev; 180 186 struct uclogic_params p = {0, }; 181 187 182 - res = uclogic_params_ugee_v2_init_event_hooks(NULL, &p); 188 + hdev = kunit_kzalloc(test, sizeof(struct hid_device), GFP_KERNEL); 189 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hdev); 190 + 191 + fake_dev = kunit_kzalloc(test, sizeof(struct fake_device), GFP_KERNEL); 192 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_dev); 193 + 194 + hid_set_drvdata(hdev, fake_dev); 195 + 196 + res = uclogic_params_ugee_v2_init_event_hooks(hdev, &p); 183 197 KUNIT_ASSERT_EQ(test, res, 0); 184 198 185 199 /* Check that the function can be called repeatedly */
+3 -8
drivers/hid/usbhid/hid-core.c
··· 1562 1562 return 0; 1563 1563 } 1564 1564 1565 - #ifdef CONFIG_PM 1566 1565 static int hid_resume_common(struct hid_device *hid, bool driver_suspended) 1567 1566 { 1568 1567 int status = 0; ··· 1653 1654 return status; 1654 1655 } 1655 1656 1656 - #endif /* CONFIG_PM */ 1657 - 1658 1657 static const struct usb_device_id hid_usb_ids[] = { 1659 1658 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, 1660 1659 .bInterfaceClass = USB_INTERFACE_CLASS_HID }, ··· 1665 1668 .name = "usbhid", 1666 1669 .probe = usbhid_probe, 1667 1670 .disconnect = usbhid_disconnect, 1668 - #ifdef CONFIG_PM 1669 - .suspend = hid_suspend, 1670 - .resume = hid_resume, 1671 - .reset_resume = hid_reset_resume, 1672 - #endif 1671 + .suspend = pm_ptr(hid_suspend), 1672 + .resume = pm_ptr(hid_resume), 1673 + .reset_resume = pm_ptr(hid_reset_resume), 1673 1674 .pre_reset = hid_pre_reset, 1674 1675 .post_reset = hid_post_reset, 1675 1676 .id_table = hid_usb_ids,
+2 -2
include/linux/hid.h
··· 833 833 void (*feature_mapping)(struct hid_device *hdev, 834 834 struct hid_field *field, 835 835 struct hid_usage *usage); 836 - #ifdef CONFIG_PM 836 + 837 837 int (*suspend)(struct hid_device *hdev, pm_message_t message); 838 838 int (*resume)(struct hid_device *hdev); 839 839 int (*reset_resume)(struct hid_device *hdev); 840 - #endif 840 + 841 841 /* private: */ 842 842 struct device_driver driver; 843 843 };
+4 -6
tools/testing/selftests/hid/Makefile
··· 21 21 22 22 HOSTPKG_CONFIG := pkg-config 23 23 24 - CFLAGS += -g -O0 -rdynamic -Wall -Werror -I$(KHDR_INCLUDES) -I$(OUTPUT) 24 + CFLAGS += -g -O0 -rdynamic -Wall -Werror -I$(OUTPUT) 25 + CFLAGS += -I$(OUTPUT)/tools/include 26 + 25 27 LDLIBS += -lelf -lz -lrt -lpthread 26 28 27 29 # Silence some warnings when compiled with clang ··· 67 65 SCRATCH_DIR := $(OUTPUT)/tools 68 66 BUILD_DIR := $(SCRATCH_DIR)/build 69 67 INCLUDE_DIR := $(SCRATCH_DIR)/include 70 - KHDR_INCLUDES := $(SCRATCH_DIR)/uapi/include 71 68 BPFOBJ := $(BUILD_DIR)/libbpf/libbpf.a 72 69 ifneq ($(CROSS_COMPILE),) 73 70 HOST_BUILD_DIR := $(BUILD_DIR)/host ··· 152 151 $(Q)cp "$(VMLINUX_H)" $@ 153 152 endif 154 153 155 - $(KHDR_INCLUDES)/linux/hid.h: $(top_srcdir)/include/uapi/linux/hid.h 156 - $(MAKE) -C $(top_srcdir) INSTALL_HDR_PATH=$(SCRATCH_DIR)/uapi headers_install 157 - 158 154 $(RESOLVE_BTFIDS): $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/resolve_btfids \ 159 155 $(TOOLSDIR)/bpf/resolve_btfids/main.c \ 160 156 $(TOOLSDIR)/lib/rbtree.c \ ··· 229 231 $(Q)$(BPFTOOL) gen object $(<:.o=.linked1.o) $< 230 232 $(Q)$(BPFTOOL) gen skeleton $(<:.o=.linked1.o) name $(notdir $(<:.bpf.o=)) > $@ 231 233 232 - $(OUTPUT)/%.o: %.c $(BPF_SKELS) $(KHDR_INCLUDES)/linux/hid.h 234 + $(OUTPUT)/%.o: %.c $(BPF_SKELS) 233 235 $(call msg,CC,,$@) 234 236 $(Q)$(CC) $(CFLAGS) -c $(filter %.c,$^) $(LDLIBS) -o $@ 235 237
-3
tools/testing/selftests/hid/progs/hid.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (c) 2022 Red hat */ 3 - #include "vmlinux.h" 4 - #include <bpf/bpf_helpers.h> 5 - #include <bpf/bpf_tracing.h> 6 3 #include "hid_bpf_helpers.h" 7 4 8 5 char _license[] SEC("license") = "GPL";
+77
tools/testing/selftests/hid/progs/hid_bpf_helpers.h
··· 5 5 #ifndef __HID_BPF_HELPERS_H 6 6 #define __HID_BPF_HELPERS_H 7 7 8 + /* "undefine" structs and enums in vmlinux.h, because we "override" them below */ 9 + #define hid_bpf_ctx hid_bpf_ctx___not_used 10 + #define hid_report_type hid_report_type___not_used 11 + #define hid_class_request hid_class_request___not_used 12 + #define hid_bpf_attach_flags hid_bpf_attach_flags___not_used 13 + #define HID_INPUT_REPORT HID_INPUT_REPORT___not_used 14 + #define HID_OUTPUT_REPORT HID_OUTPUT_REPORT___not_used 15 + #define HID_FEATURE_REPORT HID_FEATURE_REPORT___not_used 16 + #define HID_REPORT_TYPES HID_REPORT_TYPES___not_used 17 + #define HID_REQ_GET_REPORT HID_REQ_GET_REPORT___not_used 18 + #define HID_REQ_GET_IDLE HID_REQ_GET_IDLE___not_used 19 + #define HID_REQ_GET_PROTOCOL HID_REQ_GET_PROTOCOL___not_used 20 + #define HID_REQ_SET_REPORT HID_REQ_SET_REPORT___not_used 21 + #define HID_REQ_SET_IDLE HID_REQ_SET_IDLE___not_used 22 + #define HID_REQ_SET_PROTOCOL HID_REQ_SET_PROTOCOL___not_used 23 + #define HID_BPF_FLAG_NONE HID_BPF_FLAG_NONE___not_used 24 + #define HID_BPF_FLAG_INSERT_HEAD HID_BPF_FLAG_INSERT_HEAD___not_used 25 + #define HID_BPF_FLAG_MAX HID_BPF_FLAG_MAX___not_used 26 + 27 + #include "vmlinux.h" 28 + 29 + #undef hid_bpf_ctx 30 + #undef hid_report_type 31 + #undef hid_class_request 32 + #undef hid_bpf_attach_flags 33 + #undef HID_INPUT_REPORT 34 + #undef HID_OUTPUT_REPORT 35 + #undef HID_FEATURE_REPORT 36 + #undef HID_REPORT_TYPES 37 + #undef HID_REQ_GET_REPORT 38 + #undef HID_REQ_GET_IDLE 39 + #undef HID_REQ_GET_PROTOCOL 40 + #undef HID_REQ_SET_REPORT 41 + #undef HID_REQ_SET_IDLE 42 + #undef HID_REQ_SET_PROTOCOL 43 + #undef HID_BPF_FLAG_NONE 44 + #undef HID_BPF_FLAG_INSERT_HEAD 45 + #undef HID_BPF_FLAG_MAX 46 + 47 + #include <bpf/bpf_helpers.h> 48 + #include <bpf/bpf_tracing.h> 49 + #include <linux/const.h> 50 + 51 + enum hid_report_type { 52 + HID_INPUT_REPORT = 0, 53 + HID_OUTPUT_REPORT = 1, 54 + HID_FEATURE_REPORT = 2, 55 + 56 + HID_REPORT_TYPES, 57 + }; 58 + 59 + struct hid_bpf_ctx { 60 + __u32 index; 61 + const struct hid_device *hid; 62 + __u32 allocated_size; 63 + enum hid_report_type report_type; 64 + union { 65 + __s32 retval; 66 + __s32 size; 67 + }; 68 + } __attribute__((preserve_access_index)); 69 + 70 + enum hid_class_request { 71 + HID_REQ_GET_REPORT = 0x01, 72 + HID_REQ_GET_IDLE = 0x02, 73 + HID_REQ_GET_PROTOCOL = 0x03, 74 + HID_REQ_SET_REPORT = 0x09, 75 + HID_REQ_SET_IDLE = 0x0A, 76 + HID_REQ_SET_PROTOCOL = 0x0B, 77 + }; 78 + 79 + enum hid_bpf_attach_flags { 80 + HID_BPF_FLAG_NONE = 0, 81 + HID_BPF_FLAG_INSERT_HEAD = _BITUL(0), 82 + HID_BPF_FLAG_MAX, 83 + }; 84 + 8 85 /* following are kfuncs exported by HID for HID-BPF */ 9 86 extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, 10 87 unsigned int offset,