aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-06-01 13:55:28 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 18:04:15 -0400
commitdf9a1f482d1252045210f50048911e2efba61e62 (patch)
treea2a581e278e9ef6ede4b58ef73d3388510f06064
parent47104b0dd32cec467574822b0dc3517b3de3f0ad (diff)
[PATCH] usbhid: use usb_reset_composite_device
This patch (as702) makes usbhid use the new usb_reset_composite_device API. Now HID interfaces can coexist with other interfaces on the same device, and a reset can safely be requested by any of the drivers. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/input/hid-core.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index c6051beeabdc..17b6e6ab3703 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -944,21 +944,28 @@ static void hid_reset(void *_hid)
944 dev_dbg(&hid->intf->dev, "resetting device\n"); 944 dev_dbg(&hid->intf->dev, "resetting device\n");
945 rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); 945 rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
946 if (rc_lock >= 0) { 946 if (rc_lock >= 0) {
947 rc = usb_reset_device(hid->dev); 947 rc = usb_reset_composite_device(hid->dev, hid->intf);
948 if (rc_lock) 948 if (rc_lock)
949 usb_unlock_device(hid->dev); 949 usb_unlock_device(hid->dev);
950 } 950 }
951 clear_bit(HID_RESET_PENDING, &hid->iofl); 951 clear_bit(HID_RESET_PENDING, &hid->iofl);
952 952
953 if (rc == 0) { 953 switch (rc) {
954 hid->retry_delay = 0; 954 case 0:
955 if (hid_start_in(hid)) 955 if (!test_bit(HID_IN_RUNNING, &hid->iofl))
956 hid_io_error(hid); 956 hid_io_error(hid);
957 } else if (!(rc == -ENODEV || rc == -EHOSTUNREACH || rc == -EINTR)) 957 break;
958 default:
958 err("can't reset device, %s-%s/input%d, status %d", 959 err("can't reset device, %s-%s/input%d, status %d",
959 hid->dev->bus->bus_name, 960 hid->dev->bus->bus_name,
960 hid->dev->devpath, 961 hid->dev->devpath,
961 hid->ifnum, rc); 962 hid->ifnum, rc);
963 /* FALLTHROUGH */
964 case -EHOSTUNREACH:
965 case -ENODEV:
966 case -EINTR:
967 break;
968 }
962} 969}
963 970
964/* Main I/O error handler */ 971/* Main I/O error handler */
@@ -2063,11 +2070,29 @@ static int hid_resume(struct usb_interface *intf)
2063 int status; 2070 int status;
2064 2071
2065 clear_bit(HID_SUSPENDED, &hid->iofl); 2072 clear_bit(HID_SUSPENDED, &hid->iofl);
2073 hid->retry_delay = 0;
2066 status = hid_start_in(hid); 2074 status = hid_start_in(hid);
2067 dev_dbg(&intf->dev, "resume status %d\n", status); 2075 dev_dbg(&intf->dev, "resume status %d\n", status);
2068 return status; 2076 return status;
2069} 2077}
2070 2078
2079/* Treat USB reset pretty much the same as suspend/resume */
2080static void hid_pre_reset(struct usb_interface *intf)
2081{
2082 /* FIXME: What if the interface is already suspended? */
2083 hid_suspend(intf, PMSG_ON);
2084}
2085
2086static void hid_post_reset(struct usb_interface *intf)
2087{
2088 struct usb_device *dev = interface_to_usbdev (intf);
2089
2090 hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
2091 /* FIXME: Any more reinitialization needed? */
2092
2093 hid_resume(intf);
2094}
2095
2071static struct usb_device_id hid_usb_ids [] = { 2096static struct usb_device_id hid_usb_ids [] = {
2072 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, 2097 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
2073 .bInterfaceClass = USB_INTERFACE_CLASS_HID }, 2098 .bInterfaceClass = USB_INTERFACE_CLASS_HID },
@@ -2082,6 +2107,8 @@ static struct usb_driver hid_driver = {
2082 .disconnect = hid_disconnect, 2107 .disconnect = hid_disconnect,
2083 .suspend = hid_suspend, 2108 .suspend = hid_suspend,
2084 .resume = hid_resume, 2109 .resume = hid_resume,
2110 .pre_reset = hid_pre_reset,
2111 .post_reset = hid_post_reset,
2085 .id_table = hid_usb_ids, 2112 .id_table = hid_usb_ids,
2086}; 2113};
2087 2114