Merge branch 'bkl' into for-linus

+12 -42
+12 -42
drivers/hid/usbhid/hiddev.c
··· 67 67 struct mutex thread_lock; 68 68 }; 69 69 70 - static struct hiddev *hiddev_table[HIDDEV_MINORS]; 70 + static struct usb_driver hiddev_driver; 71 71 72 72 /* 73 73 * Find a report, given the report's type and ID. The ID can be specified ··· 265 265 static int hiddev_open(struct inode *inode, struct file *file) 266 266 { 267 267 struct hiddev_list *list; 268 - int res, i; 268 + struct usb_interface *intf; 269 + struct hiddev *hiddev; 270 + int res; 269 271 270 - /* See comment in hiddev_connect() for BKL explanation */ 271 - lock_kernel(); 272 - i = iminor(inode) - HIDDEV_MINOR_BASE; 273 - 274 - if (i >= HIDDEV_MINORS || i < 0 || !hiddev_table[i]) 272 + intf = usb_find_interface(&hiddev_driver, iminor(inode)); 273 + if (!intf) 275 274 return -ENODEV; 275 + hiddev = usb_get_intfdata(intf); 276 276 277 277 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) 278 278 return -ENOMEM; 279 279 mutex_init(&list->thread_lock); 280 - 281 - list->hiddev = hiddev_table[i]; 282 - 283 - 280 + list->hiddev = hiddev; 284 281 file->private_data = list; 285 282 286 283 /* ··· 286 289 */ 287 290 if (list->hiddev->exist) { 288 291 if (!list->hiddev->open++) { 289 - res = usbhid_open(hiddev_table[i]->hid); 292 + res = usbhid_open(hiddev->hid); 290 293 if (res < 0) { 291 294 res = -EIO; 292 295 goto bail; ··· 298 301 } 299 302 300 303 spin_lock_irq(&list->hiddev->list_lock); 301 - list_add_tail(&list->node, &hiddev_table[i]->list); 304 + list_add_tail(&list->node, &hiddev->list); 302 305 spin_unlock_irq(&list->hiddev->list_lock); 303 306 304 307 if (!list->hiddev->open++) 305 308 if (list->hiddev->exist) { 306 - struct hid_device *hid = hiddev_table[i]->hid; 309 + struct hid_device *hid = hiddev->hid; 307 310 res = usbhid_get_power(hid); 308 311 if (res < 0) { 309 312 res = -EIO; ··· 311 314 } 312 315 usbhid_open(hid); 313 316 } 314 - 315 - unlock_kernel(); 316 317 return 0; 317 318 bail: 318 319 file->private_data = NULL; 319 320 kfree(list); 320 - unlock_kernel(); 321 321 return res; 322 322 } 323 323 ··· 888 894 hid->hiddev = hiddev; 889 895 hiddev->hid = hid; 890 896 hiddev->exist = 1; 891 - 892 - /* 893 - * BKL here is used to avoid race after usb_register_dev(). 894 - * Once the device node has been created, open() could happen on it. 895 - * The code below will then fail, as hiddev_table hasn't been 896 - * updated. 897 - * 898 - * The obvious fix -- introducing mutex to guard hiddev_table[] 899 - * doesn't work, as usb_open() and usb_register_dev() both take 900 - * minor_rwsem, thus we'll have ABBA deadlock. 901 - * 902 - * Before BKL pushdown, usb_open() had been acquiring it in right 903 - * order, so _open() was safe to use it to protect from this race. 904 - * Now the order is different, but AB-BA deadlock still doesn't occur 905 - * as BKL is dropped on schedule() (i.e. while sleeping on 906 - * minor_rwsem). Fugly. 907 - */ 908 - lock_kernel(); 897 + usb_set_intfdata(usbhid->intf, usbhid); 909 898 retval = usb_register_dev(usbhid->intf, &hiddev_class); 910 899 if (retval) { 911 900 err_hid("Not able to get a minor for this device."); 912 901 hid->hiddev = NULL; 913 - unlock_kernel(); 914 902 kfree(hiddev); 915 903 return -1; 916 - } else { 917 - hid->minor = usbhid->intf->minor; 918 - hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; 919 904 } 920 - unlock_kernel(); 921 - 922 905 return 0; 923 906 } 924 907 ··· 913 942 hiddev->exist = 0; 914 943 mutex_unlock(&hiddev->existancelock); 915 944 916 - hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL; 917 945 usb_deregister_dev(usbhid->intf, &hiddev_class); 918 946 919 947 if (hiddev->open) {