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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull HID fixes from Jiri Kosina:

- fix for OOB in hiddev, from Dmitry Torokhov

- _poll API fixes for hidraw, from Marcel Holtmann

- functional fix for Steam driver, from Rodrigo Rivas Costa

- a few new device IDs / device-specific quirks and other assorted
smaller fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
HID: steam: Fix input device disappearing
HID: intel-ish-hid: ipc: Add Tiger Lake PCI device ID
drivers/hid/hid-multitouch.c: fix a possible null pointer access.
HID: wacom: Recognize new MobileStudio Pro PID
HID: intel-ish-hid: ipc: add CMP device id
HID: hiddev: fix mess in hiddev_open()
HID: hid-input: clear unmapped usages
HID: Add quirk for incorrect input length on Lenovo Y720
HID: asus: Ignore Asus vendor-page usage-code 0xff events
HID: ite: Add USB id match for Acer SW5-012 keyboard dock
HID: Add quirk for Xin-Mo Dual Controller
HID: Fix slab-out-of-bounds read in hid_field_extract
HID: multitouch: Add LG MELF0410 I2C touchscreen support
HID: uhid: Fix returning EPOLLOUT from uhid_char_poll
HID: hidraw: Fix returning EPOLLOUT from hidraw_poll

+101 -69
+2 -1
drivers/hid/hid-asus.c
··· 261 261 struct hid_usage *usage, __s32 value) 262 262 { 263 263 if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 && 264 - (usage->hid & HID_USAGE) != 0x00 && !usage->type) { 264 + (usage->hid & HID_USAGE) != 0x00 && 265 + (usage->hid & HID_USAGE) != 0xff && !usage->type) { 265 266 hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n", 266 267 usage->hid & HID_USAGE); 267 268 }
+6
drivers/hid/hid-core.c
··· 288 288 offset = report->size; 289 289 report->size += parser->global.report_size * parser->global.report_count; 290 290 291 + /* Total size check: Allow for possible report index byte */ 292 + if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) { 293 + hid_err(parser->device, "report is too long\n"); 294 + return -1; 295 + } 296 + 291 297 if (!parser->local.usage_index) /* Ignore padding fields */ 292 298 return 0; 293 299
+3
drivers/hid/hid-ids.h
··· 631 631 #define USB_VENDOR_ID_ITE 0x048d 632 632 #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 633 633 #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 634 + #define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a 634 635 #define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 635 636 #define USB_DEVICE_ID_ITE8595 0x8595 636 637 ··· 731 730 #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 732 731 #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 733 732 #define I2C_DEVICE_ID_LG_8001 0x8001 733 + #define I2C_DEVICE_ID_LG_7010 0x7010 734 734 735 735 #define USB_VENDOR_ID_LOGITECH 0x046d 736 736 #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e ··· 1104 1102 #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 1105 1103 #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 1106 1104 #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 1105 + #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968 1107 1106 #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 1108 1107 #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7 1109 1108
+12 -4
drivers/hid/hid-input.c
··· 1132 1132 } 1133 1133 1134 1134 mapped: 1135 - if (device->driver->input_mapped && device->driver->input_mapped(device, 1136 - hidinput, field, usage, &bit, &max) < 0) 1137 - goto ignore; 1135 + if (device->driver->input_mapped && 1136 + device->driver->input_mapped(device, hidinput, field, usage, 1137 + &bit, &max) < 0) { 1138 + /* 1139 + * The driver indicated that no further generic handling 1140 + * of the usage is desired. 1141 + */ 1142 + return; 1143 + } 1138 1144 1139 1145 set_bit(usage->type, input->evbit); 1140 1146 ··· 1221 1215 set_bit(MSC_SCAN, input->mscbit); 1222 1216 } 1223 1217 1224 - ignore: 1225 1218 return; 1226 1219 1220 + ignore: 1221 + usage->type = 0; 1222 + usage->code = 0; 1227 1223 } 1228 1224 1229 1225 static void hidinput_handle_scroll(struct hid_usage *usage,
+3
drivers/hid/hid-ite.c
··· 40 40 static const struct hid_device_id ite_devices[] = { 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 + /* 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) }, 43 46 { } 44 47 }; 45 48 MODULE_DEVICE_TABLE(hid, ite_devices);
+4 -1
drivers/hid/hid-multitouch.c
··· 1019 1019 tool = MT_TOOL_DIAL; 1020 1020 else if (unlikely(!confidence_state)) { 1021 1021 tool = MT_TOOL_PALM; 1022 - if (!active && 1022 + if (!active && mt && 1023 1023 input_mt_is_active(&mt->slots[slotnum])) { 1024 1024 /* 1025 1025 * The non-confidence was reported for ··· 1985 1985 { .driver_data = MT_CLS_LG, 1986 1986 HID_USB_DEVICE(USB_VENDOR_ID_LG, 1987 1987 USB_DEVICE_ID_LG_MELFAS_MT) }, 1988 + { .driver_data = MT_CLS_LG, 1989 + HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, 1990 + USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) }, 1988 1991 1989 1992 /* MosArt panels */ 1990 1993 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+1
drivers/hid/hid-quirks.c
··· 174 174 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT }, 175 175 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 176 176 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 177 + { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT }, 177 178 178 179 { 0 } 179 180 };
+4
drivers/hid/hid-steam.c
··· 768 768 769 769 if (steam->quirks & STEAM_QUIRK_WIRELESS) { 770 770 hid_info(hdev, "Steam wireless receiver connected"); 771 + /* If using a wireless adaptor ask for connection status */ 772 + steam->connected = false; 771 773 steam_request_conn_status(steam); 772 774 } else { 775 + /* A wired connection is always present */ 776 + steam->connected = true; 773 777 ret = steam_register(steam); 774 778 if (ret) { 775 779 hid_err(hdev,
+2 -2
drivers/hid/hidraw.c
··· 252 252 253 253 poll_wait(file, &list->hidraw->wait, wait); 254 254 if (list->head != list->tail) 255 - return EPOLLIN | EPOLLRDNORM | EPOLLOUT; 255 + return EPOLLIN | EPOLLRDNORM; 256 256 if (!list->hidraw->exist) 257 257 return EPOLLERR | EPOLLHUP; 258 - return 0; 258 + return EPOLLOUT | EPOLLWRNORM; 259 259 } 260 260 261 261 static int hidraw_open(struct inode *inode, struct file *file)
+13 -3
drivers/hid/i2c-hid/i2c-hid-core.c
··· 49 49 #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) 50 50 #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) 51 51 #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) 52 + #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6) 53 + 52 54 53 55 /* flags */ 54 56 #define I2C_HID_STARTED 0 ··· 177 175 I2C_HID_QUIRK_BOGUS_IRQ }, 178 176 { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, 179 177 I2C_HID_QUIRK_RESET_ON_RESUME }, 178 + { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, 179 + I2C_HID_QUIRK_BAD_INPUT_SIZE }, 180 180 { 0, 0 } 181 181 }; 182 182 ··· 500 496 } 501 497 502 498 if ((ret_size > size) || (ret_size < 2)) { 503 - dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", 504 - __func__, size, ret_size); 505 - return; 499 + if (ihid->quirks & I2C_HID_QUIRK_BAD_INPUT_SIZE) { 500 + ihid->inbuf[0] = size & 0xff; 501 + ihid->inbuf[1] = size >> 8; 502 + ret_size = size; 503 + } else { 504 + dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", 505 + __func__, size, ret_size); 506 + return; 507 + } 506 508 } 507 509 508 510 i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf);
+2
drivers/hid/intel-ish-hid/ipc/hw-ish.h
··· 24 24 #define ICL_MOBILE_DEVICE_ID 0x34FC 25 25 #define SPT_H_DEVICE_ID 0xA135 26 26 #define CML_LP_DEVICE_ID 0x02FC 27 + #define CMP_H_DEVICE_ID 0x06FC 27 28 #define EHL_Ax_DEVICE_ID 0x4BB3 29 + #define TGL_LP_DEVICE_ID 0xA0FC 28 30 29 31 #define REVISION_ID_CHT_A0 0x6 30 32 #define REVISION_ID_CHT_Ax_SI 0x0
+2
drivers/hid/intel-ish-hid/ipc/pci-ish.c
··· 34 34 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ICL_MOBILE_DEVICE_ID)}, 35 35 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_H_DEVICE_ID)}, 36 36 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CML_LP_DEVICE_ID)}, 37 + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CMP_H_DEVICE_ID)}, 37 38 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, EHL_Ax_DEVICE_ID)}, 39 + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, TGL_LP_DEVICE_ID)}, 38 40 {0, } 39 41 }; 40 42 MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
+1 -1
drivers/hid/uhid.c
··· 772 772 if (uhid->head != uhid->tail) 773 773 return EPOLLIN | EPOLLRDNORM; 774 774 775 - return 0; 775 + return EPOLLOUT | EPOLLWRNORM; 776 776 } 777 777 778 778 static const struct file_operations uhid_fops = {
+42 -55
drivers/hid/usbhid/hiddev.c
··· 241 241 return 0; 242 242 } 243 243 244 + static int __hiddev_open(struct hiddev *hiddev, struct file *file) 245 + { 246 + struct hiddev_list *list; 247 + int error; 248 + 249 + lockdep_assert_held(&hiddev->existancelock); 250 + 251 + list = vzalloc(sizeof(*list)); 252 + if (!list) 253 + return -ENOMEM; 254 + 255 + mutex_init(&list->thread_lock); 256 + list->hiddev = hiddev; 257 + 258 + if (!hiddev->open++) { 259 + error = hid_hw_power(hiddev->hid, PM_HINT_FULLON); 260 + if (error < 0) 261 + goto err_drop_count; 262 + 263 + error = hid_hw_open(hiddev->hid); 264 + if (error < 0) 265 + goto err_normal_power; 266 + } 267 + 268 + spin_lock_irq(&hiddev->list_lock); 269 + list_add_tail(&list->node, &hiddev->list); 270 + spin_unlock_irq(&hiddev->list_lock); 271 + 272 + file->private_data = list; 273 + 274 + return 0; 275 + 276 + err_normal_power: 277 + hid_hw_power(hiddev->hid, PM_HINT_NORMAL); 278 + err_drop_count: 279 + hiddev->open--; 280 + vfree(list); 281 + return error; 282 + } 283 + 244 284 /* 245 285 * open file op 246 286 */ 247 287 static int hiddev_open(struct inode *inode, struct file *file) 248 288 { 249 - struct hiddev_list *list; 250 289 struct usb_interface *intf; 251 290 struct hid_device *hid; 252 291 struct hiddev *hiddev; ··· 294 255 intf = usbhid_find_interface(iminor(inode)); 295 256 if (!intf) 296 257 return -ENODEV; 258 + 297 259 hid = usb_get_intfdata(intf); 298 260 hiddev = hid->hiddev; 299 261 300 - if (!(list = vzalloc(sizeof(struct hiddev_list)))) 301 - return -ENOMEM; 302 - mutex_init(&list->thread_lock); 303 - list->hiddev = hiddev; 304 - file->private_data = list; 305 - 306 - /* 307 - * no need for locking because the USB major number 308 - * is shared which usbcore guards against disconnect 309 - */ 310 - if (list->hiddev->exist) { 311 - if (!list->hiddev->open++) { 312 - res = hid_hw_open(hiddev->hid); 313 - if (res < 0) 314 - goto bail; 315 - } 316 - } else { 317 - res = -ENODEV; 318 - goto bail; 319 - } 320 - 321 - spin_lock_irq(&list->hiddev->list_lock); 322 - list_add_tail(&list->node, &hiddev->list); 323 - spin_unlock_irq(&list->hiddev->list_lock); 324 - 325 262 mutex_lock(&hiddev->existancelock); 326 - /* 327 - * recheck exist with existance lock held to 328 - * avoid opening a disconnected device 329 - */ 330 - if (!list->hiddev->exist) { 331 - res = -ENODEV; 332 - goto bail_unlock; 333 - } 334 - if (!list->hiddev->open++) 335 - if (list->hiddev->exist) { 336 - struct hid_device *hid = hiddev->hid; 337 - res = hid_hw_power(hid, PM_HINT_FULLON); 338 - if (res < 0) 339 - goto bail_unlock; 340 - res = hid_hw_open(hid); 341 - if (res < 0) 342 - goto bail_normal_power; 343 - } 344 - mutex_unlock(&hiddev->existancelock); 345 - return 0; 346 - bail_normal_power: 347 - hid_hw_power(hid, PM_HINT_NORMAL); 348 - bail_unlock: 263 + res = hiddev->exist ? __hiddev_open(hiddev, file) : -ENODEV; 349 264 mutex_unlock(&hiddev->existancelock); 350 265 351 - spin_lock_irq(&list->hiddev->list_lock); 352 - list_del(&list->node); 353 - spin_unlock_irq(&list->hiddev->list_lock); 354 - bail: 355 - file->private_data = NULL; 356 - vfree(list); 357 266 return res; 358 267 } 359 268
+4 -2
drivers/hid/wacom_wac.c
··· 2096 2096 (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ 2097 2097 hdev->product == 0x357 || hdev->product == 0x358 || /* Intuos Pro 2 */ 2098 2098 hdev->product == 0x392 || /* Intuos Pro 2 */ 2099 - hdev->product == 0x398 || hdev->product == 0x399)) { /* MobileStudio Pro */ 2099 + hdev->product == 0x398 || hdev->product == 0x399 || /* MobileStudio Pro */ 2100 + hdev->product == 0x3AA)) { /* MobileStudio Pro */ 2100 2101 value = (field->logical_maximum - value); 2101 2102 2102 2103 if (hdev->product == 0x357 || hdev->product == 0x358 || 2103 2104 hdev->product == 0x392) 2104 2105 value = wacom_offset_rotation(input, usage, value, 3, 16); 2105 2106 else if (hdev->product == 0x34d || hdev->product == 0x34e || 2106 - hdev->product == 0x398 || hdev->product == 0x399) 2107 + hdev->product == 0x398 || hdev->product == 0x399 || 2108 + hdev->product == 0x3AA) 2107 2109 value = wacom_offset_rotation(input, usage, value, 1, 2); 2108 2110 } 2109 2111 else {