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

Merge branches 'upstream-fixes', 'bkl-removal', 'debugfs-fixes' and 'hid-suspend' into for-linus

+91 -46
+8 -15
drivers/hid/hid-core.c
··· 1081 1081 1082 1082 buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); 1083 1083 1084 - if (!buf) { 1085 - report = hid_get_report(report_enum, data); 1084 + if (!buf) 1086 1085 goto nomem; 1087 - } 1088 - 1089 - snprintf(buf, HID_DEBUG_BUFSIZE - 1, 1090 - "\nreport (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); 1091 - hid_debug_event(hid, buf); 1092 - 1093 - report = hid_get_report(report_enum, data); 1094 - if (!report) { 1095 - kfree(buf); 1096 - return -1; 1097 - } 1098 1086 1099 1087 /* dump the report */ 1100 1088 snprintf(buf, HID_DEBUG_BUFSIZE - 1, 1101 - "report %d (size %u) = ", report->id, size); 1089 + "\nreport (size %u) (%snumbered) = ", size, report_enum->numbered ? "" : "un"); 1102 1090 hid_debug_event(hid, buf); 1091 + 1103 1092 for (i = 0; i < size; i++) { 1104 1093 snprintf(buf, HID_DEBUG_BUFSIZE - 1, 1105 1094 " %02x", data[i]); 1106 1095 hid_debug_event(hid, buf); 1107 1096 } 1108 1097 hid_debug_event(hid, "\n"); 1109 - 1110 1098 kfree(buf); 1111 1099 1112 1100 nomem: 1101 + report = hid_get_report(report_enum, data); 1102 + 1103 + if (!report) 1104 + return -1; 1105 + 1113 1106 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { 1114 1107 ret = hdrv->raw_event(hid, report, data, size); 1115 1108 if (ret != 0)
+4 -1
drivers/hid/hid-magicmouse.c
··· 354 354 goto err_free; 355 355 } 356 356 357 - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT); 357 + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 358 358 if (ret) { 359 359 dev_err(&hdev->dev, "magicmouse hw start failed\n"); 360 360 goto err_free; 361 361 } 362 + 363 + /* we are handling the input ourselves */ 364 + hidinput_disconnect(hdev); 362 365 363 366 report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); 364 367 if (!report) {
+31 -27
drivers/hid/hidraw.c
··· 106 106 static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 107 107 { 108 108 unsigned int minor = iminor(file->f_path.dentry->d_inode); 109 - /* FIXME: What stops hidraw_table going NULL */ 110 - struct hid_device *dev = hidraw_table[minor]->hid; 109 + struct hid_device *dev; 111 110 __u8 *buf; 112 111 int ret = 0; 113 112 114 - if (!dev->hid_output_raw_report) 115 - return -ENODEV; 113 + mutex_lock(&minors_lock); 114 + dev = hidraw_table[minor]->hid; 115 + 116 + if (!dev->hid_output_raw_report) { 117 + ret = -ENODEV; 118 + goto out; 119 + } 116 120 117 121 if (count > HID_MAX_BUFFER_SIZE) { 118 122 printk(KERN_WARNING "hidraw: pid %d passed too large report\n", 119 123 task_pid_nr(current)); 120 - return -EINVAL; 124 + ret = -EINVAL; 125 + goto out; 121 126 } 122 127 123 128 if (count < 2) { 124 129 printk(KERN_WARNING "hidraw: pid %d passed too short report\n", 125 130 task_pid_nr(current)); 126 - return -EINVAL; 127 - } 128 - 129 - buf = kmalloc(count * sizeof(__u8), GFP_KERNEL); 130 - if (!buf) 131 - return -ENOMEM; 132 - 133 - if (copy_from_user(buf, buffer, count)) { 134 - ret = -EFAULT; 131 + ret = -EINVAL; 135 132 goto out; 136 133 } 137 134 135 + buf = kmalloc(count * sizeof(__u8), GFP_KERNEL); 136 + if (!buf) { 137 + ret = -ENOMEM; 138 + goto out; 139 + } 140 + 141 + if (copy_from_user(buf, buffer, count)) { 142 + ret = -EFAULT; 143 + goto out_free; 144 + } 145 + 138 146 ret = dev->hid_output_raw_report(dev, buf, count, HID_OUTPUT_REPORT); 139 - out: 147 + out_free: 140 148 kfree(buf); 149 + out: 150 + mutex_unlock(&minors_lock); 141 151 return ret; 142 152 } 143 153 ··· 175 165 goto out; 176 166 } 177 167 178 - lock_kernel(); 179 168 mutex_lock(&minors_lock); 180 169 if (!hidraw_table[minor]) { 181 - printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n", 182 - minor); 183 170 kfree(list); 184 171 err = -ENODEV; 185 172 goto out_unlock; ··· 204 197 205 198 out_unlock: 206 199 mutex_unlock(&minors_lock); 207 - unlock_kernel(); 208 200 out: 209 201 return err; 210 202 ··· 215 209 struct hidraw *dev; 216 210 struct hidraw_list *list = file->private_data; 217 211 218 - if (!hidraw_table[minor]) { 219 - printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n", 220 - minor); 212 + if (!hidraw_table[minor]) 221 213 return -ENODEV; 222 - } 223 214 224 215 list_del(&list->node); 225 216 dev = hidraw_table[minor]; ··· 241 238 struct inode *inode = file->f_path.dentry->d_inode; 242 239 unsigned int minor = iminor(inode); 243 240 long ret = 0; 244 - /* FIXME: What stops hidraw_table going NULL */ 245 - struct hidraw *dev = hidraw_table[minor]; 241 + struct hidraw *dev; 246 242 void __user *user_arg = (void __user*) arg; 247 243 248 - lock_kernel(); 244 + mutex_lock(&minors_lock); 245 + dev = hidraw_table[minor]; 246 + 249 247 switch (cmd) { 250 248 case HIDIOCGRDESCSIZE: 251 249 if (put_user(dev->hid->rsize, (int __user *)arg)) ··· 319 315 320 316 ret = -ENOTTY; 321 317 } 322 - unlock_kernel(); 318 + mutex_unlock(&minors_lock); 323 319 return ret; 324 320 } 325 321
+23 -1
drivers/hid/usbhid/hid-core.c
··· 1313 1313 { 1314 1314 set_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1315 1315 spin_unlock_irq(&usbhid->lock); 1316 + if (hid->driver && hid->driver->suspend) { 1317 + status = hid->driver->suspend(hid, message); 1318 + if (status < 0) 1319 + return status; 1320 + } 1316 1321 } else { 1317 1322 usbhid_mark_busy(usbhid); 1318 1323 spin_unlock_irq(&usbhid->lock); ··· 1325 1320 } 1326 1321 1327 1322 } else { 1323 + if (hid->driver && hid->driver->suspend) { 1324 + status = hid->driver->suspend(hid, message); 1325 + if (status < 0) 1326 + return status; 1327 + } 1328 1328 spin_lock_irq(&usbhid->lock); 1329 1329 set_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1330 1330 spin_unlock_irq(&usbhid->lock); ··· 1384 1374 hid_io_error(hid); 1385 1375 usbhid_restart_queues(usbhid); 1386 1376 1377 + if (status >= 0 && hid->driver && hid->driver->resume) { 1378 + int ret = hid->driver->resume(hid); 1379 + if (ret < 0) 1380 + status = ret; 1381 + } 1387 1382 dev_dbg(&intf->dev, "resume status %d\n", status); 1388 1383 return 0; 1389 1384 } ··· 1397 1382 { 1398 1383 struct hid_device *hid = usb_get_intfdata(intf); 1399 1384 struct usbhid_device *usbhid = hid->driver_data; 1385 + int status; 1400 1386 1401 1387 clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1402 - return hid_post_reset(intf); 1388 + status = hid_post_reset(intf); 1389 + if (status >= 0 && hid->driver && hid->driver->reset_resume) { 1390 + int ret = hid->driver->reset_resume(hid); 1391 + if (ret < 0) 1392 + status = ret; 1393 + } 1394 + return status; 1403 1395 } 1404 1396 1405 1397 #endif /* CONFIG_PM */
+17 -2
drivers/hid/usbhid/hiddev.c
··· 267 267 struct hiddev_list *list; 268 268 int res, i; 269 269 270 + /* See comment in hiddev_connect() for BKL explanation */ 270 271 lock_kernel(); 271 272 i = iminor(inode) - HIDDEV_MINOR_BASE; 272 273 ··· 895 894 hiddev->hid = hid; 896 895 hiddev->exist = 1; 897 896 898 - /* when lock_kernel() usage is fixed in usb_open(), 899 - * we could also fix it here */ 897 + /* 898 + * BKL here is used to avoid race after usb_register_dev(). 899 + * Once the device node has been created, open() could happen on it. 900 + * The code below will then fail, as hiddev_table hasn't been 901 + * updated. 902 + * 903 + * The obvious fix -- introducing mutex to guard hiddev_table[] 904 + * doesn't work, as usb_open() and usb_register_dev() both take 905 + * minor_rwsem, thus we'll have ABBA deadlock. 906 + * 907 + * Before BKL pushdown, usb_open() had been acquiring it in right 908 + * order, so _open() was safe to use it to protect from this race. 909 + * Now the order is different, but AB-BA deadlock still doesn't occur 910 + * as BKL is dropped on schedule() (i.e. while sleeping on 911 + * minor_rwsem). Fugly. 912 + */ 900 913 lock_kernel(); 901 914 retval = usb_register_dev(usbhid->intf, &hiddev_class); 902 915 if (retval) {
+8
include/linux/hid.h
··· 591 591 * @report_fixup: called before report descriptor parsing (NULL means nop) 592 592 * @input_mapping: invoked on input registering before mapping an usage 593 593 * @input_mapped: invoked on input registering after mapping an usage 594 + * @suspend: invoked on suspend (NULL means nop) 595 + * @resume: invoked on resume if device was not reset (NULL means nop) 596 + * @reset_resume: invoked on resume if device was reset (NULL means nop) 594 597 * 595 598 * raw_event and event should return 0 on no action performed, 1 when no 596 599 * further processing should be done and negative on error ··· 634 631 int (*input_mapped)(struct hid_device *hdev, 635 632 struct hid_input *hidinput, struct hid_field *field, 636 633 struct hid_usage *usage, unsigned long **bit, int *max); 634 + #ifdef CONFIG_PM 635 + int (*suspend)(struct hid_device *hdev, pm_message_t message); 636 + int (*resume)(struct hid_device *hdev); 637 + int (*reset_resume)(struct hid_device *hdev); 638 + #endif 637 639 /* private: */ 638 640 struct device_driver driver; 639 641 };