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
This commit is contained in:
Коммит
28023d2a8e
|
@ -27,7 +27,8 @@ if HID
|
|||
|
||||
config HID_BATTERY_STRENGTH
|
||||
bool "Battery level reporting for HID devices"
|
||||
depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
|
||||
depends on HID
|
||||
select POWER_SUPPLY
|
||||
default n
|
||||
---help---
|
||||
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[] = {
|
|||
{ 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_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_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
|
||||
|
|
|
@ -526,6 +526,7 @@
|
|||
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
|
||||
#define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010
|
||||
#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_VENDOR_ID_LABTEC 0x1020
|
||||
|
|
|
@ -311,6 +311,9 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
|||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
|
||||
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,
|
||||
USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
|
||||
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
|
||||
|
|
|
@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||
}
|
||||
break;
|
||||
case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
|
||||
case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
|
||||
if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) {
|
||||
rdesc = 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)
|
|||
switch (id->product) {
|
||||
case USB_DEVICE_ID_KYE_EASYPEN_I405X:
|
||||
case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
|
||||
case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
|
||||
case USB_DEVICE_ID_KYE_EASYPEN_M610X:
|
||||
ret = kye_tablet_enable(hdev);
|
||||
if (ret) {
|
||||
|
@ -445,6 +447,8 @@ static const struct hid_device_id kye_devices[] = {
|
|||
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_2) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
|
||||
USB_DEVICE_ID_KYE_EASYPEN_M610X) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
|
||||
|
|
|
@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev,
|
|||
|
||||
switch (data[0]) {
|
||||
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);
|
||||
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:
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
|
|||
(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 */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)
|
|||
return NULL;
|
||||
|
||||
memcpy(name, &response.rap.params[2], len);
|
||||
|
||||
/* include the terminating '\0' */
|
||||
hidpp_prefix_name(&name, len + 1);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp)
|
|||
index += ret;
|
||||
}
|
||||
|
||||
/* include the terminating '\0' */
|
||||
hidpp_prefix_name(&name, __name_length + 1);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
|
|||
|
||||
switch (data[0]) {
|
||||
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) {
|
||||
input_event(wd->input, EV_KEY, BTN_LEFT,
|
||||
!!(data[1] & 0x01));
|
||||
input_event(wd->input, EV_KEY, BTN_RIGHT,
|
||||
!!(data[1] & 0x02));
|
||||
input_sync(wd->input);
|
||||
return 0;
|
||||
} else {
|
||||
if (size < 21)
|
||||
return 1;
|
||||
return wtp_mouse_raw_xy_event(hidpp, &data[7]);
|
||||
}
|
||||
case REPORT_ID_HIDPP_LONG:
|
||||
/* size is already checked in hidpp_raw_event. */
|
||||
if ((report->fap.feature_index != wd->mt_feature_index) ||
|
||||
(report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
|
||||
return 1;
|
||||
|
|
|
@ -35,6 +35,8 @@ static struct class *pyra_class;
|
|||
static void profile_activated(struct pyra_device *pyra,
|
||||
unsigned int new_profile)
|
||||
{
|
||||
if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
|
||||
return;
|
||||
pyra->actual_profile = new_profile;
|
||||
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,
|
|||
if (off != 0 || count != PYRA_SIZE_SETTINGS)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&pyra->pyra_lock);
|
||||
|
||||
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);
|
||||
if (retval) {
|
||||
|
|
|
@ -706,12 +706,7 @@ static int i2c_hid_start(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;
|
||||
|
||||
i2c_hid_free_buffers(ihid);
|
||||
}
|
||||
|
||||
static int i2c_hid_open(struct hid_device *hid)
|
||||
|
|
|
@ -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_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_2, 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_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
|
|
Загрузка…
Ссылка в новой задаче