Commit 6d104af3 authored by Johan Hovold's avatar Johan Hovold Committed by Jiri Kosina

HID: corsair: fix DMA buffers on stack

Not all platforms support DMA to the stack, and specifically since v4.9
this is no longer supported on x86 with VMAP_STACK either.

Note that the macro-mode buffer was larger than necessary.

Fixes: 6f78193e ("HID: corsair: Add Corsair Vengeance K90 driver")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent a89af4ab
...@@ -148,7 +148,11 @@ static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev) ...@@ -148,7 +148,11 @@ 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,
...@@ -158,16 +162,22 @@ static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev) ...@@ -158,16 +162,22 @@ static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev)
if (ret < 0) { if (ret < 0) {
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,7 +263,11 @@ static ssize_t k90_show_macro_mode(struct device *dev, ...@@ -253,7 +263,11 @@ 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,
...@@ -263,7 +277,8 @@ static ssize_t k90_show_macro_mode(struct device *dev, ...@@ -263,7 +277,8 @@ static ssize_t k90_show_macro_mode(struct device *dev,
if (ret < 0) { if (ret < 0) {
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,7 +340,11 @@ static ssize_t k90_show_current_profile(struct device *dev, ...@@ -320,7 +340,11 @@ 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,
...@@ -330,16 +354,22 @@ static ssize_t k90_show_current_profile(struct device *dev, ...@@ -330,16 +354,22 @@ static ssize_t k90_show_current_profile(struct device *dev,
if (ret < 0) { if (ret < 0) {
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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment