Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
torvalds committed Jan 19, 2017
2 parents 4a1cc2e + a9ce785 commit 2ed5e5a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 23 deletions.
60 changes: 45 additions & 15 deletions drivers/hid/hid-corsair.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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]) {
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
16 changes: 8 additions & 8 deletions drivers/hid/wacom_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)) {
Expand Down
10 changes: 10 additions & 0 deletions drivers/hid/wacom_wac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 2ed5e5a

Please sign in to comment.