diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-06-01 13:55:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-21 18:04:15 -0400 |
commit | df9a1f482d1252045210f50048911e2efba61e62 (patch) | |
tree | a2a581e278e9ef6ede4b58ef73d3388510f06064 | |
parent | 47104b0dd32cec467574822b0dc3517b3de3f0ad (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.c | 37 |
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 */ | ||
2080 | static 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 | |||
2086 | static 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 | |||
2071 | static struct usb_device_id hid_usb_ids [] = { | 2096 | static 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 | ||