aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2009-09-15 10:27:45 -0400
committerJiri Kosina <jkosina@suse.cz>2009-09-17 09:15:11 -0400
commitc4c259bcc27c4242b012106afdba183622b1735f (patch)
tree5db41b8ea3d43f3a10479257da302590a6b974f2
parentd1ff65226c5afe55f9af38a439058f41b71e114f (diff)
HID: consolidate connect and disconnect into core code
HID core registers input, hidraw and hiddev devices, but leaves unregistering it up to the individual driver, which is not really nice. Let's move all the logic to the core. Reported-by: Marcel Holtmann <marcel@holtmann.org> Reported-by: Brian Rogers <brian@xyzw.org> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-core.c11
-rw-r--r--drivers/hid/usbhid/hid-core.c16
-rw-r--r--include/linux/hid.h3
-rw-r--r--net/bluetooth/hidp/core.c7
4 files changed, 19 insertions, 18 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index ca9bb26c2076..be34d32906bd 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1237,6 +1237,17 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1237} 1237}
1238EXPORT_SYMBOL_GPL(hid_connect); 1238EXPORT_SYMBOL_GPL(hid_connect);
1239 1239
1240void hid_disconnect(struct hid_device *hdev)
1241{
1242 if (hdev->claimed & HID_CLAIMED_INPUT)
1243 hidinput_disconnect(hdev);
1244 if (hdev->claimed & HID_CLAIMED_HIDDEV)
1245 hdev->hiddev_disconnect(hdev);
1246 if (hdev->claimed & HID_CLAIMED_HIDRAW)
1247 hidraw_disconnect(hdev);
1248}
1249EXPORT_SYMBOL_GPL(hid_disconnect);
1250
1240/* a list of devices for which there is a specialized driver on HID bus */ 1251/* a list of devices for which there is a specialized driver on HID bus */
1241static const struct hid_device_id hid_blacklist[] = { 1252static const struct hid_device_id hid_blacklist[] = {
1242 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, 1253 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 1b0e07a67d6d..03bd703255a3 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1041,13 +1041,6 @@ static void usbhid_stop(struct hid_device *hid)
1041 1041
1042 hid_cancel_delayed_stuff(usbhid); 1042 hid_cancel_delayed_stuff(usbhid);
1043 1043
1044 if (hid->claimed & HID_CLAIMED_INPUT)
1045 hidinput_disconnect(hid);
1046 if (hid->claimed & HID_CLAIMED_HIDDEV)
1047 hiddev_disconnect(hid);
1048 if (hid->claimed & HID_CLAIMED_HIDRAW)
1049 hidraw_disconnect(hid);
1050
1051 hid->claimed = 0; 1044 hid->claimed = 0;
1052 1045
1053 usb_free_urb(usbhid->urbin); 1046 usb_free_urb(usbhid->urbin);
@@ -1085,7 +1078,7 @@ static struct hid_ll_driver usb_hid_driver = {
1085 .hidinput_input_event = usb_hidinput_input_event, 1078 .hidinput_input_event = usb_hidinput_input_event,
1086}; 1079};
1087 1080
1088static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) 1081static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id)
1089{ 1082{
1090 struct usb_host_interface *interface = intf->cur_altsetting; 1083 struct usb_host_interface *interface = intf->cur_altsetting;
1091 struct usb_device *dev = interface_to_usbdev(intf); 1084 struct usb_device *dev = interface_to_usbdev(intf);
@@ -1117,6 +1110,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
1117 hid->ff_init = hid_pidff_init; 1110 hid->ff_init = hid_pidff_init;
1118#ifdef CONFIG_USB_HIDDEV 1111#ifdef CONFIG_USB_HIDDEV
1119 hid->hiddev_connect = hiddev_connect; 1112 hid->hiddev_connect = hiddev_connect;
1113 hid->hiddev_disconnect = hiddev_disconnect;
1120 hid->hiddev_hid_event = hiddev_hid_event; 1114 hid->hiddev_hid_event = hiddev_hid_event;
1121 hid->hiddev_report_event = hiddev_report_event; 1115 hid->hiddev_report_event = hiddev_report_event;
1122#endif 1116#endif
@@ -1177,7 +1171,7 @@ err:
1177 return ret; 1171 return ret;
1178} 1172}
1179 1173
1180static void hid_disconnect(struct usb_interface *intf) 1174static void usbhid_disconnect(struct usb_interface *intf)
1181{ 1175{
1182 struct hid_device *hid = usb_get_intfdata(intf); 1176 struct hid_device *hid = usb_get_intfdata(intf);
1183 struct usbhid_device *usbhid; 1177 struct usbhid_device *usbhid;
@@ -1359,8 +1353,8 @@ MODULE_DEVICE_TABLE (usb, hid_usb_ids);
1359 1353
1360static struct usb_driver hid_driver = { 1354static struct usb_driver hid_driver = {
1361 .name = "usbhid", 1355 .name = "usbhid",
1362 .probe = hid_probe, 1356 .probe = usbhid_probe,
1363 .disconnect = hid_disconnect, 1357 .disconnect = usbhid_disconnect,
1364#ifdef CONFIG_PM 1358#ifdef CONFIG_PM
1365 .suspend = hid_suspend, 1359 .suspend = hid_suspend,
1366 .resume = hid_resume, 1360 .resume = hid_resume,
diff --git a/include/linux/hid.h b/include/linux/hid.h
index a0ebdace7baa..10f628416740 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -494,6 +494,7 @@ struct hid_device { /* device report descriptor */
494 494
495 /* hiddev event handler */ 495 /* hiddev event handler */
496 int (*hiddev_connect)(struct hid_device *, unsigned int); 496 int (*hiddev_connect)(struct hid_device *, unsigned int);
497 void (*hiddev_disconnect)(struct hid_device *);
497 void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, 498 void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
498 struct hid_usage *, __s32); 499 struct hid_usage *, __s32);
499 void (*hiddev_report_event) (struct hid_device *, struct hid_report *); 500 void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
@@ -691,6 +692,7 @@ struct hid_device *hid_allocate_device(void);
691int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); 692int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
692int hid_check_keys_pressed(struct hid_device *hid); 693int hid_check_keys_pressed(struct hid_device *hid);
693int hid_connect(struct hid_device *hid, unsigned int connect_mask); 694int hid_connect(struct hid_device *hid, unsigned int connect_mask);
695void hid_disconnect(struct hid_device *hid);
694 696
695/** 697/**
696 * hid_map_usage - map usage input bits 698 * hid_map_usage - map usage input bits
@@ -800,6 +802,7 @@ static inline int __must_check hid_hw_start(struct hid_device *hdev,
800 */ 802 */
801static inline void hid_hw_stop(struct hid_device *hdev) 803static inline void hid_hw_stop(struct hid_device *hdev)
802{ 804{
805 hid_disconnect(hdev);
803 hdev->ll_driver->stop(hdev); 806 hdev->ll_driver->stop(hdev);
804} 807}
805 808
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 09bedeb5579c..49d8495d69be 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -577,11 +577,6 @@ static int hidp_session(void *arg)
577 } 577 }
578 578
579 if (session->hid) { 579 if (session->hid) {
580 if (session->hid->claimed & HID_CLAIMED_INPUT)
581 hidinput_disconnect(session->hid);
582 if (session->hid->claimed & HID_CLAIMED_HIDRAW)
583 hidraw_disconnect(session->hid);
584
585 hid_destroy_device(session->hid); 580 hid_destroy_device(session->hid);
586 session->hid = NULL; 581 session->hid = NULL;
587 } 582 }
@@ -747,8 +742,6 @@ static void hidp_stop(struct hid_device *hid)
747 skb_queue_purge(&session->ctrl_transmit); 742 skb_queue_purge(&session->ctrl_transmit);
748 skb_queue_purge(&session->intr_transmit); 743 skb_queue_purge(&session->intr_transmit);
749 744
750 if (hid->claimed & HID_CLAIMED_INPUT)
751 hidinput_disconnect(hid);
752 hid->claimed = 0; 745 hid->claimed = 0;
753} 746}
754 747