mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID fixes from Jiri Kosina: - regression fix for generic Wacom devices, from Jason Gerecke - DMA-on-stack fixes for hid-corsair driver, from Johan Hovold * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: HID: wacom: Fix sibling detection regression HID: corsair: fix control-transfer error handling HID: corsair: fix DMA buffers on stack
This commit is contained in:
commit
2ed5e5af2f
3 changed files with 63 additions and 23 deletions
|
@ -148,26 +148,36 @@ static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev)
|
||||||
struct usb_interface *usbif = to_usb_interface(dev->parent);
|
struct usb_interface *usbif = to_usb_interface(dev->parent);
|
||||||
struct usb_device *usbdev = interface_to_usbdev(usbif);
|
struct usb_device *usbdev = interface_to_usbdev(usbif);
|
||||||
int brightness;
|
int brightness;
|
||||||
char data[8];
|
char *data;
|
||||||
|
|
||||||
|
data = kmalloc(8, GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
|
ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
|
||||||
K90_REQUEST_STATUS,
|
K90_REQUEST_STATUS,
|
||||||
USB_DIR_IN | USB_TYPE_VENDOR |
|
USB_DIR_IN | USB_TYPE_VENDOR |
|
||||||
USB_RECIP_DEVICE, 0, 0, data, 8,
|
USB_RECIP_DEVICE, 0, 0, data, 8,
|
||||||
USB_CTRL_SET_TIMEOUT);
|
USB_CTRL_SET_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret < 5) {
|
||||||
dev_warn(dev, "Failed to get K90 initial state (error %d).\n",
|
dev_warn(dev, "Failed to get K90 initial state (error %d).\n",
|
||||||
ret);
|
ret);
|
||||||
return -EIO;
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
brightness = data[4];
|
brightness = data[4];
|
||||||
if (brightness < 0 || brightness > 3) {
|
if (brightness < 0 || brightness > 3) {
|
||||||
dev_warn(dev,
|
dev_warn(dev,
|
||||||
"Read invalid backlight brightness: %02hhx.\n",
|
"Read invalid backlight brightness: %02hhx.\n",
|
||||||
data[4]);
|
data[4]);
|
||||||
return -EIO;
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
return brightness;
|
ret = brightness;
|
||||||
|
out:
|
||||||
|
kfree(data);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum led_brightness k90_record_led_get(struct led_classdev *led_cdev)
|
static enum led_brightness k90_record_led_get(struct led_classdev *led_cdev)
|
||||||
|
@ -253,17 +263,22 @@ static ssize_t k90_show_macro_mode(struct device *dev,
|
||||||
struct usb_interface *usbif = to_usb_interface(dev->parent);
|
struct usb_interface *usbif = to_usb_interface(dev->parent);
|
||||||
struct usb_device *usbdev = interface_to_usbdev(usbif);
|
struct usb_device *usbdev = interface_to_usbdev(usbif);
|
||||||
const char *macro_mode;
|
const char *macro_mode;
|
||||||
char data[8];
|
char *data;
|
||||||
|
|
||||||
|
data = kmalloc(2, GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
|
ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
|
||||||
K90_REQUEST_GET_MODE,
|
K90_REQUEST_GET_MODE,
|
||||||
USB_DIR_IN | USB_TYPE_VENDOR |
|
USB_DIR_IN | USB_TYPE_VENDOR |
|
||||||
USB_RECIP_DEVICE, 0, 0, data, 2,
|
USB_RECIP_DEVICE, 0, 0, data, 2,
|
||||||
USB_CTRL_SET_TIMEOUT);
|
USB_CTRL_SET_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret < 1) {
|
||||||
dev_warn(dev, "Failed to get K90 initial mode (error %d).\n",
|
dev_warn(dev, "Failed to get K90 initial mode (error %d).\n",
|
||||||
ret);
|
ret);
|
||||||
return -EIO;
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (data[0]) {
|
switch (data[0]) {
|
||||||
|
@ -277,10 +292,15 @@ static ssize_t k90_show_macro_mode(struct device *dev,
|
||||||
default:
|
default:
|
||||||
dev_warn(dev, "K90 in unknown mode: %02hhx.\n",
|
dev_warn(dev, "K90 in unknown mode: %02hhx.\n",
|
||||||
data[0]);
|
data[0]);
|
||||||
return -EIO;
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n", macro_mode);
|
ret = snprintf(buf, PAGE_SIZE, "%s\n", macro_mode);
|
||||||
|
out:
|
||||||
|
kfree(data);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t k90_store_macro_mode(struct device *dev,
|
static ssize_t k90_store_macro_mode(struct device *dev,
|
||||||
|
@ -320,26 +340,36 @@ static ssize_t k90_show_current_profile(struct device *dev,
|
||||||
struct usb_interface *usbif = to_usb_interface(dev->parent);
|
struct usb_interface *usbif = to_usb_interface(dev->parent);
|
||||||
struct usb_device *usbdev = interface_to_usbdev(usbif);
|
struct usb_device *usbdev = interface_to_usbdev(usbif);
|
||||||
int current_profile;
|
int current_profile;
|
||||||
char data[8];
|
char *data;
|
||||||
|
|
||||||
|
data = kmalloc(8, GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
|
ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
|
||||||
K90_REQUEST_STATUS,
|
K90_REQUEST_STATUS,
|
||||||
USB_DIR_IN | USB_TYPE_VENDOR |
|
USB_DIR_IN | USB_TYPE_VENDOR |
|
||||||
USB_RECIP_DEVICE, 0, 0, data, 8,
|
USB_RECIP_DEVICE, 0, 0, data, 8,
|
||||||
USB_CTRL_SET_TIMEOUT);
|
USB_CTRL_SET_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret < 8) {
|
||||||
dev_warn(dev, "Failed to get K90 initial state (error %d).\n",
|
dev_warn(dev, "Failed to get K90 initial state (error %d).\n",
|
||||||
ret);
|
ret);
|
||||||
return -EIO;
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
current_profile = data[7];
|
current_profile = data[7];
|
||||||
if (current_profile < 1 || current_profile > 3) {
|
if (current_profile < 1 || current_profile > 3) {
|
||||||
dev_warn(dev, "Read invalid current profile: %02hhx.\n",
|
dev_warn(dev, "Read invalid current profile: %02hhx.\n",
|
||||||
data[7]);
|
data[7]);
|
||||||
return -EIO;
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n", current_profile);
|
ret = snprintf(buf, PAGE_SIZE, "%d\n", current_profile);
|
||||||
|
out:
|
||||||
|
kfree(data);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t k90_store_current_profile(struct device *dev,
|
static ssize_t k90_store_current_profile(struct device *dev,
|
||||||
|
|
|
@ -740,6 +740,11 @@ static int wacom_add_shared_data(struct hid_device *hdev)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)
|
||||||
|
wacom_wac->shared->touch = hdev;
|
||||||
|
else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN)
|
||||||
|
wacom_wac->shared->pen = hdev;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&wacom_udev_list_lock);
|
mutex_unlock(&wacom_udev_list_lock);
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -2036,10 +2041,6 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
error = wacom_add_shared_data(hdev);
|
|
||||||
if (error)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bamboo Pad has a generic hid handling for the Pen, and we switch it
|
* Bamboo Pad has a generic hid handling for the Pen, and we switch it
|
||||||
* into debug mode for the touch part.
|
* into debug mode for the touch part.
|
||||||
|
@ -2080,10 +2081,9 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
|
||||||
|
|
||||||
wacom_update_name(wacom, wireless ? " (WL)" : "");
|
wacom_update_name(wacom, wireless ? " (WL)" : "");
|
||||||
|
|
||||||
if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)
|
error = wacom_add_shared_data(hdev);
|
||||||
wacom_wac->shared->touch = hdev;
|
if (error)
|
||||||
else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN)
|
goto fail;
|
||||||
wacom_wac->shared->pen = hdev;
|
|
||||||
|
|
||||||
if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) &&
|
if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) &&
|
||||||
(features->quirks & WACOM_QUIRK_BATTERY)) {
|
(features->quirks & WACOM_QUIRK_BATTERY)) {
|
||||||
|
|
|
@ -2187,6 +2187,16 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
|
||||||
|
|
||||||
wacom_report_events(hdev, report);
|
wacom_report_events(hdev, report);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non-input reports may be sent prior to the device being
|
||||||
|
* completely initialized. Since only their events need
|
||||||
|
* to be processed, exit after 'wacom_report_events' has
|
||||||
|
* been called to prevent potential crashes in the report-
|
||||||
|
* processing functions.
|
||||||
|
*/
|
||||||
|
if (report->type != HID_INPUT_REPORT)
|
||||||
|
return;
|
||||||
|
|
||||||
if (WACOM_PAD_FIELD(field)) {
|
if (WACOM_PAD_FIELD(field)) {
|
||||||
wacom_wac_pad_battery_report(hdev, report);
|
wacom_wac_pad_battery_report(hdev, report);
|
||||||
if (wacom->wacom_wac.pad_input)
|
if (wacom->wacom_wac.pad_input)
|
||||||
|
|
Loading…
Add table
Reference in a new issue