mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-28 20:02:17 +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_device *usbdev = interface_to_usbdev(usbif);
|
||||
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),
|
||||
K90_REQUEST_STATUS,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR |
|
||||
USB_RECIP_DEVICE, 0, 0, data, 8,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
if (ret < 5) {
|
||||
dev_warn(dev, "Failed to get K90 initial state (error %d).\n",
|
||||
ret);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
brightness = data[4];
|
||||
if (brightness < 0 || brightness > 3) {
|
||||
dev_warn(dev,
|
||||
"Read invalid backlight brightness: %02hhx.\n",
|
||||
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)
|
||||
|
@ -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_device *usbdev = interface_to_usbdev(usbif);
|
||||
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),
|
||||
K90_REQUEST_GET_MODE,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR |
|
||||
USB_RECIP_DEVICE, 0, 0, data, 2,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
if (ret < 1) {
|
||||
dev_warn(dev, "Failed to get K90 initial mode (error %d).\n",
|
||||
ret);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (data[0]) {
|
||||
|
@ -277,10 +292,15 @@ static ssize_t k90_show_macro_mode(struct device *dev,
|
|||
default:
|
||||
dev_warn(dev, "K90 in unknown mode: %02hhx.\n",
|
||||
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,
|
||||
|
@ -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_device *usbdev = interface_to_usbdev(usbif);
|
||||
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),
|
||||
K90_REQUEST_STATUS,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR |
|
||||
USB_RECIP_DEVICE, 0, 0, data, 8,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
if (ret < 8) {
|
||||
dev_warn(dev, "Failed to get K90 initial state (error %d).\n",
|
||||
ret);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
current_profile = data[7];
|
||||
if (current_profile < 1 || current_profile > 3) {
|
||||
dev_warn(dev, "Read invalid current profile: %02hhx.\n",
|
||||
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,
|
||||
|
|
|
@ -740,6 +740,11 @@ static int wacom_add_shared_data(struct hid_device *hdev)
|
|||
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:
|
||||
mutex_unlock(&wacom_udev_list_lock);
|
||||
return retval;
|
||||
|
@ -2036,10 +2041,6 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
|
|||
if (error)
|
||||
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
|
||||
* 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)" : "");
|
||||
|
||||
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;
|
||||
error = wacom_add_shared_data(hdev);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) &&
|
||||
(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);
|
||||
|
||||
/*
|
||||
* 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)) {
|
||||
wacom_wac_pad_battery_report(hdev, report);
|
||||
if (wacom->wacom_wac.pad_input)
|
||||
|
|
Loading…
Reference in a new issue