···67 struct mutex thread_lock;68};6970-static struct hiddev *hiddev_table[HIDDEV_MINORS];7172/*73 * Find a report, given the report's type and ID. The ID can be specified···265static int hiddev_open(struct inode *inode, struct file *file)266{267 struct hiddev_list *list;268- int res, i;00269270- /* 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])275 return -ENODEV;0276277 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))278 return -ENOMEM;279 mutex_init(&list->thread_lock);280-281- list->hiddev = hiddev_table[i];282-283-284 file->private_data = list;285286 /*···286 */287 if (list->hiddev->exist) {288 if (!list->hiddev->open++) {289- res = usbhid_open(hiddev_table[i]->hid);290 if (res < 0) {291 res = -EIO;292 goto bail;···298 }299300 spin_lock_irq(&list->hiddev->list_lock);301- list_add_tail(&list->node, &hiddev_table[i]->list);302 spin_unlock_irq(&list->hiddev->list_lock);303304 if (!list->hiddev->open++)305 if (list->hiddev->exist) {306- struct hid_device *hid = hiddev_table[i]->hid;307 res = usbhid_get_power(hid);308 if (res < 0) {309 res = -EIO;···311 }312 usbhid_open(hid);313 }314-315- unlock_kernel();316 return 0;317bail:318 file->private_data = NULL;319 kfree(list);320- unlock_kernel();321 return res;322}323···888 hid->hiddev = hiddev;889 hiddev->hid = hid;890 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 been896- * updated.897- *898- * The obvious fix -- introducing mutex to guard hiddev_table[]899- * doesn't work, as usb_open() and usb_register_dev() both take900- * minor_rwsem, thus we'll have ABBA deadlock.901- *902- * Before BKL pushdown, usb_open() had been acquiring it in right903- * 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 occur905- * as BKL is dropped on schedule() (i.e. while sleeping on906- * minor_rwsem). Fugly.907- */908- lock_kernel();909 retval = usb_register_dev(usbhid->intf, &hiddev_class);910 if (retval) {911 err_hid("Not able to get a minor for this device.");912 hid->hiddev = NULL;913- unlock_kernel();914 kfree(hiddev);915 return -1;916- } else {917- hid->minor = usbhid->intf->minor;918- hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;919 }920- unlock_kernel();921-922 return 0;923}924···913 hiddev->exist = 0;914 mutex_unlock(&hiddev->existancelock);915916- hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;917 usb_deregister_dev(usbhid->intf, &hiddev_class);918919 if (hiddev->open) {
···67 struct mutex thread_lock;68};6970+static struct usb_driver hiddev_driver;7172/*73 * Find a report, given the report's type and ID. The ID can be specified···265static int hiddev_open(struct inode *inode, struct file *file)266{267 struct hiddev_list *list;268+ struct usb_interface *intf;269+ struct hiddev *hiddev;270+ int res;271272+ intf = usb_find_interface(&hiddev_driver, iminor(inode));273+ if (!intf)000274 return -ENODEV;275+ hiddev = usb_get_intfdata(intf);276277 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))278 return -ENOMEM;279 mutex_init(&list->thread_lock);280+ list->hiddev = hiddev;000281 file->private_data = list;282283 /*···289 */290 if (list->hiddev->exist) {291 if (!list->hiddev->open++) {292+ res = usbhid_open(hiddev->hid);293 if (res < 0) {294 res = -EIO;295 goto bail;···301 }302303 spin_lock_irq(&list->hiddev->list_lock);304+ list_add_tail(&list->node, &hiddev->list);305 spin_unlock_irq(&list->hiddev->list_lock);306307 if (!list->hiddev->open++)308 if (list->hiddev->exist) {309+ struct hid_device *hid = hiddev->hid;310 res = usbhid_get_power(hid);311 if (res < 0) {312 res = -EIO;···314 }315 usbhid_open(hid);316 }00317 return 0;318bail:319 file->private_data = NULL;320 kfree(list);0321 return res;322}323···894 hid->hiddev = hiddev;895 hiddev->hid = hid;896 hiddev->exist = 1;897+ usb_set_intfdata(usbhid->intf, usbhid);00000000000000000898 retval = usb_register_dev(usbhid->intf, &hiddev_class);899 if (retval) {900 err_hid("Not able to get a minor for this device.");901 hid->hiddev = NULL;0902 kfree(hiddev);903 return -1;000904 }00905 return 0;906}907···942 hiddev->exist = 0;943 mutex_unlock(&hiddev->existancelock);9440945 usb_deregister_dev(usbhid->intf, &hiddev_class);946947 if (hiddev->open) {