diff --git a/src/Makefile.am b/src/Makefile.am index 56640e2a..8ad3b162 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,8 @@ libratbag_la_SOURCES = \ libratbag-hidraw.h \ libratbag-private.h \ libratbag-test.c \ - libratbag-test.h + libratbag-test.h \ + usb-ids.h libratbag_la_LIBADD = \ libhidpp.la \ @@ -66,7 +67,8 @@ libhidpp_la_SOURCES = \ hidpp10.h \ hidpp10.c \ hidpp20.h \ - hidpp20.c + hidpp20.c \ + usb-ids.h libhidpp_la_LDFLAGS = -lm libutil_la_SOURCES = \ libratbag-util.c \ diff --git a/src/driver-hidpp10.c b/src/driver-hidpp10.c index 71e74590..73202eef 100644 --- a/src/driver-hidpp10.c +++ b/src/driver-hidpp10.c @@ -35,8 +35,6 @@ #include "config.h" -#define USB_VENDOR_ID_LOGITECH 0x046d - #include #include #include @@ -45,6 +43,7 @@ #include #include "hidpp10.h" +#include "usb-ids.h" #include "libratbag-private.h" #include "libratbag-hidraw.h" diff --git a/src/driver-hidpp20.c b/src/driver-hidpp20.c index 66fdce04..a09c34de 100644 --- a/src/driver-hidpp20.c +++ b/src/driver-hidpp20.c @@ -773,6 +773,26 @@ hidpp20_log(void *userdata, enum hidpp_log_priority priority, const char *format log_msg_va(device->ratbag, priority, format, args); } +static void +hidpp20drv_remove(struct ratbag_device *device) +{ + struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device); + struct hidpp20_device *dev = drv_data->dev; + + if (!device) + return; + + ratbag_close_hidraw(device); + + if (drv_data->profiles) + hidpp20_onboard_profiles_destroy(dev, drv_data->profiles); + free(drv_data->controls); + free(drv_data->sensors); + if (drv_data->dev) + hidpp20_device_destroy(drv_data->dev); + free(drv_data); +} + static int hidpp20drv_probe(struct ratbag_device *device) { @@ -792,9 +812,6 @@ hidpp20drv_probe(struct ratbag_device *device) dev = hidpp20_device_new(&base, HIDPP_RECEIVER_IDX); if (!dev) { - log_error(device->ratbag, - "Failed to get HID++2.0 device for %s\n", - device->name); rc = -ENODEV; goto err; } @@ -808,11 +825,9 @@ hidpp20drv_probe(struct ratbag_device *device) drv_data->num_resolutions = 1; drv_data->num_buttons = 8; - if (dev->proto_major >= 2) { - rc = hidpp20drv_20_probe(device); - if (rc) - goto err; - } + rc = hidpp20drv_20_probe(device); + if (rc) + goto err; ratbag_device_init_profiles(device, drv_data->num_profiles, @@ -821,27 +836,10 @@ hidpp20drv_probe(struct ratbag_device *device) return rc; err: - free(drv_data); - ratbag_set_drv_data(device, NULL); + hidpp20drv_remove(device); return rc; } -static void -hidpp20drv_remove(struct ratbag_device *device) -{ - struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device); - struct hidpp20_device *dev = drv_data->dev; - - ratbag_close_hidraw(device); - - if (drv_data->profiles) - hidpp20_onboard_profiles_destroy(dev, drv_data->profiles); - free(drv_data->controls); - free(drv_data->sensors); - hidpp20_device_destroy(drv_data->dev); - free(drv_data); -} - struct ratbag_driver hidpp20_driver = { .name = "Logitech HID++2.0", .id = "hidpp20", diff --git a/src/hidpp20.c b/src/hidpp20.c index 38b82e42..2b707a2b 100644 --- a/src/hidpp20.c +++ b/src/hidpp20.c @@ -1892,6 +1892,9 @@ hidpp20_device_new(const struct hidpp_device *base, unsigned int idx) goto err; } + if (dev->proto_major < 2) + goto err; + rc = hidpp20_feature_set_get(dev); if (rc < 0) goto err; diff --git a/src/liblur.c b/src/liblur.c index e2149ce8..1bb5cb54 100644 --- a/src/liblur.c +++ b/src/liblur.c @@ -30,13 +30,13 @@ #include #include +#include "usb-ids.h" #include "hidpp10.h" #include "libratbag-util.h" #include "liblur.h" #define _EXPORT_ __attribute__ ((visibility("default"))) #define MAX_DEVICES 6 -#define VENDOR_ID_LOGITECH 0x046d struct lur_receiver { int refcount; @@ -113,7 +113,7 @@ lur_device_disconnect(struct lur_device *dev) _EXPORT_ int lur_is_receiver(uint16_t vid, uint16_t pid) { - return (vid == VENDOR_ID_LOGITECH && (pid == 0xc52b || pid == 0xc532)); + return (vid == USB_VENDOR_ID_LOGITECH && (pid == 0xc52b || pid == 0xc532)); } static bool @@ -232,7 +232,7 @@ lur_receiver_enumerate(struct lur_receiver *lur, lur_receiver_ref(lur); dev->refcount = 1; dev->name = strdup_safe(name); - dev->vid = VENDOR_ID_LOGITECH; + dev->vid = USB_VENDOR_ID_LOGITECH; dev->pid = wpid; dev->type = type; dev->serial = serial; diff --git a/src/libratbag.c b/src/libratbag.c index 65e18eea..55067d7a 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -34,6 +34,7 @@ #include #include +#include "usb-ids.h" #include "libratbag-private.h" #include "libratbag-util.h" @@ -283,23 +284,15 @@ out: return rc; } -bool -ratbag_assign_driver(struct ratbag_device *device, - const struct input_id *dev_id, - struct ratbag_test_device *test_device) +static inline bool +ratbag_test_driver(struct ratbag_device *device, + const struct input_id *dev_id, + const char *driver_name, + struct ratbag_test_device *test_device) { struct ratbag *ratbag = device->ratbag; struct ratbag_driver *driver; int rc; - const char *driver_name; - - if (!test_device) { - driver_name = udev_prop_value(device->udev_device, "RATBAG_DRIVER"); - if (!driver_name) - return false; - } else { - driver_name = "test_driver"; - } list_for_each(driver, &ratbag->drivers, link) { if (streq(driver->id, driver_name)) { @@ -311,7 +304,7 @@ ratbag_assign_driver(struct ratbag_device *device, if (!device->driver) { log_error(ratbag, "%s: driver '%s' does not exist\n", device->name, driver_name); - return false; + goto error; } if (test_device) @@ -320,22 +313,64 @@ ratbag_assign_driver(struct ratbag_device *device, rc = device->driver->probe(device); if (rc == 0) { if (!ratbag_sanity_check_device(device)) { - return false; + goto error; } else { - log_debug(ratbag, "driver match found: %s\n", driver->name); + log_debug(ratbag, + "driver match found: %s\n", + device->driver->name); return true; } } - device->driver = NULL; - if (rc != -ENODEV) log_error(ratbag, "%s: error opening hidraw node (%s)\n", device->name, strerror(-rc)); +error: + device->driver = NULL; + return false; } +static inline bool +ratbag_driver_fallback_logitech(struct ratbag_device *device, + const struct input_id *dev_id) +{ + int rc; + + if (dev_id->vendor != USB_VENDOR_ID_LOGITECH) + return false; + + rc = ratbag_test_driver(device, dev_id, "hidpp20", NULL); + if (!rc) + rc = ratbag_test_driver(device, dev_id, "hidpp10", NULL); + + return rc; +} + +bool +ratbag_assign_driver(struct ratbag_device *device, + const struct input_id *dev_id, + struct ratbag_test_device *test_device) +{ + bool rc; + const char *driver_name; + + if (!test_device) { + driver_name = udev_prop_value(device->udev_device, "RATBAG_DRIVER"); + } else { + driver_name = "test_driver"; + } + + if (driver_name) { + rc = ratbag_test_driver(device, dev_id, driver_name, test_device); + } else { + rc = ratbag_driver_fallback_logitech(device, dev_id); + } + + return rc; +} + static inline char* get_device_name(struct udev_device *device) { diff --git a/src/usb-ids.h b/src/usb-ids.h new file mode 100644 index 00000000..f69273e3 --- /dev/null +++ b/src/usb-ids.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2016 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef USB_IDS_H +#define USB_IDS_H + +#define USB_VENDOR_ID_LOGITECH 0x046d + +#endif +