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 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID fixes from Jiri Kosina:
"The most important fix is Logitech Unifying receiver regression in
device enumeration fix from Nestor Lopez Casado. In addition to that,
there is a small memory leak fix for Thinkpad keyboard driver from
Axel Lin."

* 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
HID: Fix logitech-dj: missing Unifying device issue
HID: lenovo-tpkbd: Fix memory leak in tpkbd_remove_tp()

+48
+2
drivers/hid/hid-lenovo-tpkbd.c
··· 519 519 led_classdev_unregister(&data_pointer->led_mute); 520 520 521 521 hid_set_drvdata(hdev, NULL); 522 + kfree(data_pointer->led_micmute.name); 523 + kfree(data_pointer->led_mute.name); 522 524 kfree(data_pointer); 523 525 } 524 526
+45
drivers/hid/hid-logitech-dj.c
··· 193 193 static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, 194 194 size_t count, 195 195 unsigned char report_type); 196 + static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev); 196 197 197 198 static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev, 198 199 struct dj_report *dj_report) ··· 234 233 if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] & 235 234 SPFUNCTION_DEVICE_LIST_EMPTY) { 236 235 dbg_hid("%s: device list is empty\n", __func__); 236 + djrcv_dev->querying_devices = false; 237 237 return; 238 238 } 239 239 ··· 242 240 (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { 243 241 dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n", 244 242 __func__, dj_report->device_index); 243 + return; 244 + } 245 + 246 + if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { 247 + /* The device is already known. No need to reallocate it. */ 248 + dbg_hid("%s: device is already known\n", __func__); 245 249 return; 246 250 } 247 251 ··· 314 306 struct dj_report dj_report; 315 307 unsigned long flags; 316 308 int count; 309 + int retval; 317 310 318 311 dbg_hid("%s\n", __func__); 319 312 ··· 347 338 logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report); 348 339 break; 349 340 default: 341 + /* A normal report (i. e. not belonging to a pair/unpair notification) 342 + * arriving here, means that the report arrived but we did not have a 343 + * paired dj_device associated to the report's device_index, this 344 + * means that the original "device paired" notification corresponding 345 + * to this dj_device never arrived to this driver. The reason is that 346 + * hid-core discards all packets coming from a device while probe() is 347 + * executing. */ 348 + if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) { 349 + /* ok, we don't know the device, just re-ask the 350 + * receiver for the list of connected devices. */ 351 + retval = logi_dj_recv_query_paired_devices(djrcv_dev); 352 + if (!retval) { 353 + /* everything went fine, so just leave */ 354 + break; 355 + } 356 + dev_err(&djrcv_dev->hdev->dev, 357 + "%s:logi_dj_recv_query_paired_devices " 358 + "error:%d\n", __func__, retval); 359 + } 350 360 dbg_hid("%s: unexpected report type\n", __func__); 351 361 } 352 362 } ··· 396 368 if (!djdev) { 397 369 dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" 398 370 " is NULL, index %d\n", dj_report->device_index); 371 + kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report)); 372 + 373 + if (schedule_work(&djrcv_dev->work) == 0) { 374 + dbg_hid("%s: did not schedule the work item, was already " 375 + "queued\n", __func__); 376 + } 399 377 return; 400 378 } 401 379 ··· 432 398 if (dj_device == NULL) { 433 399 dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" 434 400 " is NULL, index %d\n", dj_report->device_index); 401 + kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report)); 402 + 403 + if (schedule_work(&djrcv_dev->work) == 0) { 404 + dbg_hid("%s: did not schedule the work item, was already " 405 + "queued\n", __func__); 406 + } 435 407 return; 436 408 } 437 409 ··· 479 439 struct dj_report *dj_report; 480 440 int retval; 481 441 442 + /* no need to protect djrcv_dev->querying_devices */ 443 + if (djrcv_dev->querying_devices) 444 + return 0; 445 + 482 446 dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); 483 447 if (!dj_report) 484 448 return -ENOMEM; ··· 493 449 kfree(dj_report); 494 450 return retval; 495 451 } 452 + 496 453 497 454 static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, 498 455 unsigned timeout)
+1
drivers/hid/hid-logitech-dj.h
··· 101 101 struct work_struct work; 102 102 struct kfifo notif_fifo; 103 103 spinlock_t lock; 104 + bool querying_devices; 104 105 }; 105 106 106 107 struct dj_device {