}
 EXPORT_SYMBOL_GPL(hid_connect);
 
+void hid_disconnect(struct hid_device *hdev)
+{
+       if (hdev->claimed & HID_CLAIMED_INPUT)
+               hidinput_disconnect(hdev);
+       if (hdev->claimed & HID_CLAIMED_HIDDEV)
+               hdev->hiddev_disconnect(hdev);
+       if (hdev->claimed & HID_CLAIMED_HIDRAW)
+               hidraw_disconnect(hdev);
+}
+EXPORT_SYMBOL_GPL(hid_disconnect);
+
 /* a list of devices for which there is a specialized driver on HID bus */
 static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
 
 
        hid_cancel_delayed_stuff(usbhid);
 
-       if (hid->claimed & HID_CLAIMED_INPUT)
-               hidinput_disconnect(hid);
-       if (hid->claimed & HID_CLAIMED_HIDDEV)
-               hiddev_disconnect(hid);
-       if (hid->claimed & HID_CLAIMED_HIDRAW)
-               hidraw_disconnect(hid);
-
        hid->claimed = 0;
 
        usb_free_urb(usbhid->urbin);
        .hidinput_input_event = usb_hidinput_input_event,
 };
 
-static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
        struct usb_host_interface *interface = intf->cur_altsetting;
        struct usb_device *dev = interface_to_usbdev(intf);
        hid->ff_init = hid_pidff_init;
 #ifdef CONFIG_USB_HIDDEV
        hid->hiddev_connect = hiddev_connect;
+       hid->hiddev_disconnect = hiddev_disconnect;
        hid->hiddev_hid_event = hiddev_hid_event;
        hid->hiddev_report_event = hiddev_report_event;
 #endif
        return ret;
 }
 
-static void hid_disconnect(struct usb_interface *intf)
+static void usbhid_disconnect(struct usb_interface *intf)
 {
        struct hid_device *hid = usb_get_intfdata(intf);
        struct usbhid_device *usbhid;
 
 static struct usb_driver hid_driver = {
        .name =         "usbhid",
-       .probe =        hid_probe,
-       .disconnect =   hid_disconnect,
+       .probe =        usbhid_probe,
+       .disconnect =   usbhid_disconnect,
 #ifdef CONFIG_PM
        .suspend =      hid_suspend,
        .resume =       hid_resume,
 
 
        /* hiddev event handler */
        int (*hiddev_connect)(struct hid_device *, unsigned int);
+       void (*hiddev_disconnect)(struct hid_device *);
        void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
                                  struct hid_usage *, __s32);
        void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
 int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
 int hid_check_keys_pressed(struct hid_device *hid);
 int hid_connect(struct hid_device *hid, unsigned int connect_mask);
+void hid_disconnect(struct hid_device *hid);
 
 /**
  * hid_map_usage - map usage input bits
  */
 static inline void hid_hw_stop(struct hid_device *hdev)
 {
+       hid_disconnect(hdev);
        hdev->ll_driver->stop(hdev);
 }
 
 
        }
 
        if (session->hid) {
-               if (session->hid->claimed & HID_CLAIMED_INPUT)
-                       hidinput_disconnect(session->hid);
-               if (session->hid->claimed & HID_CLAIMED_HIDRAW)
-                       hidraw_disconnect(session->hid);
-
                hid_destroy_device(session->hid);
                session->hid = NULL;
        }
        skb_queue_purge(&session->ctrl_transmit);
        skb_queue_purge(&session->intr_transmit);
 
-       if (hid->claimed & HID_CLAIMED_INPUT)
-               hidinput_disconnect(hid);
        hid->claimed = 0;
 }