Skip to content

Commit 278de45

Browse files
committed
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
2 parents e46bfab + 4eb1b01 commit 278de45

File tree

9 files changed

+64
-36
lines changed

9 files changed

+64
-36
lines changed

drivers/hid/hid-alps.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
730730
if (data->has_sp) {
731731
input2 = input_allocate_device();
732732
if (!input2) {
733-
input_free_device(input2);
733+
ret = -ENOMEM;
734734
goto exit;
735735
}
736736

drivers/hid/hid-apple.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
340340
unsigned long **bit, int *max)
341341
{
342342
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)) {
344345
/* The fn key on Apple USB keyboards */
345346
set_bit(EV_REP, hi->input->evbit);
346347
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);

drivers/hid/hid-bigbenff.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ static __u8 pid0902_rdesc_fixed[] = {
174174
struct bigben_device {
175175
struct hid_device *hid;
176176
struct hid_report *report;
177+
bool removed;
177178
u8 led_state; /* LED1 = 1 .. LED4 = 8 */
178179
u8 right_motor_on; /* right motor off/on 0/1 */
179180
u8 left_motor_force; /* left motor force 0-255 */
@@ -190,6 +191,9 @@ static void bigben_worker(struct work_struct *work)
190191
struct bigben_device, worker);
191192
struct hid_field *report_field = bigben->report->field[0];
192193

194+
if (bigben->removed)
195+
return;
196+
193197
if (bigben->work_led) {
194198
bigben->work_led = false;
195199
report_field->value[0] = 0x01; /* 1 = led message */
@@ -220,10 +224,16 @@ static void bigben_worker(struct work_struct *work)
220224
static int hid_bigben_play_effect(struct input_dev *dev, void *data,
221225
struct ff_effect *effect)
222226
{
223-
struct bigben_device *bigben = data;
227+
struct hid_device *hid = input_get_drvdata(dev);
228+
struct bigben_device *bigben = hid_get_drvdata(hid);
224229
u8 right_motor_on;
225230
u8 left_motor_force;
226231

232+
if (!bigben) {
233+
hid_err(hid, "no device data\n");
234+
return 0;
235+
}
236+
227237
if (effect->type != FF_RUMBLE)
228238
return 0;
229239

@@ -298,8 +308,8 @@ static void bigben_remove(struct hid_device *hid)
298308
{
299309
struct bigben_device *bigben = hid_get_drvdata(hid);
300310

311+
bigben->removed = true;
301312
cancel_work_sync(&bigben->worker);
302-
hid_hw_close(hid);
303313
hid_hw_stop(hid);
304314
}
305315

@@ -319,6 +329,7 @@ static int bigben_probe(struct hid_device *hid,
319329
return -ENOMEM;
320330
hid_set_drvdata(hid, bigben);
321331
bigben->hid = hid;
332+
bigben->removed = false;
322333

323334
error = hid_parse(hid);
324335
if (error) {
@@ -341,10 +352,10 @@ static int bigben_probe(struct hid_device *hid,
341352

342353
INIT_WORK(&bigben->worker, bigben_worker);
343354

344-
error = input_ff_create_memless(hidinput->input, bigben,
355+
error = input_ff_create_memless(hidinput->input, NULL,
345356
hid_bigben_play_effect);
346357
if (error)
347-
return error;
358+
goto error_hw_stop;
348359

349360
name_sz = strlen(dev_name(&hid->dev)) + strlen(":red:bigben#") + 1;
350361

@@ -354,8 +365,10 @@ static int bigben_probe(struct hid_device *hid,
354365
sizeof(struct led_classdev) + name_sz,
355366
GFP_KERNEL
356367
);
357-
if (!led)
358-
return -ENOMEM;
368+
if (!led) {
369+
error = -ENOMEM;
370+
goto error_hw_stop;
371+
}
359372
name = (void *)(&led[1]);
360373
snprintf(name, name_sz,
361374
"%s:red:bigben%d",
@@ -369,7 +382,7 @@ static int bigben_probe(struct hid_device *hid,
369382
bigben->leds[n] = led;
370383
error = devm_led_classdev_register(&hid->dev, led);
371384
if (error)
372-
return error;
385+
goto error_hw_stop;
373386
}
374387

375388
/* initial state: LED1 is on, no rumble effect */
@@ -383,6 +396,10 @@ static int bigben_probe(struct hid_device *hid,
383396
hid_info(hid, "LED and force feedback support for BigBen gamepad\n");
384397

385398
return 0;
399+
400+
error_hw_stop:
401+
hid_hw_stop(hid);
402+
return error;
386403
}
387404

388405
static __u8 *bigben_report_fixup(struct hid_device *hid, __u8 *rdesc,

drivers/hid/hid-core.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1741,7 +1741,9 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
17411741

17421742
rsize = ((report->size - 1) >> 3) + 1;
17431743

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)
17451747
rsize = HID_MAX_BUFFER_SIZE;
17461748

17471749
if (csize < rsize) {

drivers/hid/hid-ite.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ static const struct hid_device_id ite_devices[] = {
4141
{ HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) },
4242
{ HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) },
4343
/* 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) },
4647
{ }
4748
};
4849
MODULE_DEVICE_TABLE(hid, ite_devices);

drivers/hid/hid-logitech-hidpp.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,36 +1256,35 @@ static int hidpp20_battery_map_status_voltage(u8 data[3], int *voltage,
12561256
{
12571257
int status;
12581258

1259-
long charge_sts = (long)data[2];
1259+
long flags = (long) data[2];
12601260

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
12711278
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-
}
12791279

12801280
*charge_type = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
1281-
if (test_bit(3, &charge_sts)) {
1281+
if (test_bit(3, &flags)) {
12821282
*charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
12831283
}
1284-
if (test_bit(4, &charge_sts)) {
1284+
if (test_bit(4, &flags)) {
12851285
*charge_type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
12861286
}
1287-
1288-
if (test_bit(5, &charge_sts)) {
1287+
if (test_bit(5, &flags)) {
12891288
*level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
12901289
}
12911290

drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
341341
},
342342
.driver_data = (void *)&sipodev_desc
343343
},
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+
},
344352
{
345353
.ident = "Direkt-Tek DTLAPY116-2",
346354
.matches = {

drivers/hid/usbhid/hiddev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,9 +932,9 @@ void hiddev_disconnect(struct hid_device *hid)
932932
hiddev->exist = 0;
933933

934934
if (hiddev->open) {
935-
mutex_unlock(&hiddev->existancelock);
936935
hid_hw_close(hiddev->hid);
937936
wake_up_interruptible(&hiddev->wait);
937+
mutex_unlock(&hiddev->existancelock);
938938
} else {
939939
mutex_unlock(&hiddev->existancelock);
940940
kfree(hiddev);

include/linux/hid.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ struct hid_report_enum {
492492
};
493493

494494
#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 */
496496
#define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */
497497
#define HID_OUTPUT_FIFO_SIZE 64
498498

0 commit comments

Comments
 (0)