Commit df9a1f48 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[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: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 47104b0d
...@@ -944,21 +944,28 @@ static void hid_reset(void *_hid) ...@@ -944,21 +944,28 @@ static void hid_reset(void *_hid)
dev_dbg(&hid->intf->dev, "resetting device\n"); dev_dbg(&hid->intf->dev, "resetting device\n");
rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
if (rc_lock >= 0) { if (rc_lock >= 0) {
rc = usb_reset_device(hid->dev); rc = usb_reset_composite_device(hid->dev, hid->intf);
if (rc_lock) if (rc_lock)
usb_unlock_device(hid->dev); usb_unlock_device(hid->dev);
} }
clear_bit(HID_RESET_PENDING, &hid->iofl); clear_bit(HID_RESET_PENDING, &hid->iofl);
if (rc == 0) { switch (rc) {
hid->retry_delay = 0; case 0:
if (hid_start_in(hid)) if (!test_bit(HID_IN_RUNNING, &hid->iofl))
hid_io_error(hid); hid_io_error(hid);
} else if (!(rc == -ENODEV || rc == -EHOSTUNREACH || rc == -EINTR)) break;
default:
err("can't reset device, %s-%s/input%d, status %d", err("can't reset device, %s-%s/input%d, status %d",
hid->dev->bus->bus_name, hid->dev->bus->bus_name,
hid->dev->devpath, hid->dev->devpath,
hid->ifnum, rc); hid->ifnum, rc);
/* FALLTHROUGH */
case -EHOSTUNREACH:
case -ENODEV:
case -EINTR:
break;
}
} }
/* Main I/O error handler */ /* Main I/O error handler */
...@@ -2063,11 +2070,29 @@ static int hid_resume(struct usb_interface *intf) ...@@ -2063,11 +2070,29 @@ static int hid_resume(struct usb_interface *intf)
int status; int status;
clear_bit(HID_SUSPENDED, &hid->iofl); clear_bit(HID_SUSPENDED, &hid->iofl);
hid->retry_delay = 0;
status = hid_start_in(hid); status = hid_start_in(hid);
dev_dbg(&intf->dev, "resume status %d\n", status); dev_dbg(&intf->dev, "resume status %d\n", status);
return status; return status;
} }
/* Treat USB reset pretty much the same as suspend/resume */
static void hid_pre_reset(struct usb_interface *intf)
{
/* FIXME: What if the interface is already suspended? */
hid_suspend(intf, PMSG_ON);
}
static void hid_post_reset(struct usb_interface *intf)
{
struct usb_device *dev = interface_to_usbdev (intf);
hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
/* FIXME: Any more reinitialization needed? */
hid_resume(intf);
}
static struct usb_device_id hid_usb_ids [] = { static struct usb_device_id hid_usb_ids [] = {
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
.bInterfaceClass = USB_INTERFACE_CLASS_HID }, .bInterfaceClass = USB_INTERFACE_CLASS_HID },
...@@ -2082,6 +2107,8 @@ static struct usb_driver hid_driver = { ...@@ -2082,6 +2107,8 @@ static struct usb_driver hid_driver = {
.disconnect = hid_disconnect, .disconnect = hid_disconnect,
.suspend = hid_suspend, .suspend = hid_suspend,
.resume = hid_resume, .resume = hid_resume,
.pre_reset = hid_pre_reset,
.post_reset = hid_post_reset,
.id_table = hid_usb_ids, .id_table = hid_usb_ids,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment