Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID fixes from Jiri Kosina:

- DMA-on-stack fixes for a couple drivers, from Benjamin Tissoires

- small memory sanitization fix for sensor-hub driver, from Song
Hongyan

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
HID: hid-sensor-hub: clear memory to avoid random data
HID: rmi: make transfer buffers DMA capable
HID: magicmouse: make transfer buffers DMA capable
HID: lg: make transfer buffers DMA capable
HID: cp2112: make transfer buffers DMA capable

+108 -44
+79 -36
drivers/hid/hid-cp2112.c
··· 32 32 #include <linux/usb/ch9.h> 33 33 #include "hid-ids.h" 34 34 35 + #define CP2112_REPORT_MAX_LENGTH 64 36 + #define CP2112_GPIO_CONFIG_LENGTH 5 37 + #define CP2112_GPIO_GET_LENGTH 2 38 + #define CP2112_GPIO_SET_LENGTH 3 39 + 35 40 enum { 36 41 CP2112_GPIO_CONFIG = 0x02, 37 42 CP2112_GPIO_GET = 0x03, ··· 166 161 atomic_t read_avail; 167 162 atomic_t xfer_avail; 168 163 struct gpio_chip gc; 164 + u8 *in_out_buffer; 165 + spinlock_t lock; 169 166 }; 170 167 171 168 static int gpio_push_pull = 0xFF; ··· 178 171 { 179 172 struct cp2112_device *dev = gpiochip_get_data(chip); 180 173 struct hid_device *hdev = dev->hdev; 181 - u8 buf[5]; 174 + u8 *buf = dev->in_out_buffer; 175 + unsigned long flags; 182 176 int ret; 183 177 178 + spin_lock_irqsave(&dev->lock, flags); 179 + 184 180 ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, 185 - sizeof(buf), HID_FEATURE_REPORT, 186 - HID_REQ_GET_REPORT); 187 - if (ret != sizeof(buf)) { 181 + CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, 182 + HID_REQ_GET_REPORT); 183 + if (ret != CP2112_GPIO_CONFIG_LENGTH) { 188 184 hid_err(hdev, "error requesting GPIO config: %d\n", ret); 189 - return ret; 185 + goto exit; 190 186 } 191 187 192 188 buf[1] &= ~(1 << offset); 193 189 buf[2] = gpio_push_pull; 194 190 195 - ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, sizeof(buf), 196 - HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 191 + ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, 192 + CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, 193 + HID_REQ_SET_REPORT); 197 194 if (ret < 0) { 198 195 hid_err(hdev, "error setting GPIO config: %d\n", ret); 199 - return ret; 196 + goto exit; 200 197 } 201 198 202 - return 0; 199 + ret = 0; 200 + 201 + exit: 202 + spin_unlock_irqrestore(&dev->lock, flags); 203 + return ret <= 0 ? ret : -EIO; 203 204 } 204 205 205 206 static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 206 207 { 207 208 struct cp2112_device *dev = gpiochip_get_data(chip); 208 209 struct hid_device *hdev = dev->hdev; 209 - u8 buf[3]; 210 + u8 *buf = dev->in_out_buffer; 211 + unsigned long flags; 210 212 int ret; 213 + 214 + spin_lock_irqsave(&dev->lock, flags); 211 215 212 216 buf[0] = CP2112_GPIO_SET; 213 217 buf[1] = value ? 0xff : 0; 214 218 buf[2] = 1 << offset; 215 219 216 - ret = hid_hw_raw_request(hdev, CP2112_GPIO_SET, buf, sizeof(buf), 217 - HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 220 + ret = hid_hw_raw_request(hdev, CP2112_GPIO_SET, buf, 221 + CP2112_GPIO_SET_LENGTH, HID_FEATURE_REPORT, 222 + HID_REQ_SET_REPORT); 218 223 if (ret < 0) 219 224 hid_err(hdev, "error setting GPIO values: %d\n", ret); 225 + 226 + spin_unlock_irqrestore(&dev->lock, flags); 220 227 } 221 228 222 229 static int cp2112_gpio_get(struct gpio_chip *chip, unsigned offset) 223 230 { 224 231 struct cp2112_device *dev = gpiochip_get_data(chip); 225 232 struct hid_device *hdev = dev->hdev; 226 - u8 buf[2]; 233 + u8 *buf = dev->in_out_buffer; 234 + unsigned long flags; 227 235 int ret; 228 236 229 - ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf, sizeof(buf), 230 - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 231 - if (ret != sizeof(buf)) { 237 + spin_lock_irqsave(&dev->lock, flags); 238 + 239 + ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf, 240 + CP2112_GPIO_GET_LENGTH, HID_FEATURE_REPORT, 241 + HID_REQ_GET_REPORT); 242 + if (ret != CP2112_GPIO_GET_LENGTH) { 232 243 hid_err(hdev, "error requesting GPIO values: %d\n", ret); 233 - return ret; 244 + ret = ret < 0 ? ret : -EIO; 245 + goto exit; 234 246 } 235 247 236 - return (buf[1] >> offset) & 1; 248 + ret = (buf[1] >> offset) & 1; 249 + 250 + exit: 251 + spin_unlock_irqrestore(&dev->lock, flags); 252 + 253 + return ret; 237 254 } 238 255 239 256 static int cp2112_gpio_direction_output(struct gpio_chip *chip, ··· 265 234 { 266 235 struct cp2112_device *dev = gpiochip_get_data(chip); 267 236 struct hid_device *hdev = dev->hdev; 268 - u8 buf[5]; 237 + u8 *buf = dev->in_out_buffer; 238 + unsigned long flags; 269 239 int ret; 270 240 241 + spin_lock_irqsave(&dev->lock, flags); 242 + 271 243 ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, 272 - sizeof(buf), HID_FEATURE_REPORT, 273 - HID_REQ_GET_REPORT); 274 - if (ret != sizeof(buf)) { 244 + CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, 245 + HID_REQ_GET_REPORT); 246 + if (ret != CP2112_GPIO_CONFIG_LENGTH) { 275 247 hid_err(hdev, "error requesting GPIO config: %d\n", ret); 276 - return ret; 248 + goto fail; 277 249 } 278 250 279 251 buf[1] |= 1 << offset; 280 252 buf[2] = gpio_push_pull; 281 253 282 - ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, sizeof(buf), 283 - HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 254 + ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, 255 + CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, 256 + HID_REQ_SET_REPORT); 284 257 if (ret < 0) { 285 258 hid_err(hdev, "error setting GPIO config: %d\n", ret); 286 - return ret; 259 + goto fail; 287 260 } 261 + 262 + spin_unlock_irqrestore(&dev->lock, flags); 288 263 289 264 /* 290 265 * Set gpio value when output direction is already set, ··· 299 262 cp2112_gpio_set(chip, offset, value); 300 263 301 264 return 0; 265 + 266 + fail: 267 + spin_unlock_irqrestore(&dev->lock, flags); 268 + return ret < 0 ? ret : -EIO; 302 269 } 303 270 304 271 static int cp2112_hid_get(struct hid_device *hdev, unsigned char report_number, ··· 1048 1007 struct cp2112_smbus_config_report config; 1049 1008 int ret; 1050 1009 1010 + dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); 1011 + if (!dev) 1012 + return -ENOMEM; 1013 + 1014 + dev->in_out_buffer = devm_kzalloc(&hdev->dev, CP2112_REPORT_MAX_LENGTH, 1015 + GFP_KERNEL); 1016 + if (!dev->in_out_buffer) 1017 + return -ENOMEM; 1018 + 1019 + spin_lock_init(&dev->lock); 1020 + 1051 1021 ret = hid_parse(hdev); 1052 1022 if (ret) { 1053 1023 hid_err(hdev, "parse failed\n"); ··· 1115 1063 goto err_power_normal; 1116 1064 } 1117 1065 1118 - dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1119 - if (!dev) { 1120 - ret = -ENOMEM; 1121 - goto err_power_normal; 1122 - } 1123 - 1124 1066 hid_set_drvdata(hdev, (void *)dev); 1125 1067 dev->hdev = hdev; 1126 1068 dev->adap.owner = THIS_MODULE; ··· 1133 1087 1134 1088 if (ret) { 1135 1089 hid_err(hdev, "error registering i2c adapter\n"); 1136 - goto err_free_dev; 1090 + goto err_power_normal; 1137 1091 } 1138 1092 1139 1093 hid_dbg(hdev, "adapter registered\n"); ··· 1169 1123 gpiochip_remove(&dev->gc); 1170 1124 err_free_i2c: 1171 1125 i2c_del_adapter(&dev->adap); 1172 - err_free_dev: 1173 - kfree(dev); 1174 1126 err_power_normal: 1175 1127 hid_hw_power(hdev, PM_HINT_NORMAL); 1176 1128 err_hid_close: ··· 1193 1149 */ 1194 1150 hid_hw_close(hdev); 1195 1151 hid_hw_stop(hdev); 1196 - kfree(dev); 1197 1152 } 1198 1153 1199 1154 static int cp2112_raw_event(struct hid_device *hdev, struct hid_report *report,
+10 -4
drivers/hid/hid-lg.c
··· 756 756 757 757 /* Setup wireless link with Logitech Wii wheel */ 758 758 if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) { 759 - unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 759 + const unsigned char cbuf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 760 + u8 *buf = kmemdup(cbuf, sizeof(cbuf), GFP_KERNEL); 760 761 761 - ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), 762 + if (!buf) { 763 + ret = -ENOMEM; 764 + goto err_free; 765 + } 766 + 767 + ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(cbuf), 762 768 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 763 - 764 769 if (ret >= 0) { 765 770 /* insert a little delay of 10 jiffies ~ 40ms */ 766 771 wait_queue_head_t wait; ··· 777 772 buf[1] = 0xB2; 778 773 get_random_bytes(&buf[2], 2); 779 774 780 - ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), 775 + ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(cbuf), 781 776 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 782 777 } 778 + kfree(buf); 783 779 } 784 780 785 781 if (drv_data->quirks & LG_FF)
+10 -2
drivers/hid/hid-magicmouse.c
··· 493 493 static int magicmouse_probe(struct hid_device *hdev, 494 494 const struct hid_device_id *id) 495 495 { 496 - __u8 feature[] = { 0xd7, 0x01 }; 496 + const u8 feature[] = { 0xd7, 0x01 }; 497 + u8 *buf; 497 498 struct magicmouse_sc *msc; 498 499 struct hid_report *report; 499 500 int ret; ··· 545 544 } 546 545 report->size = 6; 547 546 547 + buf = kmemdup(feature, sizeof(feature), GFP_KERNEL); 548 + if (!buf) { 549 + ret = -ENOMEM; 550 + goto err_stop_hw; 551 + } 552 + 548 553 /* 549 554 * Some devices repond with 'invalid report id' when feature 550 555 * report switching it into multitouch mode is sent to it. ··· 559 552 * but there seems to be no other way of switching the mode. 560 553 * Thus the super-ugly hacky success check below. 561 554 */ 562 - ret = hid_hw_raw_request(hdev, feature[0], feature, sizeof(feature), 555 + ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(feature), 563 556 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 557 + kfree(buf); 564 558 if (ret != -EIO && ret != sizeof(feature)) { 565 559 hid_err(hdev, "unable to request touch data (%d)\n", ret); 566 560 goto err_stop_hw;
+8 -2
drivers/hid/hid-rmi.c
··· 188 188 static int rmi_set_mode(struct hid_device *hdev, u8 mode) 189 189 { 190 190 int ret; 191 - u8 txbuf[2] = {RMI_SET_RMI_MODE_REPORT_ID, mode}; 191 + const u8 txbuf[2] = {RMI_SET_RMI_MODE_REPORT_ID, mode}; 192 + u8 *buf; 192 193 193 - ret = hid_hw_raw_request(hdev, RMI_SET_RMI_MODE_REPORT_ID, txbuf, 194 + buf = kmemdup(txbuf, sizeof(txbuf), GFP_KERNEL); 195 + if (!buf) 196 + return -ENOMEM; 197 + 198 + ret = hid_hw_raw_request(hdev, RMI_SET_RMI_MODE_REPORT_ID, buf, 194 199 sizeof(txbuf), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 200 + kfree(buf); 195 201 if (ret < 0) { 196 202 dev_err(&hdev->dev, "unable to set rmi mode to %d (%d)\n", mode, 197 203 ret);
+1
drivers/hid/hid-sensor-hub.c
··· 212 212 __s32 value; 213 213 int ret = 0; 214 214 215 + memset(buffer, 0, buffer_size); 215 216 mutex_lock(&data->mutex); 216 217 report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); 217 218 if (!report || (field_index >= report->maxfield)) {