From 8aba9a4bcabb791fa4dae89bc2d2ac194793ae9a Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 7 Aug 2009 02:23:44 +0200 Subject: [PATCH] hid2hci: install re-trigger for hid device when recovering from S3 --- extras/hid2hci/70-hid2hci.rules | 6 +-- extras/hid2hci/hid2hci.c | 82 ++++----------------------------- 2 files changed, 13 insertions(+), 75 deletions(-) diff --git a/extras/hid2hci/70-hid2hci.rules b/extras/hid2hci/70-hid2hci.rules index 1af356c99..b332c168e 100644 --- a/extras/hid2hci/70-hid2hci.rules +++ b/extras/hid2hci/70-hid2hci.rules @@ -1,6 +1,6 @@ # do not edit this file, it will be overwritten on update -ACTION!="add", GOTO="hid2hci_end" +ACTION!="add|change", GOTO="hid2hci_end" SUBSYSTEM!="usb", GOTO="hid2hci_end" # Variety of Dell Bluetooth devices - match on a mouse device that is @@ -8,7 +8,7 @@ SUBSYSTEM!="usb", GOTO="hid2hci_end" # Known supported devices: 413c:8154, 413c:8158, 413c:8162 ATTR{bInterfaceClass}=="03", ATTR{bInterfaceSubClass}=="01", ATTR{bInterfaceProtocol}=="02", \ ATTRS{bDeviceClass}=="00", ATTRS{idVendor}=="413c", ATTRS{bmAttributes}=="e0", \ - RUN+="hid2hci --method=dell --devpath=%p" + RUN+="hid2hci --method=dell --devpath=%p", ENV{HID2HCI_SWITCH}="1" # Logitech devices (hidraw) KERNEL=="hidraw*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c70[345abce]|c71[34bc]", \ @@ -21,7 +21,7 @@ ENV{DEVTYPE}!="usb_device", GOTO="hid2hci_end" # device needs to be chased down on the USB bus. ATTR{bDeviceClass}=="e0", ATTR{bDeviceSubClass}=="01", ATTR{bDeviceProtocol}=="01", \ ATTR{idVendor}=="413c", ATTR{bmAttributes}=="e0", \ - ENV{REMOVE_CMD}="hid2hci --method=dell --devpath=%p --find-sibling-intf=03:01:02" + ENV{REMOVE_CMD}="/sbin/udevadm trigger --action=change --subsystem-match=usb --property-match=HID2HCI_SWITCH=1" # CSR devices ATTR{idVendor}=="0a12|0458|05ac", ATTR{idProduct}=="1000", RUN+="hid2hci --method=csr --devpath=%p" diff --git a/extras/hid2hci/hid2hci.c b/extras/hid2hci/hid2hci.c index 298ac39ec..0d0a022d5 100644 --- a/extras/hid2hci/hid2hci.c +++ b/extras/hid2hci/hid2hci.c @@ -191,70 +191,14 @@ static struct usb_device *usb_device_open_from_udev(struct udev_device *usb_dev) return NULL; } -static struct usb_dev_handle *find_device(struct udev_device *udev_dev, const char *sibling_intf) +static struct usb_dev_handle *find_device(struct udev_device *udev_dev) { - struct udev *udev = udev_device_get_udev(udev_dev); struct usb_device *dev; - struct udev_device *udev_parent; - char str[UTIL_NAME_SIZE]; - struct udev_enumerate *enumerate; - struct udev_list_entry *entry; - struct usb_dev_handle *handle = NULL; - - if (sibling_intf == NULL) { - dev = usb_device_open_from_udev(udev_dev); - if (dev == NULL) - return NULL; - return usb_open(dev); - } - - /* find matching sibling of the current usb_device, they share the same hub */ - udev_parent = udev_device_get_parent_with_subsystem_devtype(udev_dev, "usb", "usb_device"); - if (udev_parent == NULL) - return NULL; - enumerate = udev_enumerate_new(udev); - if (enumerate == NULL) + dev = usb_device_open_from_udev(udev_dev); + if (dev == NULL) return NULL; - - udev_enumerate_add_match_subsystem(enumerate, "usb"); - - /* match all childs of the parent */ - util_strscpyl(str, sizeof(str), udev_device_get_sysname(udev_parent), "*", NULL); - udev_enumerate_add_match_sysname(enumerate, str); - - /* match the specified interface */ - util_strscpy(str, sizeof(str), sibling_intf); - str[2] = '\0'; - str[5] = '\0'; - str[8] = '\0'; - if (strcmp(str, "-1") != 0) - udev_enumerate_add_match_sysattr(enumerate, "bInterfaceClass", str); - if (strcmp(&str[3], "-1") != 0) - udev_enumerate_add_match_sysattr(enumerate, "bInterfaceSubClass", &str[3]); - if (strcmp(&str[6], "-1") != 0) - udev_enumerate_add_match_sysattr(enumerate, "bInterfaceProtocol", &str[6]); - - udev_enumerate_scan_devices(enumerate); - udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(enumerate)) { - struct udev_device *udev_device; - - udev_device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(entry)); - if (udev_device != NULL) { - /* get the usb_device of the usb_interface we matched */ - udev_parent = udev_device_get_parent_with_subsystem_devtype(udev_device, "usb", "usb_device"); - if (udev_parent == NULL) - continue; - /* only look at the first matching device */ - dev = usb_device_open_from_udev(udev_parent); - if (dev != NULL) - handle = usb_open(dev); - udev_device_unref(udev_device); - break; - } -} - udev_enumerate_unref(enumerate); - return handle; + return usb_open(dev); } static void usage(const char *error) @@ -268,7 +212,6 @@ static void usage(const char *error) " --mode= mode to switch to [hid|hci] (default hci)\n" " --devpath= sys device path\n" " --method= method to use to switch [csr|logitech-hid|dell]\n" - " --find-sibling-intf= find the sibling device with 00:00:00 (class:subclass:prot)\n" " --help\n\n"); } @@ -279,7 +222,6 @@ int main(int argc, char *argv[]) { "mode", required_argument, NULL, 'm' }, { "devpath", required_argument, NULL, 'p' }, { "method", required_argument, NULL, 'M' }, - { "find-sibling-intf", required_argument, NULL, 'I' }, { } }; enum method { @@ -294,14 +236,13 @@ int main(int argc, char *argv[]) int (*usb_switch)(struct usb_dev_handle *dev, enum mode mode) = NULL; enum mode mode = HCI; const char *devpath = NULL; - const char *sibling_intf = NULL; int err = -1; int rc = 1; for (;;) { int option; - option = getopt_long(argc, argv, "m:p:M:I:qh", options, NULL); + option = getopt_long(argc, argv, "m:p:M:qh", options, NULL); if (option == -1) break; @@ -333,9 +274,6 @@ int main(int argc, char *argv[]) exit(1); } break; - case 'I': - sibling_intf = optarg; - break; case 'h': usage(NULL); default: @@ -377,10 +315,10 @@ int main(int argc, char *argv[]) } } - handle = find_device(dev, sibling_intf); + handle = find_device(dev); if (handle == NULL) { - fprintf(stderr, "error: unable to handle '%s' (intf=%s)\n", - udev_device_get_syspath(dev), sibling_intf); + fprintf(stderr, "error: unable to handle '%s'\n", + udev_device_get_syspath(dev)); goto exit; } err = usb_switch(handle, mode); @@ -402,8 +340,8 @@ int main(int argc, char *argv[]) } if (err < 0) - fprintf(stderr, "error: switching device '%s' (intf=%s) failed.\n", - udev_device_get_syspath(udev_dev), sibling_intf); + fprintf(stderr, "error: switching device '%s' failed.\n", + udev_device_get_syspath(udev_dev)); exit: udev_device_unref(udev_dev); udev_unref(udev); -- 2.30.2