提交 2ed5e5af 编写于 作者: L Linus Torvalds

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
...@@ -148,26 +148,36 @@ static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册