提交 28023d2a 编写于 作者: L Linus Torvalds

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

Pull HID updates from Jiri Kosina:

 - bounds checking fixes in logitech and roccat drivers, from Peter Wu
   and Dan Carpenter

 - double-kfree fix in i2c-hid driver on bus shutdown, from Mika
   Westerberg

 - a couple of various small driver fixes

 - a few device id additions

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: roccat: potential out of bounds in pyra_sysfs_write_settings()
  HID: Add a new id 0x501a for Genius MousePen i608X
  HID: logitech-hidpp: prefix the name with "Logitech"
  HID: logitech-hidpp: avoid unintended fall-through
  HID: Allow HID_BATTERY_STRENGTH to be enabled
  HID: i2c-hid: Do not free buffers in i2c_hid_stop()
  HID: add battery quirk for USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO keyboard
  HID: logitech-hidpp: check WTP report length
  HID: logitech-dj: check report length
...@@ -27,7 +27,8 @@ if HID ...@@ -27,7 +27,8 @@ if HID
config HID_BATTERY_STRENGTH config HID_BATTERY_STRENGTH
bool "Battery level reporting for HID devices" bool "Battery level reporting for HID devices"
depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY depends on HID
select POWER_SUPPLY
default n default n
---help--- ---help---
This option adds support of reporting battery strength (for HID devices This option adds support of reporting battery strength (for HID devices
......
...@@ -1805,6 +1805,7 @@ static const struct hid_device_id hid_have_special_driver[] = { ...@@ -1805,6 +1805,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
......
...@@ -526,6 +526,7 @@ ...@@ -526,6 +526,7 @@
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003 #define USB_DEVICE_ID_KYE_GPEN_560 0x5003
#define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010
#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011
#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2 0x501a
#define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013 #define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013
#define USB_VENDOR_ID_LABTEC 0x1020 #define USB_VENDOR_ID_LABTEC 0x1020
......
...@@ -311,6 +311,9 @@ static const struct hid_device_id hid_battery_quirks[] = { ...@@ -311,6 +311,9 @@ static const struct hid_device_id hid_battery_quirks[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
......
...@@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, ...@@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
} }
break; break;
case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) { if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) {
rdesc = mousepen_i608x_rdesc_fixed; rdesc = mousepen_i608x_rdesc_fixed;
*rsize = sizeof(mousepen_i608x_rdesc_fixed); *rsize = sizeof(mousepen_i608x_rdesc_fixed);
...@@ -415,6 +416,7 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -415,6 +416,7 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id)
switch (id->product) { switch (id->product) {
case USB_DEVICE_ID_KYE_EASYPEN_I405X: case USB_DEVICE_ID_KYE_EASYPEN_I405X:
case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
case USB_DEVICE_ID_KYE_EASYPEN_M610X: case USB_DEVICE_ID_KYE_EASYPEN_M610X:
ret = kye_tablet_enable(hdev); ret = kye_tablet_enable(hdev);
if (ret) { if (ret) {
...@@ -445,6 +447,8 @@ static const struct hid_device_id kye_devices[] = { ...@@ -445,6 +447,8 @@ static const struct hid_device_id kye_devices[] = {
USB_DEVICE_ID_KYE_EASYPEN_I405X) }, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
USB_DEVICE_ID_KYE_EASYPEN_M610X) }, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
......
...@@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev, ...@@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev,
switch (data[0]) { switch (data[0]) {
case REPORT_ID_DJ_SHORT: case REPORT_ID_DJ_SHORT:
if (size != DJREPORT_SHORT_LENGTH) {
dev_err(&hdev->dev, "DJ report of bad size (%d)", size);
return false;
}
return logi_dj_dj_event(hdev, report, data, size); return logi_dj_dj_event(hdev, report, data, size);
case REPORT_ID_HIDPP_SHORT: case REPORT_ID_HIDPP_SHORT:
/* intentional fallthrough */ if (size != HIDPP_REPORT_SHORT_LENGTH) {
dev_err(&hdev->dev,
"Short HID++ report of bad size (%d)", size);
return false;
}
return logi_dj_hidpp_event(hdev, report, data, size);
case REPORT_ID_HIDPP_LONG: case REPORT_ID_HIDPP_LONG:
if (size != HIDPP_REPORT_LONG_LENGTH) {
dev_err(&hdev->dev,
"Long HID++ report of bad size (%d)", size);
return false;
}
return logi_dj_hidpp_event(hdev, report, data, size); return logi_dj_hidpp_event(hdev, report, data, size);
} }
......
...@@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report) ...@@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
(report->rap.sub_id == 0x41); (report->rap.sub_id == 0x41);
} }
/**
* hidpp_prefix_name() prefixes the current given name with "Logitech ".
*/
static void hidpp_prefix_name(char **name, int name_length)
{
#define PREFIX_LENGTH 9 /* "Logitech " */
int new_length;
char *new_name;
if (name_length > PREFIX_LENGTH &&
strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0)
/* The prefix has is already in the name */
return;
new_length = PREFIX_LENGTH + name_length;
new_name = kzalloc(new_length, GFP_KERNEL);
if (!new_name)
return;
snprintf(new_name, new_length, "Logitech %s", *name);
kfree(*name);
*name = new_name;
}
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* HIDP++ 1.0 commands */ /* HIDP++ 1.0 commands */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
...@@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev) ...@@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)
return NULL; return NULL;
memcpy(name, &response.rap.params[2], len); memcpy(name, &response.rap.params[2], len);
/* include the terminating '\0' */
hidpp_prefix_name(&name, len + 1);
return name; return name;
} }
...@@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp) ...@@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp)
index += ret; index += ret;
} }
/* include the terminating '\0' */
hidpp_prefix_name(&name, __name_length + 1);
return name; return name;
} }
...@@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size) ...@@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
switch (data[0]) { switch (data[0]) {
case 0x02: case 0x02:
if (size < 2) {
hid_err(hdev, "Received HID report of bad size (%d)",
size);
return 1;
}
if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) { if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
input_event(wd->input, EV_KEY, BTN_LEFT, input_event(wd->input, EV_KEY, BTN_LEFT,
!!(data[1] & 0x01)); !!(data[1] & 0x01));
input_event(wd->input, EV_KEY, BTN_RIGHT, input_event(wd->input, EV_KEY, BTN_RIGHT,
!!(data[1] & 0x02)); !!(data[1] & 0x02));
input_sync(wd->input); input_sync(wd->input);
return 0;
} else { } else {
if (size < 21) if (size < 21)
return 1; return 1;
return wtp_mouse_raw_xy_event(hidpp, &data[7]); return wtp_mouse_raw_xy_event(hidpp, &data[7]);
} }
case REPORT_ID_HIDPP_LONG: case REPORT_ID_HIDPP_LONG:
/* size is already checked in hidpp_raw_event. */
if ((report->fap.feature_index != wd->mt_feature_index) || if ((report->fap.feature_index != wd->mt_feature_index) ||
(report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
return 1; return 1;
......
...@@ -35,6 +35,8 @@ static struct class *pyra_class; ...@@ -35,6 +35,8 @@ static struct class *pyra_class;
static void profile_activated(struct pyra_device *pyra, static void profile_activated(struct pyra_device *pyra,
unsigned int new_profile) unsigned int new_profile)
{ {
if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
return;
pyra->actual_profile = new_profile; pyra->actual_profile = new_profile;
pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
} }
...@@ -257,9 +259,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, ...@@ -257,9 +259,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
if (off != 0 || count != PYRA_SIZE_SETTINGS) if (off != 0 || count != PYRA_SIZE_SETTINGS)
return -EINVAL; return -EINVAL;
mutex_lock(&pyra->pyra_lock);
settings = (struct pyra_settings const *)buf; settings = (struct pyra_settings const *)buf;
if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings))
return -EINVAL;
mutex_lock(&pyra->pyra_lock);
retval = pyra_set_settings(usb_dev, settings); retval = pyra_set_settings(usb_dev, settings);
if (retval) { if (retval) {
......
...@@ -706,12 +706,7 @@ static int i2c_hid_start(struct hid_device *hid) ...@@ -706,12 +706,7 @@ static int i2c_hid_start(struct hid_device *hid)
static void i2c_hid_stop(struct hid_device *hid) static void i2c_hid_stop(struct hid_device *hid)
{ {
struct i2c_client *client = hid->driver_data;
struct i2c_hid *ihid = i2c_get_clientdata(client);
hid->claimed = 0; hid->claimed = 0;
i2c_hid_free_buffers(ihid);
} }
static int i2c_hid_open(struct hid_device *hid) static int i2c_hid_open(struct hid_device *hid)
......
...@@ -124,6 +124,7 @@ static const struct hid_blacklist { ...@@ -124,6 +124,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册