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

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

Pull HID subsystem fixes from Jiri Kosina:

- syzkaller-reported error handling fixes in various drivers, from
various people

- increase of HID report buffer size to 8K, which is apparently needed
by certain modern devices

- a few new device-ID-specific fixes / quirks

- battery charging status reporting fix in logitech-hidpp, from Filipe
Laíns

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
HID: hid-bigbenff: fix race condition for scheduled work during removal
HID: hid-bigbenff: call hid_hw_stop() in case of error
HID: hid-bigbenff: fix general protection fault caused by double kfree
HID: i2c-hid: add Trekstor Surfbook E11B to descriptor override
HID: alps: Fix an error handling path in 'alps_input_configured()'
HID: hiddev: Fix race in in hiddev_disconnect()
HID: core: increase HID report buffer size to 8KiB
HID: core: fix off-by-one memset in hid_report_raw_event()
HID: apple: Add support for recent firmware on Magic Keyboards
HID: ite: Only bind to keyboard USB interface on Acer SW5-012 keyboard dock
HID: logitech-hidpp: BatteryVoltage: only read chargeStatus if extPower is active

+64 -36
+1 -1
drivers/hid/hid-alps.c
··· 730 730 if (data->has_sp) { 731 731 input2 = input_allocate_device(); 732 732 if (!input2) { 733 - input_free_device(input2); 733 + ret = -ENOMEM; 734 734 goto exit; 735 735 } 736 736
+2 -1
drivers/hid/hid-apple.c
··· 340 340 unsigned long **bit, int *max) 341 341 { 342 342 if (usage->hid == (HID_UP_CUSTOM | 0x0003) || 343 - usage->hid == (HID_UP_MSVENDOR | 0x0003)) { 343 + usage->hid == (HID_UP_MSVENDOR | 0x0003) || 344 + usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { 344 345 /* The fn key on Apple USB keyboards */ 345 346 set_bit(EV_REP, hi->input->evbit); 346 347 hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
+24 -7
drivers/hid/hid-bigbenff.c
··· 174 174 struct bigben_device { 175 175 struct hid_device *hid; 176 176 struct hid_report *report; 177 + bool removed; 177 178 u8 led_state; /* LED1 = 1 .. LED4 = 8 */ 178 179 u8 right_motor_on; /* right motor off/on 0/1 */ 179 180 u8 left_motor_force; /* left motor force 0-255 */ ··· 190 189 struct bigben_device *bigben = container_of(work, 191 190 struct bigben_device, worker); 192 191 struct hid_field *report_field = bigben->report->field[0]; 192 + 193 + if (bigben->removed) 194 + return; 193 195 194 196 if (bigben->work_led) { 195 197 bigben->work_led = false; ··· 224 220 static int hid_bigben_play_effect(struct input_dev *dev, void *data, 225 221 struct ff_effect *effect) 226 222 { 227 - struct bigben_device *bigben = data; 223 + struct hid_device *hid = input_get_drvdata(dev); 224 + struct bigben_device *bigben = hid_get_drvdata(hid); 228 225 u8 right_motor_on; 229 226 u8 left_motor_force; 227 + 228 + if (!bigben) { 229 + hid_err(hid, "no device data\n"); 230 + return 0; 231 + } 230 232 231 233 if (effect->type != FF_RUMBLE) 232 234 return 0; ··· 308 298 { 309 299 struct bigben_device *bigben = hid_get_drvdata(hid); 310 300 301 + bigben->removed = true; 311 302 cancel_work_sync(&bigben->worker); 312 - hid_hw_close(hid); 313 303 hid_hw_stop(hid); 314 304 } 315 305 ··· 329 319 return -ENOMEM; 330 320 hid_set_drvdata(hid, bigben); 331 321 bigben->hid = hid; 322 + bigben->removed = false; 332 323 333 324 error = hid_parse(hid); 334 325 if (error) { ··· 352 341 353 342 INIT_WORK(&bigben->worker, bigben_worker); 354 343 355 - error = input_ff_create_memless(hidinput->input, bigben, 344 + error = input_ff_create_memless(hidinput->input, NULL, 356 345 hid_bigben_play_effect); 357 346 if (error) 358 - return error; 347 + goto error_hw_stop; 359 348 360 349 name_sz = strlen(dev_name(&hid->dev)) + strlen(":red:bigben#") + 1; 361 350 ··· 365 354 sizeof(struct led_classdev) + name_sz, 366 355 GFP_KERNEL 367 356 ); 368 - if (!led) 369 - return -ENOMEM; 357 + if (!led) { 358 + error = -ENOMEM; 359 + goto error_hw_stop; 360 + } 370 361 name = (void *)(&led[1]); 371 362 snprintf(name, name_sz, 372 363 "%s:red:bigben%d", ··· 382 369 bigben->leds[n] = led; 383 370 error = devm_led_classdev_register(&hid->dev, led); 384 371 if (error) 385 - return error; 372 + goto error_hw_stop; 386 373 } 387 374 388 375 /* initial state: LED1 is on, no rumble effect */ ··· 396 383 hid_info(hid, "LED and force feedback support for BigBen gamepad\n"); 397 384 398 385 return 0; 386 + 387 + error_hw_stop: 388 + hid_hw_stop(hid); 389 + return error; 399 390 } 400 391 401 392 static __u8 *bigben_report_fixup(struct hid_device *hid, __u8 *rdesc,
+3 -1
drivers/hid/hid-core.c
··· 1741 1741 1742 1742 rsize = ((report->size - 1) >> 3) + 1; 1743 1743 1744 - if (rsize > HID_MAX_BUFFER_SIZE) 1744 + if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) 1745 + rsize = HID_MAX_BUFFER_SIZE - 1; 1746 + else if (rsize > HID_MAX_BUFFER_SIZE) 1745 1747 rsize = HID_MAX_BUFFER_SIZE; 1746 1748 1747 1749 if (csize < rsize) {
+3 -2
drivers/hid/hid-ite.c
··· 41 41 { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, 42 42 { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, 43 43 /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ 44 - { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, 45 - USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, 44 + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 45 + USB_VENDOR_ID_SYNAPTICS, 46 + USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, 46 47 { } 47 48 }; 48 49 MODULE_DEVICE_TABLE(hid, ite_devices);
+21 -22
drivers/hid/hid-logitech-hidpp.c
··· 1256 1256 { 1257 1257 int status; 1258 1258 1259 - long charge_sts = (long)data[2]; 1259 + long flags = (long) data[2]; 1260 1260 1261 - *level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; 1262 - switch (data[2] & 0xe0) { 1263 - case 0x00: 1264 - status = POWER_SUPPLY_STATUS_CHARGING; 1265 - break; 1266 - case 0x20: 1267 - status = POWER_SUPPLY_STATUS_FULL; 1268 - *level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; 1269 - break; 1270 - case 0x40: 1261 + if (flags & 0x80) 1262 + switch (flags & 0x07) { 1263 + case 0: 1264 + status = POWER_SUPPLY_STATUS_CHARGING; 1265 + break; 1266 + case 1: 1267 + status = POWER_SUPPLY_STATUS_FULL; 1268 + *level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; 1269 + break; 1270 + case 2: 1271 + status = POWER_SUPPLY_STATUS_NOT_CHARGING; 1272 + break; 1273 + default: 1274 + status = POWER_SUPPLY_STATUS_UNKNOWN; 1275 + break; 1276 + } 1277 + else 1271 1278 status = POWER_SUPPLY_STATUS_DISCHARGING; 1272 - break; 1273 - case 0xe0: 1274 - status = POWER_SUPPLY_STATUS_NOT_CHARGING; 1275 - break; 1276 - default: 1277 - status = POWER_SUPPLY_STATUS_UNKNOWN; 1278 - } 1279 1279 1280 1280 *charge_type = POWER_SUPPLY_CHARGE_TYPE_STANDARD; 1281 - if (test_bit(3, &charge_sts)) { 1281 + if (test_bit(3, &flags)) { 1282 1282 *charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST; 1283 1283 } 1284 - if (test_bit(4, &charge_sts)) { 1284 + if (test_bit(4, &flags)) { 1285 1285 *charge_type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; 1286 1286 } 1287 - 1288 - if (test_bit(5, &charge_sts)) { 1287 + if (test_bit(5, &flags)) { 1289 1288 *level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; 1290 1289 } 1291 1290
+8
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
··· 342 342 .driver_data = (void *)&sipodev_desc 343 343 }, 344 344 { 345 + .ident = "Trekstor SURFBOOK E11B", 346 + .matches = { 347 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), 348 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"), 349 + }, 350 + .driver_data = (void *)&sipodev_desc 351 + }, 352 + { 345 353 .ident = "Direkt-Tek DTLAPY116-2", 346 354 .matches = { 347 355 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
+1 -1
drivers/hid/usbhid/hiddev.c
··· 932 932 hiddev->exist = 0; 933 933 934 934 if (hiddev->open) { 935 - mutex_unlock(&hiddev->existancelock); 936 935 hid_hw_close(hiddev->hid); 937 936 wake_up_interruptible(&hiddev->wait); 937 + mutex_unlock(&hiddev->existancelock); 938 938 } else { 939 939 mutex_unlock(&hiddev->existancelock); 940 940 kfree(hiddev);
+1 -1
include/linux/hid.h
··· 492 492 }; 493 493 494 494 #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ 495 - #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ 495 + #define HID_MAX_BUFFER_SIZE 8192 /* 8kb */ 496 496 #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ 497 497 #define HID_OUTPUT_FIFO_SIZE 64 498 498