Commit 008464a9 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull HID fixes from Jiri Kosina:

 - quirk for Toshiba Click Mini L9W-B, from Hans de Goede

 - intel-ish-hid and wacom error handling (device freeing) path fixes
   from Arvind Yadav

 - memory corruption fix in intel-ish-hid driver from Hans de Goede

 - a few new device ID additions to hid-lenovo from Peter Ganzhorn

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: i2c-hid: Add RESEND_REPORT_DESCR quirk for Toshiba Click Mini L9W-B
  HID: intel-ish-hid: use put_device() instead of kfree()
  HID: intel_ish-hid: Stop using a static local buffer in get_report()
  HID: intel_ish-hid: Move header size check to inside the loop
  HID: wacom: Release device resource data obtained by devres_alloc()
  HID: lenovo: Add support for IBM/Lenovo Scrollpoint mice
parents 036db8bd 070b9637
...@@ -462,10 +462,11 @@ config HID_LENOVO ...@@ -462,10 +462,11 @@ config HID_LENOVO
select NEW_LEDS select NEW_LEDS
select LEDS_CLASS select LEDS_CLASS
---help--- ---help---
Support for Lenovo devices that are not fully compliant with HID standard. Support for IBM/Lenovo devices that are not fully compliant with HID standard.
Say Y if you want support for the non-compliant features of the Lenovo Say Y if you want support for horizontal scrolling of the IBM/Lenovo
Thinkpad standalone keyboards, e.g: Scrollpoint mice or the non-compliant features of the Lenovo Thinkpad
standalone keyboards, e.g:
- ThinkPad USB Keyboard with TrackPoint (supports extra LEDs and trackpoint - ThinkPad USB Keyboard with TrackPoint (supports extra LEDs and trackpoint
configuration) configuration)
- ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys) - ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys)
......
...@@ -552,6 +552,13 @@ ...@@ -552,6 +552,13 @@
#define USB_VENDOR_ID_HUION 0x256c #define USB_VENDOR_ID_HUION 0x256c
#define USB_DEVICE_ID_HUION_TABLET 0x006e #define USB_DEVICE_ID_HUION_TABLET 0x006e
#define USB_VENDOR_ID_IBM 0x04b3
#define USB_DEVICE_ID_IBM_SCROLLPOINT_III 0x3100
#define USB_DEVICE_ID_IBM_SCROLLPOINT_PRO 0x3103
#define USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL 0x3105
#define USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL 0x3108
#define USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO 0x3109
#define USB_VENDOR_ID_IDEACOM 0x1cb6 #define USB_VENDOR_ID_IDEACOM 0x1cb6
#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
#define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651
...@@ -684,6 +691,7 @@ ...@@ -684,6 +691,7 @@
#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009 #define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
#define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047 #define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
#define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048
#define USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL 0x6049
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085
#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3
...@@ -964,6 +972,7 @@ ...@@ -964,6 +972,7 @@
#define USB_DEVICE_ID_SIS817_TOUCH 0x0817 #define USB_DEVICE_ID_SIS817_TOUCH 0x0817
#define USB_DEVICE_ID_SIS_TS 0x1013 #define USB_DEVICE_ID_SIS_TS 0x1013
#define USB_DEVICE_ID_SIS1030_TOUCH 0x1030 #define USB_DEVICE_ID_SIS1030_TOUCH 0x1030
#define USB_DEVICE_ID_SIS10FB_TOUCH 0x10fb
#define USB_VENDOR_ID_SKYCABLE 0x1223 #define USB_VENDOR_ID_SKYCABLE 0x1223
#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
......
...@@ -6,6 +6,17 @@ ...@@ -6,6 +6,17 @@
* *
* Copyright (c) 2012 Bernhard Seibold * Copyright (c) 2012 Bernhard Seibold
* Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk> * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk>
*
* Linux IBM/Lenovo Scrollpoint mouse driver:
* - IBM Scrollpoint III
* - IBM Scrollpoint Pro
* - IBM Scrollpoint Optical
* - IBM Scrollpoint Optical 800dpi
* - IBM Scrollpoint Optical 800dpi Pro
* - Lenovo Scrollpoint Optical
*
* Copyright (c) 2012 Peter De Wachter <pdewacht@gmail.com>
* Copyright (c) 2018 Peter Ganzhorn <peter.ganzhorn@gmail.com>
*/ */
/* /*
...@@ -160,6 +171,17 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, ...@@ -160,6 +171,17 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev,
return 0; return 0;
} }
static int lenovo_input_mapping_scrollpoint(struct hid_device *hdev,
struct hid_input *hi, struct hid_field *field,
struct hid_usage *usage, unsigned long **bit, int *max)
{
if (usage->hid == HID_GD_Z) {
hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
return 1;
}
return 0;
}
static int lenovo_input_mapping(struct hid_device *hdev, static int lenovo_input_mapping(struct hid_device *hdev,
struct hid_input *hi, struct hid_field *field, struct hid_input *hi, struct hid_field *field,
struct hid_usage *usage, unsigned long **bit, int *max) struct hid_usage *usage, unsigned long **bit, int *max)
...@@ -172,6 +194,14 @@ static int lenovo_input_mapping(struct hid_device *hdev, ...@@ -172,6 +194,14 @@ static int lenovo_input_mapping(struct hid_device *hdev,
case USB_DEVICE_ID_LENOVO_CBTKBD: case USB_DEVICE_ID_LENOVO_CBTKBD:
return lenovo_input_mapping_cptkbd(hdev, hi, field, return lenovo_input_mapping_cptkbd(hdev, hi, field,
usage, bit, max); usage, bit, max);
case USB_DEVICE_ID_IBM_SCROLLPOINT_III:
case USB_DEVICE_ID_IBM_SCROLLPOINT_PRO:
case USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL:
case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL:
case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO:
case USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL:
return lenovo_input_mapping_scrollpoint(hdev, hi, field,
usage, bit, max);
default: default:
return 0; return 0;
} }
...@@ -883,6 +913,12 @@ static const struct hid_device_id lenovo_devices[] = { ...@@ -883,6 +913,12 @@ static const struct hid_device_id lenovo_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_III) },
{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_PRO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL) },
{ } { }
}; };
......
...@@ -174,6 +174,8 @@ static const struct i2c_hid_quirks { ...@@ -174,6 +174,8 @@ static const struct i2c_hid_quirks {
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
{ I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118, { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118,
I2C_HID_QUIRK_RESEND_REPORT_DESCR }, I2C_HID_QUIRK_RESEND_REPORT_DESCR },
{ USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS10FB_TOUCH,
I2C_HID_QUIRK_RESEND_REPORT_DESCR },
{ 0, 0 } { 0, 0 }
}; };
......
...@@ -77,21 +77,21 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf, ...@@ -77,21 +77,21 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data;
int curr_hid_dev = client_data->cur_hid_dev; int curr_hid_dev = client_data->cur_hid_dev;
if (data_len < sizeof(struct hostif_msg_hdr)) {
dev_err(&client_data->cl_device->dev,
"[hid-ish]: error, received %u which is less than data header %u\n",
(unsigned int)data_len,
(unsigned int)sizeof(struct hostif_msg_hdr));
++client_data->bad_recv_cnt;
ish_hw_reset(hid_ishtp_cl->dev);
return;
}
payload = recv_buf + sizeof(struct hostif_msg_hdr); payload = recv_buf + sizeof(struct hostif_msg_hdr);
total_len = data_len; total_len = data_len;
cur_pos = 0; cur_pos = 0;
do { do {
if (cur_pos + sizeof(struct hostif_msg) > total_len) {
dev_err(&client_data->cl_device->dev,
"[hid-ish]: error, received %u which is less than data header %u\n",
(unsigned int)data_len,
(unsigned int)sizeof(struct hostif_msg_hdr));
++client_data->bad_recv_cnt;
ish_hw_reset(hid_ishtp_cl->dev);
break;
}
recv_msg = (struct hostif_msg *)(recv_buf + cur_pos); recv_msg = (struct hostif_msg *)(recv_buf + cur_pos);
payload_len = recv_msg->hdr.size; payload_len = recv_msg->hdr.size;
...@@ -412,9 +412,7 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id, ...@@ -412,9 +412,7 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id,
{ {
struct ishtp_hid_data *hid_data = hid->driver_data; struct ishtp_hid_data *hid_data = hid->driver_data;
struct ishtp_cl_data *client_data = hid_data->client_data; struct ishtp_cl_data *client_data = hid_data->client_data;
static unsigned char buf[10]; struct hostif_msg_to_sensor msg = {};
unsigned int len;
struct hostif_msg_to_sensor *msg = (struct hostif_msg_to_sensor *)buf;
int rv; int rv;
int i; int i;
...@@ -426,14 +424,11 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id, ...@@ -426,14 +424,11 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id,
return; return;
} }
len = sizeof(struct hostif_msg_to_sensor); msg.hdr.command = (report_type == HID_FEATURE_REPORT) ?
memset(msg, 0, sizeof(struct hostif_msg_to_sensor));
msg->hdr.command = (report_type == HID_FEATURE_REPORT) ?
HOSTIF_GET_FEATURE_REPORT : HOSTIF_GET_INPUT_REPORT; HOSTIF_GET_FEATURE_REPORT : HOSTIF_GET_INPUT_REPORT;
for (i = 0; i < client_data->num_hid_devices; ++i) { for (i = 0; i < client_data->num_hid_devices; ++i) {
if (hid == client_data->hid_sensor_hubs[i]) { if (hid == client_data->hid_sensor_hubs[i]) {
msg->hdr.device_id = msg.hdr.device_id =
client_data->hid_devices[i].dev_id; client_data->hid_devices[i].dev_id;
break; break;
} }
...@@ -442,8 +437,9 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id, ...@@ -442,8 +437,9 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id,
if (i == client_data->num_hid_devices) if (i == client_data->num_hid_devices)
return; return;
msg->report_id = report_id; msg.report_id = report_id;
rv = ishtp_cl_send(client_data->hid_ishtp_cl, buf, len); rv = ishtp_cl_send(client_data->hid_ishtp_cl, (uint8_t *)&msg,
sizeof(msg));
if (rv) if (rv)
hid_ishtp_trace(client_data, "%s hid %p send failed\n", hid_ishtp_trace(client_data, "%s hid %p send failed\n",
__func__, hid); __func__, hid);
......
...@@ -418,7 +418,7 @@ static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev, ...@@ -418,7 +418,7 @@ static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev,
list_del(&device->device_link); list_del(&device->device_link);
spin_unlock_irqrestore(&dev->device_list_lock, flags); spin_unlock_irqrestore(&dev->device_list_lock, flags);
dev_err(dev->devc, "Failed to register ISHTP client device\n"); dev_err(dev->devc, "Failed to register ISHTP client device\n");
kfree(device); put_device(&device->dev);
return NULL; return NULL;
} }
......
...@@ -1213,8 +1213,10 @@ static int __wacom_devm_sysfs_create_group(struct wacom *wacom, ...@@ -1213,8 +1213,10 @@ static int __wacom_devm_sysfs_create_group(struct wacom *wacom,
devres->root = root; devres->root = root;
error = sysfs_create_group(devres->root, group); error = sysfs_create_group(devres->root, group);
if (error) if (error) {
devres_free(devres);
return error; return error;
}
devres_add(&wacom->hdev->dev, devres); devres_add(&wacom->hdev->dev, devres);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment