From 92e60dd1a4e04ad606e4dc32a90c214bc05b4d88 Mon Sep 17 00:00:00 2001 From: Alexander Ponyatykh Date: Sat, 16 Nov 2019 23:45:55 +0300 Subject: [PATCH 1/8] Migrate from legacy libusb-0.1 to libusb-1.0 --- debian/changelog | 7 + debian/control | 4 +- debian/patches/00-fix-reinit.patch | 17 +- ...ix-spelling-error => 01-fix-spelling.path} | 14 +- ...from-legacy-libusb-0.1-to-libusb-1.0.patch | 666 ++++++++++++++++++ debian/patches/series | 3 +- 6 files changed, 702 insertions(+), 9 deletions(-) rename debian/patches/{01-fix-spelling-error => 01-fix-spelling.path} (68%) create mode 100644 debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch diff --git a/debian/changelog b/debian/changelog index 6266651..e9a509c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libg15 (1.3.0~svn324-2) unstable; urgency=medium + + * Migrate from legacy libusb-0.1 to libusb-1.0 (closes: bug#810409, + bug#611649). + + -- Alexander Ponyatykh Sun, 17 Nov 2019 00:17:00 +0300 + libg15 (1.3.0~svn324-1) unstable; urgency=medium * New upstream version 1.3.0~svn324. diff --git a/debian/control b/debian/control index 944dd10..ff00fd0 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: libg15 Section: libs Priority: optional Maintainer: Alexander Ponyatykh -Build-Depends: debhelper (>=12), libusb-dev +Build-Depends: debhelper (>=12), libusb-1.0-0-dev (>=2:1.0.22) Standards-Version: 4.4.1 Homepage: https://sourceforge.net/projects/g15tools/ Vcs-Git: https://salsa.debian.org/debian/libg15.git @@ -11,7 +11,7 @@ Vcs-Browser: https://salsa.debian.org/debian/libg15 Package: libg15-1 Architecture: any Multi-Arch: same -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: libusb-1.0-0 (>=2:1.0.22), ${shlibs:Depends}, ${misc:Depends} Description: Library for interfacing with the Logitech G15 keyboards libg15 provides an API for low level control of the LCD display and the extra keys on some Logitech keyboards (G11, G15) diff --git a/debian/patches/00-fix-reinit.patch b/debian/patches/00-fix-reinit.patch index 04e9674..09721f8 100644 --- a/debian/patches/00-fix-reinit.patch +++ b/debian/patches/00-fix-reinit.patch @@ -1,12 +1,21 @@ -Description: fix re_initLibG15() to properly reset internal state. -Author: Alexander Ponyatykh +From: Alexander Ponyatykh +Date: Fri, 15 Nov 2019 02:19:01 +0300 +Subject: fix re_initLibG15() to properly reset internal state. + Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libusb/+bug/1357556 Forwarded: no Last-Update: 2015-05-17 + =================================================================== +--- + libg15.c | 55 ++++++++++++++++++++++++++++--------------------------- + 1 file changed, 28 insertions(+), 27 deletions(-) + +diff --git a/libg15.c b/libg15.c +index 31b2bd6..369ed40 100644 --- a/libg15.c +++ b/libg15.c -@@ -283,19 +283,36 @@ +@@ -283,19 +283,36 @@ static usb_dev_handle * findAndOpenG15() { return keyboard_device; } @@ -52,7 +61,7 @@ Last-Update: 2015-05-17 keyboard_device = findAndOpenG15(); if (!keyboard_device) -@@ -327,28 +344,12 @@ +@@ -327,28 +344,12 @@ int initLibG15() return retval; } diff --git a/debian/patches/01-fix-spelling-error b/debian/patches/01-fix-spelling.path similarity index 68% rename from debian/patches/01-fix-spelling-error rename to debian/patches/01-fix-spelling.path index 9c31d43..abe4ae9 100644 --- a/debian/patches/01-fix-spelling-error +++ b/debian/patches/01-fix-spelling.path @@ -1,6 +1,16 @@ +From: Alexander Ponyatykh +Date: Fri, 15 Nov 2019 02:19:01 +0300 +Subject: fix spelling error + +--- + libg15.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libg15.c b/libg15.c +index 369ed40..ba1c94b 100644 --- a/libg15.c +++ b/libg15.c -@@ -152,7 +152,7 @@ +@@ -152,7 +152,7 @@ static usb_dev_handle * findAndOpenDevice(libg15_devices_t handled_device, int d if (!devh) { g15_log(stderr,G15_LOG_INFO, "Error, could not open the keyboard\n"); @@ -9,7 +19,7 @@ return 0; } -@@ -434,7 +434,7 @@ +@@ -434,7 +434,7 @@ int handle_usb_errors(const char *prefix, int ret) { case -ETIMEDOUT: return G15_ERROR_READING_USB_DEVICE; /* backward-compatibility */ break; diff --git a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch new file mode 100644 index 0000000..0d9e218 --- /dev/null +++ b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch @@ -0,0 +1,666 @@ +From: Alexander Ponyatykh +Date: Fri, 15 Nov 2019 08:46:54 +0300 +Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + +--- + configure.in | 5 +- + libg15.c | 458 ++++++++++++++++++++++++++++------------------------------- + 2 files changed, 222 insertions(+), 241 deletions(-) + +--- a/configure.in ++++ b/configure.in +@@ -31,7 +31,8 @@ + esac + + # Checks for libraries. +-AC_CHECK_LIB([usb], [main], ,AC_MSG_ERROR(["libusb not found. please install it"])) ++AC_CHECK_LIB([usb-1.0], [main], ,AC_MSG_ERROR(["libusb-1.0 not found. Please install it."])) ++AC_CHECK_LIB([usb-1.0], [libusb_set_option], ,AC_MSG_ERROR(["libusb-1.0 is too old. Please upgrade to version 1.0.22 or later."])) + + dnl Some versions of libusb do not honour timeout and block. Suns' version is one of them. + if test "x$libusb_blocks" == "xtrue"; then +@@ -41,7 +42,7 @@ + # Checks for header files. + AC_HEADER_STDC + AC_CHECK_HEADERS([string.h]) +-AC_CHECK_HEADERS([usb.h]) ++AC_CHECK_HEADERS([libusb-1.0/libusb.h]) + + # Checks for typedefs, structures, and compiler characteristics. + AC_C_CONST +--- a/libg15.c ++++ b/libg15.c +@@ -24,14 +24,14 @@ + #include "libg15.h" + #include + #include +-#include ++#include + #include + #include ++#include + #include "config.h" + +-static usb_dev_handle *keyboard_device = 0; ++static libusb_device_handle *keyboard_device = 0; + static int libg15_debugging_enabled = 0; +-static int enospc_slowdown = 0; + + static int found_devicetype = -1; + static int shared_device = 0; +@@ -67,7 +67,8 @@ + void libg15Debug(int option) { + + libg15_debugging_enabled = option; +- usb_set_debug(option); ++ if (option) ++ libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG); + } + + /* debugging wrapper */ +@@ -86,191 +87,205 @@ + + /* return number of connected and supported devices */ + int g15NumberOfConnectedDevices() { +- struct usb_bus *bus = 0; +- struct usb_device *dev = 0; +- int i=0; ++ struct libusb_device_descriptor desc; ++ libusb_device **list; + unsigned int found = 0; + +- for (i=0; g15_devices[i].name !=NULL;i++) +- for (bus = usb_busses; bus; bus = bus->next) ++ ssize_t cnt = libusb_get_device_list(NULL, &list); ++ ++ if (cnt < 0) ++ { ++ g15_log(stderr, G15_LOG_WARN, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); ++ return 0; ++ } ++ ++ for (ssize_t i = 0; i < cnt; i++) + { +- for (dev = bus->devices; dev; dev = dev->next) ++ libusb_get_device_descriptor(list[i], &desc); ++ ++ for (int j = 0; g15_devices[i].name != NULL; j++) + { +- if ((dev->descriptor.idVendor == g15_devices[i].vendorid && dev->descriptor.idProduct == g15_devices[i].productid)) ++ if ((desc.idVendor == g15_devices[j].vendorid && desc.idProduct == g15_devices[j].productid)) + found++; ++ break; + } + } ++ ++ libusb_free_device_list(list, 1); ++ + g15_log(stderr,G15_LOG_INFO,"Found %i supported devices\n",found); + return found; + } + + static int initLibUsb() + { +- usb_init(); +- +- /** +- * usb_find_busses and usb_find_devices both report the number of devices +- * / busses added / removed since the last call. since this is the first +- * call we have to return values != 0 or else we didnt find anything */ ++ int errcode = libusb_init(NULL); + +- if (!usb_find_busses()) +- return G15_ERROR_OPENING_USB_DEVICE; +- +- if (!usb_find_devices()) ++ if (errcode != 0) ++ { ++ g15_log(stderr, G15_LOG_WARN, "Failed to initialize libusb-1.0: %s\n", libusb_strerror(errcode)); + return G15_ERROR_OPENING_USB_DEVICE; ++ } + + return G15_NO_ERROR; + } + +-static usb_dev_handle * findAndOpenDevice(libg15_devices_t handled_device, int device_index) ++static libusb_device_handle * findAndOpenDevice(libg15_devices_t handled_device, int device_index) + { +- struct usb_bus *bus = 0; +- struct usb_device *dev = 0; +- int retries=0; +- int j,i,k,l; +- int interface=0; ++ struct libusb_device_descriptor desc; ++ libusb_device_handle *devh = 0; ++ libusb_device **list = 0; ++ libusb_device *dev = 0; ++ int interface = 0; ++ int retries = 0; ++ int ret; ++ ++ ssize_t cnt = libusb_get_device_list(NULL, &list); + +- for (bus = usb_busses; bus; bus = bus->next) ++ if (cnt < 0) + { +- for (dev = bus->devices; dev; dev = dev->next) ++ g15_log(stderr, G15_LOG_WARN, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); ++ return 0; ++ } ++ ++ for (ssize_t devno = 0; devno < cnt; devno++) ++ { ++ libusb_get_device_descriptor(list[devno], &desc); ++ if (desc.idVendor == handled_device.vendorid && desc.idProduct == handled_device.productid) + { +- if ((dev->descriptor.idVendor == handled_device.vendorid && dev->descriptor.idProduct == handled_device.productid)) +- { +- int ret=0; +- char name_buffer[65535]; +- name_buffer[0] = 0; +- usb_dev_handle *devh = 0; +- found_devicetype = device_index; +- g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); +-#if 0 +- devh = usb_open(dev); +- usb_reset(devh); +- usleep(50*1000); +- usb_close(devh); +-#endif +- devh = usb_open(dev); +- if (!devh) +- { +- g15_log(stderr,G15_LOG_INFO, "Error, could not open the keyboard\n"); +- g15_log(stderr,G15_LOG_INFO, "Perhaps you don't have enough permissions to access it\n"); +- return 0; +- } ++ dev = list[devno]; ++ break; ++ } ++ } ++ ++ if (!dev) { ++ libusb_free_device_list(list, 1); ++ return 0; ++ } ++ ++ found_devicetype = device_index; ++ ++ g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); + +- usleep(50*1000); ++ ret = libusb_open(dev, &devh); ++ libusb_free_device_list(list, 1); + +- g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.bNumConfigurations); ++ if (ret || !devh) ++ { ++ g15_log(stderr,G15_LOG_WARN, "Error, could not open the keyboard: %s\n", libusb_strerror(ret)); ++ return 0; ++ } ++ ++ usleep(50*1000); ++ ++ g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n", desc.bNumConfigurations); + +- /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ +- if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) +- shared_device = 1; ++ /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ ++ if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) ++ shared_device = 1; + +- for (j = 0; jdescriptor.bNumConfigurations;j++){ +- struct usb_config_descriptor *cfg = &dev->config[j]; ++ for (int j = 0; j < desc.bNumConfigurations; j++) ++ { ++ struct libusb_config_descriptor *cfg; ++ if (libusb_get_config_descriptor(dev, j, &cfg)) continue; ++ ++ for (int i = 0; i < cfg->bNumInterfaces; i++) ++ { ++ if (g15DeviceCapabilities() & G15_DEVICE_G510) ++ { ++ if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; ++ } + +- for (i=0;ibNumInterfaces; i++){ +- if (g15DeviceCapabilities()&G15_DEVICE_G510){ +- if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; ++ const struct libusb_interface *ifp = &cfg->interface[i]; ++ /* if endpoints are already known, finish up */ ++ if (g15_keys_endpoint && g15_lcd_endpoint) ++ break; ++ g15_log(stderr, G15_LOG_INFO, "Device has %i Alternate Settings\n", ifp->num_altsetting); ++ ++ for (int k=0; k < ifp->num_altsetting; k++) ++ { ++ const struct libusb_interface_descriptor *as = &ifp->altsetting[k]; ++ /* verify that the interface is for a HID device */ ++ if (as->bInterfaceClass == LIBUSB_CLASS_HID) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Interface %i has %i Endpoints\n", i, as->bNumEndpoints); ++ usleep(50*1000); ++ ++ if (libusb_kernel_driver_active(devh, i) == 1) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Trying to detach driver currently attached.\n"); ++ ++ ret = libusb_detach_kernel_driver(devh, i); ++ if (!ret) ++ { ++ g15_log(stderr,G15_LOG_INFO,"Success, detached the driver\n"); ++ } ++ else ++ { ++ g15_log(stderr,G15_LOG_INFO,"Could not detach the driver, giving up: %s\n", libusb_strerror(ret)); ++ break; + } + +- struct usb_interface *ifp = &cfg->interface[i]; +- /* if endpoints are already known, finish up */ +- if(g15_keys_endpoint && g15_lcd_endpoint) +- break; +- g15_log(stderr, G15_LOG_INFO, "Device has %i Alternate Settings\n", ifp->num_altsetting); +- +- for(k=0;knum_altsetting;k++){ +- struct usb_interface_descriptor *as = &ifp->altsetting[k]; +- /* verify that the interface is for a HID device */ +- if(as->bInterfaceClass==USB_CLASS_HID){ +- g15_log(stderr, G15_LOG_INFO, "Interface %i has %i Endpoints\n", i, as->bNumEndpoints); +- usleep(50*1000); +- /* libusb functions ending in _np are not portable between OS's +- * Non-linux users will need some way to detach the HID driver from +- * the G15 until we work out how to do this for other OS's automatically. +- * For the moment, we just skip this code.. +- */ +-#ifdef LIBUSB_HAS_GET_DRIVER_NP +- ret = usb_get_driver_np(devh, i, name_buffer, 65535); +- /* some kernel versions say that a driver is attached even though there is none +- in this case the name buffer has not been changed +- thanks to RobEngle for pointing this out */ +- if (!ret && name_buffer[0]) +- { +- g15_log(stderr,G15_LOG_INFO,"Trying to detach driver currently attached: \"%s\"\n",name_buffer); +- +- ret = usb_detach_kernel_driver_np(devh, i); +- if (!ret) +- { +- g15_log(stderr,G15_LOG_INFO,"Success, detached the driver\n"); +- } +- else +- { +- g15_log(stderr,G15_LOG_INFO,"Sorry, I could not detach the driver, giving up\n"); +- return 0; +- } +- +- } +-#endif +- /* don't set configuration if device is shared */ +- if(0 == shared_device) { +- ret = usb_set_configuration(devh, 1); +- if (ret) +- { +- g15_log(stderr,G15_LOG_INFO,"Error setting the configuration, this is fatal\n"); +- return 0; +- } +- } +- usleep(50*1000); +- while((ret = usb_claim_interface(devh,i)) && retries <10) { +- usleep(50*1000); +- retries++; +- g15_log(stderr,G15_LOG_INFO,"Trying to claim interface\n"); +- } +- +- if (ret) +- { +- g15_log(stderr,G15_LOG_INFO,"Error claiming interface, good day cruel world\n"); +- return 0; +- } +- +- for (l=0; l< as->bNumEndpoints;l++){ +- struct usb_endpoint_descriptor *ep=&as->endpoint[l]; +- g15_log(stderr, G15_LOG_INFO, "Found %s endpoint %i with address 0x%X maxtransfersize=%i \n", +- 0x80&ep->bEndpointAddress?"\"Extra Keys\"":"\"LCD\"", +- ep->bEndpointAddress&0x0f,ep->bEndpointAddress, ep->wMaxPacketSize +- ); +- +- if(0x80 & ep->bEndpointAddress) { +- g15_keys_endpoint = ep->bEndpointAddress; +- } else { +- g15_lcd_endpoint = ep->bEndpointAddress; +- } +-#if 0 +- usb_resetep(devh,ep->bEndpointAddress); +-#endif +- } +- +- if (ret) +- { +- g15_log(stderr, G15_LOG_INFO, "Error setting Alternate Interface\n"); +- } +- } ++ } ++ /* don't set configuration if device is shared */ ++ if (0 == shared_device) { ++ ret = libusb_set_configuration(devh, 1); ++ if (ret) ++ { ++ g15_log(stderr,G15_LOG_INFO,"Error setting the configuration, this is fatal: %s\n", libusb_strerror(ret)); ++ break; + } + } +- } ++ usleep(50*1000); ++ while((ret = libusb_claim_interface(devh,i)) && retries <10) { ++ usleep(50*1000); ++ retries++; ++ g15_log(stderr,G15_LOG_INFO,"Trying to claim interface\n"); ++ } + ++ if (ret) ++ { ++ g15_log(stderr,G15_LOG_INFO,"Error claiming interface, good day cruel world: %s\n", libusb_strerror(ret)); ++ break; ++ } + +- g15_log(stderr,G15_LOG_INFO,"Done opening the keyboard\n"); +- usleep(500*1000); // sleep a bit for good measure +- return devh; ++ for (int l = 0; l < as->bNumEndpoints; l++) ++ { ++ const struct libusb_endpoint_descriptor *ep=&as->endpoint[l]; ++ g15_log(stderr, G15_LOG_INFO, "Found %s endpoint %i with address 0x%X maxtransfersize=%i \n", ++ 0x80&ep->bEndpointAddress?"\"Extra Keys\"":"\"LCD\"", ++ ep->bEndpointAddress&0x0f,ep->bEndpointAddress, ep->wMaxPacketSize ++ ); ++ ++ if(0x80 & ep->bEndpointAddress) ++ { ++ g15_keys_endpoint = ep->bEndpointAddress; ++ } else { ++ g15_lcd_endpoint = ep->bEndpointAddress; ++ } ++ } ++ } + } + } ++ ++ libusb_free_config_descriptor(cfg); ++ } ++ ++ if (g15_keys_endpoint || g15_lcd_endpoint) { ++ g15_log(stderr,G15_LOG_INFO,"Done opening the keyboard\n"); ++ usleep(500*1000); // sleep a bit for good measure ++ return devh; ++ } else { ++ found_devicetype = -1; ++ libusb_release_interface(devh, 0); ++ libusb_attach_kernel_driver(devh, 0); ++ libusb_close(devh); ++ return 0; + } +- return 0; + } + + +-static usb_dev_handle * findAndOpenG15() { ++static libusb_device_handle * findAndOpenG15() { + int i; + for (i=0; g15_devices[i].name !=NULL ;i++){ + g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name); +@@ -288,19 +303,13 @@ + { + int retval = G15_NO_ERROR; + +- enospc_slowdown = shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; ++ shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; + found_devicetype = -1; + +- if (keyboard_device){ +-#ifndef SUN_LIBUSB +- retval = usb_release_interface (keyboard_device, 0); +- usleep(50*1000); +-#endif +-#if 0 +- retval = usb_reset(keyboard_device); +- usleep(50*1000); +-#endif +- usb_close(keyboard_device); ++ if (keyboard_device) { ++ retval = libusb_release_interface(keyboard_device, 0); ++ libusb_attach_kernel_driver(keyboard_device, 0); ++ libusb_close(keyboard_device); + keyboard_device=0; + return retval; + } +@@ -311,9 +320,6 @@ + { + closeKeyboardDevice(); + +- usb_find_busses(); +- usb_find_devices(); +- + keyboard_device = findAndOpenG15(); + if (!keyboard_device) + return G15_ERROR_OPENING_USB_DEVICE; +@@ -330,10 +336,6 @@ + + g15_log(stderr,G15_LOG_INFO,"%s\n",PACKAGE_STRING); + +-#ifdef SUN_LIBUSB +- g15_log(stderr,G15_LOG_INFO,"Using Sun libusb.\n"); +-#endif +- + g15NumberOfConnectedDevices(); + + keyboard_device = findAndOpenG15(); +@@ -428,36 +430,6 @@ + } + } + +-int handle_usb_errors(const char *prefix, int ret) { +- +- switch (ret){ +- case -ETIMEDOUT: +- return G15_ERROR_READING_USB_DEVICE; /* backward-compatibility */ +- break; +- case -ENOSPC: /* the we don't have enough bandwidth, apparently.. something has to give here.. */ +- g15_log(stderr,G15_LOG_INFO,"usb error: ENOSPC.. reducing speed\n"); +- enospc_slowdown = 1; +- break; +- case -ENODEV: /* the device went away - we probably should attempt to reattach */ +- case -ENXIO: /* host controller bug */ +- case -EINVAL: /* invalid request */ +- case -EAGAIN: /* try again */ +- case -EFBIG: /* too many frames to handle */ +- case -EMSGSIZE: /* msgsize is invalid */ +- g15_log(stderr,G15_LOG_INFO,"usb error: %s %s (%i)\n",prefix,usb_strerror(),ret); +- break; +- case -EPIPE: /* endpoint is stalled */ +- g15_log(stderr,G15_LOG_INFO,"usb error: %s EPIPE! clearing...\n",prefix); +- pthread_mutex_lock(&libusb_mutex); +- usb_clear_halt(keyboard_device, 0x81); +- pthread_mutex_unlock(&libusb_mutex); +- break; +- default: /* timed out */ +- g15_log(stderr,G15_LOG_INFO,"Unknown usb error: %s !! (err is %i (%s))\n",prefix,ret,usb_strerror()); +- } +- return ret; +-} +- + int writePixmapToLCD(unsigned char const *data) + { + int ret = 0; +@@ -474,43 +446,27 @@ + + /* the keyboard needs this magic byte */ + lcd_buffer[0] = 0x03; +- /* in an attempt to reduce peak bus utilisation, we break the transfer into 32 byte chunks and sleep a bit in between. +- It shouldnt make much difference, but then again, the g15 shouldnt be flooding the bus enough to cause ENOSPC, yet +- apparently does on some machines... +- I'm not sure how successful this will be in combatting ENOSPC, but we'll give it try in the real-world. */ +- +- if(enospc_slowdown != 0){ +-#ifndef LIBUSB_BLOCKS +- pthread_mutex_lock(&libusb_mutex); +-#endif +- for(transfercount = 0;transfercount<=31;transfercount++){ +- ret = usb_interrupt_write(keyboard_device, g15_lcd_endpoint, (char*)lcd_buffer+(32*transfercount), 32, 1000); +- if (ret != 32) +- { +- handle_usb_errors ("LCDPixmap Slow Write",ret); +- return G15_ERROR_WRITING_PIXMAP; +- } +- usleep(100); ++ ++ /* transfer entire buffer in one hit */ ++ int transferred = 0; ++ pthread_mutex_lock(&libusb_mutex); ++ ret = libusb_interrupt_transfer(keyboard_device, g15_lcd_endpoint, (char*)lcd_buffer, G15_BUFFER_LEN, &transferred, 1000); ++ pthread_mutex_unlock(&libusb_mutex); ++ if (ret || transferred != G15_BUFFER_LEN) ++ { ++ if (!ret) { ++ g15_log(stderr,G15_LOG_INFO,"LCDPixmap write error: short write.\n"); ++ } else { ++ g15_log(stderr,G15_LOG_INFO,"LCDPixmap write error: %s.\n", libusb_strerror(ret)); + } +-#ifndef LIBUSB_BLOCKS +- pthread_mutex_unlock(&libusb_mutex); +-#endif +- }else{ +- /* transfer entire buffer in one hit */ +-#ifdef LIBUSB_BLOCKS +- ret = usb_interrupt_write(keyboard_device, g15_lcd_endpoint, (char*)lcd_buffer, G15_BUFFER_LEN, 1000); +-#else +- pthread_mutex_lock(&libusb_mutex); +- ret = usb_interrupt_write(keyboard_device, g15_lcd_endpoint, (char*)lcd_buffer, G15_BUFFER_LEN, 1000); +- pthread_mutex_unlock(&libusb_mutex); +-#endif +- if (ret != G15_BUFFER_LEN) +- { +- handle_usb_errors ("LCDPixmap Write",ret); +- return G15_ERROR_WRITING_PIXMAP; ++ if (ret == LIBUSB_ERROR_PIPE) { ++ pthread_mutex_lock(&libusb_mutex); ++ libusb_clear_halt(keyboard_device, g15_lcd_endpoint); ++ pthread_mutex_unlock(&libusb_mutex); + } +- usleep(100); ++ return G15_ERROR_WRITING_PIXMAP; + } ++ usleep(100); + + return 0; + } +@@ -535,7 +491,9 @@ + usb_data[3] = 18; + } + pthread_mutex_lock(&libusb_mutex); +- retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)usb_data, 4, 10000); ++ retval = libusb_control_transfer(keyboard_device, ++ LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE + LIBUSB_ENDPOINT_OUT, ++ 9, 0x302, 0, (char*)usb_data, 4, 10000); + pthread_mutex_unlock(&libusb_mutex); + return retval; + } +@@ -553,7 +511,9 @@ + return G15_ERROR_UNSUPPORTED; + + pthread_mutex_lock(&libusb_mutex); +- retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)m_led_buf, 4, 10000); ++ retval = libusb_control_transfer(keyboard_device, ++ LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE + LIBUSB_ENDPOINT_OUT, ++ 9, 0x302, 0, (char*)m_led_buf, 4, 10000); + pthread_mutex_unlock(&libusb_mutex); + return retval; + } +@@ -578,7 +538,9 @@ + usb_data[2] = 0x00; + } + pthread_mutex_lock(&libusb_mutex); +- retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)usb_data, 4, 10000); ++ retval = libusb_control_transfer(keyboard_device, ++ LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE + LIBUSB_ENDPOINT_OUT, ++ 9, 0x302, 0, (char*)usb_data, 4, 10000); + pthread_mutex_unlock(&libusb_mutex); + return retval; + } +@@ -604,7 +566,9 @@ + usb_data[2] = 0x0; + } + pthread_mutex_lock(&libusb_mutex); +- retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)usb_data, 4, 10000); ++ retval = libusb_control_transfer(keyboard_device, ++ LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE + LIBUSB_ENDPOINT_OUT, ++ 9, 0x302, 0, (char*)usb_data, 4, 10000); + pthread_mutex_unlock(&libusb_mutex); + return retval; + } +@@ -619,7 +583,9 @@ + usb_data[3] = b; + + pthread_mutex_lock(&libusb_mutex); +- retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x305, 1, (char*)usb_data, 4, 10000); ++ retval = libusb_control_transfer(keyboard_device, ++ LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE + LIBUSB_ENDPOINT_OUT, ++ 9, 0x305, 1, (char*)usb_data, 4, 10000); + pthread_mutex_unlock(&libusb_mutex); + return retval; + } +@@ -1033,18 +999,30 @@ + int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) + { + unsigned char buffer[G15_KEY_READ_LENGTH]; ++ int transferred = 0; + int ret = 0; + int caps = 0; + +-#ifdef LIBUSB_BLOCKS +- ret = usb_interrupt_read(keyboard_device, g15_keys_endpoint, (char*)buffer, G15_KEY_READ_LENGTH, timeout); +-#else + pthread_mutex_lock(&libusb_mutex); +- ret = usb_interrupt_read(keyboard_device, g15_keys_endpoint, (char*)buffer, G15_KEY_READ_LENGTH, timeout); ++ ret = libusb_interrupt_transfer(keyboard_device, g15_keys_endpoint, (char*)buffer, G15_KEY_READ_LENGTH, &transferred, timeout); + pthread_mutex_unlock(&libusb_mutex); +-#endif +- if(ret>0) { +- if(buffer[0] == 1) ++ ++ switch (ret) ++ { ++ case 0: ++ break; ++ case LIBUSB_ERROR_TIMEOUT: ++ return G15_ERROR_TIMEOUT; ++ case LIBUSB_ERROR_PIPE: ++ pthread_mutex_lock(&libusb_mutex); ++ libusb_clear_halt(keyboard_device, g15_keys_endpoint); ++ pthread_mutex_unlock(&libusb_mutex); ++ //no break ++ default: ++ g15_log(stderr,G15_LOG_INFO,"USB error on keybaord read: %s.\n", libusb_strerror(ret)); ++ } ++ ++ if (transferred > 0 && buffer[0] == 1) { + return G15_ERROR_TRY_AGAIN; + } + +@@ -1054,7 +1032,7 @@ + return G15_NO_ERROR; + } + +- switch(ret) { ++ switch(transferred) { + case 4: + processKeyEvent4Byte(pressed_keys, buffer); + return G15_NO_ERROR; +@@ -1065,6 +1043,6 @@ + processKeyEvent9Byte(pressed_keys, buffer); + return G15_NO_ERROR; + default: +- return handle_usb_errors("Keyboard Read", ret); /* allow the app to deal with errors */ ++ return G15_ERROR_READING_USB_DEVICE; + } + } diff --git a/debian/patches/series b/debian/patches/series index 8fb2db5..3c0b3b6 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,3 @@ 00-fix-reinit.patch -01-fix-spelling-error +01-fix-spelling.path +02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch From 98449afc5de79bff6b0d7a2f586416d1491d7f89 Mon Sep 17 00:00:00 2001 From: Alexander Ponyatykh Date: Sun, 17 Nov 2019 03:03:53 +0300 Subject: [PATCH 2/8] Delay calling libusb_set_option() until libusb is initialized G15daemon calls libg15Debug() before initLibG15(). This works well with the legacy library, but the new one requres a context to be initialized before calling any functions. This patch adds tracking of libusb initialization status and never calls libusb_set_option() when library is not initialized. --- ...from-legacy-libusb-0.1-to-libusb-1.0.patch | 110 ++++++++++-------- 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch index 0d9e218..07ce397 100644 --- a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch +++ b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch @@ -30,7 +30,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 AC_C_CONST --- a/libg15.c +++ b/libg15.c -@@ -24,14 +24,14 @@ +@@ -24,14 +24,15 @@ #include "libg15.h" #include #include @@ -45,20 +45,22 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 +static libusb_device_handle *keyboard_device = 0; static int libg15_debugging_enabled = 0; -static int enospc_slowdown = 0; ++static int libusb_initialized = 0; static int found_devicetype = -1; static int shared_device = 0; -@@ -67,7 +67,8 @@ +@@ -67,7 +68,9 @@ void libg15Debug(int option) { libg15_debugging_enabled = option; - usb_set_debug(option); -+ if (option) -+ libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG); ++ if (option && libusb_initialized) { ++ libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_WARNING); ++ } } /* debugging wrapper */ -@@ -86,191 +87,205 @@ +@@ -86,191 +89,209 @@ /* return number of connected and supported devices */ int g15NumberOfConnectedDevices() { @@ -102,23 +104,26 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 static int initLibUsb() { - usb_init(); -- ++ int errcode = libusb_init(NULL); + - /** - * usb_find_busses and usb_find_devices both report the number of devices - * / busses added / removed since the last call. since this is the first - * call we have to return values != 0 or else we didnt find anything */ -+ int errcode = libusb_init(NULL); - -- if (!usb_find_busses()) -- return G15_ERROR_OPENING_USB_DEVICE; - -- if (!usb_find_devices()) +- if (!usb_find_busses()) + if (errcode != 0) + { + g15_log(stderr, G15_LOG_WARN, "Failed to initialize libusb-1.0: %s\n", libusb_strerror(errcode)); return G15_ERROR_OPENING_USB_DEVICE; + } +- if (!usb_find_devices()) +- return G15_ERROR_OPENING_USB_DEVICE; ++ libusb_initialized = 1; ++ ++ libg15Debug(libg15_debugging_enabled); + return G15_NO_ERROR; } @@ -139,17 +144,17 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + int ret; + + ssize_t cnt = libusb_get_device_list(NULL, &list); - -- for (bus = usb_busses; bus; bus = bus->next) ++ + if (cnt < 0) - { -- for (dev = bus->devices; dev; dev = dev->next) ++ { + g15_log(stderr, G15_LOG_WARN, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); + return 0; + } -+ + +- for (bus = usb_busses; bus; bus = bus->next) + for (ssize_t devno = 0; devno < cnt; devno++) -+ { + { +- for (dev = bus->devices; dev; dev = dev->next) + libusb_get_device_descriptor(list[devno], &desc); + if (desc.idVendor == handled_device.vendorid && desc.idProduct == handled_device.productid) { @@ -185,14 +190,13 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + } + + found_devicetype = device_index; -+ -+ g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); - usleep(50*1000); ++ g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); ++ + ret = libusb_open(dev, &devh); + libusb_free_device_list(list, 1); - -- g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.bNumConfigurations); ++ + if (ret || !devh) + { + g15_log(stderr,G15_LOG_WARN, "Error, could not open the keyboard: %s\n", libusb_strerror(ret)); @@ -202,21 +206,17 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + usleep(50*1000); + + g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n", desc.bNumConfigurations); - -- /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ -- if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) -- shared_device = 1; ++ + /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ + if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) + shared_device = 1; - -- for (j = 0; jdescriptor.bNumConfigurations;j++){ -- struct usb_config_descriptor *cfg = &dev->config[j]; ++ + for (int j = 0; j < desc.bNumConfigurations; j++) + { + struct libusb_config_descriptor *cfg; + if (libusb_get_config_descriptor(dev, j, &cfg)) continue; -+ + +- g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.bNumConfigurations); + for (int i = 0; i < cfg->bNumInterfaces; i++) + { + if (g15DeviceCapabilities() & G15_DEVICE_G510) @@ -224,15 +224,17 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; + } -- for (i=0;ibNumInterfaces; i++){ -- if (g15DeviceCapabilities()&G15_DEVICE_G510){ -- if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; +- /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ +- if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) +- shared_device = 1; + const struct libusb_interface *ifp = &cfg->interface[i]; + /* if endpoints are already known, finish up */ + if (g15_keys_endpoint && g15_lcd_endpoint) + break; + g15_log(stderr, G15_LOG_INFO, "Device has %i Alternate Settings\n", ifp->num_altsetting); -+ + +- for (j = 0; jdescriptor.bNumConfigurations;j++){ +- struct usb_config_descriptor *cfg = &dev->config[j]; + for (int k=0; k < ifp->num_altsetting; k++) + { + const struct libusb_interface_descriptor *as = &ifp->altsetting[k]; @@ -241,7 +243,10 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + { + g15_log(stderr, G15_LOG_INFO, "Interface %i has %i Endpoints\n", i, as->bNumEndpoints); + usleep(50*1000); -+ + +- for (i=0;ibNumInterfaces; i++){ +- if (g15DeviceCapabilities()&G15_DEVICE_G510){ +- if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; + if (libusb_kernel_driver_active(devh, i) == 1) + { + g15_log(stderr, G15_LOG_INFO, "Trying to detach driver currently attached.\n"); @@ -409,7 +414,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 int i; for (i=0; g15_devices[i].name !=NULL ;i++){ g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name); -@@ -288,19 +303,13 @@ +@@ -288,19 +309,13 @@ { int retval = G15_NO_ERROR; @@ -434,7 +439,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 keyboard_device=0; return retval; } -@@ -311,9 +320,6 @@ +@@ -311,9 +326,6 @@ { closeKeyboardDevice(); @@ -444,7 +449,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 keyboard_device = findAndOpenG15(); if (!keyboard_device) return G15_ERROR_OPENING_USB_DEVICE; -@@ -330,10 +336,6 @@ +@@ -330,10 +342,6 @@ g15_log(stderr,G15_LOG_INFO,"%s\n",PACKAGE_STRING); @@ -455,7 +460,18 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 g15NumberOfConnectedDevices(); keyboard_device = findAndOpenG15(); -@@ -428,36 +430,6 @@ +@@ -347,7 +355,9 @@ + int exitLibG15() + { + pthread_mutex_destroy(&libusb_mutex); +- return closeKeyboardDevice(); ++ int ret = closeKeyboardDevice(); ++ libusb_exit(NULL); ++ libusb_initialized = 0; + } + + static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data) +@@ -428,36 +438,6 @@ } } @@ -492,7 +508,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 int writePixmapToLCD(unsigned char const *data) { int ret = 0; -@@ -474,43 +446,27 @@ +@@ -474,43 +454,27 @@ /* the keyboard needs this magic byte */ lcd_buffer[0] = 0x03; @@ -554,7 +570,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 return 0; } -@@ -535,7 +491,9 @@ +@@ -535,7 +499,9 @@ usb_data[3] = 18; } pthread_mutex_lock(&libusb_mutex); @@ -565,7 +581,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -553,7 +511,9 @@ +@@ -553,7 +519,9 @@ return G15_ERROR_UNSUPPORTED; pthread_mutex_lock(&libusb_mutex); @@ -576,7 +592,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -578,7 +538,9 @@ +@@ -578,7 +546,9 @@ usb_data[2] = 0x00; } pthread_mutex_lock(&libusb_mutex); @@ -587,7 +603,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -604,7 +566,9 @@ +@@ -604,7 +574,9 @@ usb_data[2] = 0x0; } pthread_mutex_lock(&libusb_mutex); @@ -598,7 +614,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -619,7 +583,9 @@ +@@ -619,7 +591,9 @@ usb_data[3] = b; pthread_mutex_lock(&libusb_mutex); @@ -609,7 +625,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -1033,18 +999,30 @@ +@@ -1033,18 +1007,30 @@ int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) { unsigned char buffer[G15_KEY_READ_LENGTH]; @@ -647,7 +663,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 return G15_ERROR_TRY_AGAIN; } -@@ -1054,7 +1032,7 @@ +@@ -1054,7 +1040,7 @@ return G15_NO_ERROR; } @@ -656,7 +672,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 case 4: processKeyEvent4Byte(pressed_keys, buffer); return G15_NO_ERROR; -@@ -1065,6 +1043,6 @@ +@@ -1065,6 +1051,6 @@ processKeyEvent9Byte(pressed_keys, buffer); return G15_NO_ERROR; default: From aa2cf020293e5f6dec031aec0645506c924a1740 Mon Sep 17 00:00:00 2001 From: Alexander Ponyatykh Date: Sun, 17 Nov 2019 03:14:33 +0300 Subject: [PATCH 3/8] Change log level for some error messages Contrary to expectations, G15_LOG_WARN is more verbose level than G15_LOG_INFO. --- debian/changelog | 2 +- ...from-legacy-libusb-0.1-to-libusb-1.0.patch | 104 +++++++++--------- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/debian/changelog b/debian/changelog index e9a509c..3edcc35 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,7 +3,7 @@ libg15 (1.3.0~svn324-2) unstable; urgency=medium * Migrate from legacy libusb-0.1 to libusb-1.0 (closes: bug#810409, bug#611649). - -- Alexander Ponyatykh Sun, 17 Nov 2019 00:17:00 +0300 + -- Alexander Ponyatykh Sun, 17 Nov 2019 03:14:55 +0300 libg15 (1.3.0~svn324-1) unstable; urgency=medium diff --git a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch index 07ce397..7e4f91c 100644 --- a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch +++ b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch @@ -4,12 +4,14 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 --- configure.in | 5 +- - libg15.c | 458 ++++++++++++++++++++++++++++------------------------------- - 2 files changed, 222 insertions(+), 241 deletions(-) + libg15.c | 476 +++++++++++++++++++++++++++++------------------------------ + 2 files changed, 234 insertions(+), 247 deletions(-) +diff --git a/configure.in b/configure.in +index 074d98e..b533d2c 100644 --- a/configure.in +++ b/configure.in -@@ -31,7 +31,8 @@ +@@ -31,7 +31,8 @@ case $host_os in esac # Checks for libraries. @@ -19,7 +21,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 dnl Some versions of libusb do not honour timeout and block. Suns' version is one of them. if test "x$libusb_blocks" == "xtrue"; then -@@ -41,7 +42,7 @@ +@@ -41,7 +42,7 @@ fi # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([string.h]) @@ -28,6 +30,8 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST +diff --git a/libg15.c b/libg15.c +index ba1c94b..435e396 100644 --- a/libg15.c +++ b/libg15.c @@ -24,14 +24,15 @@ @@ -49,7 +53,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 static int found_devicetype = -1; static int shared_device = 0; -@@ -67,7 +68,9 @@ +@@ -67,7 +68,9 @@ int g15DeviceCapabilities() { void libg15Debug(int option) { libg15_debugging_enabled = option; @@ -60,7 +64,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 } /* debugging wrapper */ -@@ -86,191 +89,209 @@ +@@ -86,191 +89,209 @@ static int g15_log (FILE *fd, unsigned int level, const char *fmt, ...) { /* return number of connected and supported devices */ int g15NumberOfConnectedDevices() { @@ -77,7 +81,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + + if (cnt < 0) + { -+ g15_log(stderr, G15_LOG_WARN, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); ++ g15_log(stderr, G15_LOG_INFO, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); + return 0; + } + @@ -104,17 +108,17 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 static int initLibUsb() { - usb_init(); -+ int errcode = libusb_init(NULL); - +- - /** - * usb_find_busses and usb_find_devices both report the number of devices - * / busses added / removed since the last call. since this is the first - * call we have to return values != 0 or else we didnt find anything */ -- ++ int errcode = libusb_init(NULL); + - if (!usb_find_busses()) + if (errcode != 0) + { -+ g15_log(stderr, G15_LOG_WARN, "Failed to initialize libusb-1.0: %s\n", libusb_strerror(errcode)); ++ g15_log(stderr, G15_LOG_INFO, "Failed to initialize libusb-1.0: %s\n", libusb_strerror(errcode)); return G15_ERROR_OPENING_USB_DEVICE; + } @@ -144,17 +148,17 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + int ret; + + ssize_t cnt = libusb_get_device_list(NULL, &list); -+ -+ if (cnt < 0) -+ { -+ g15_log(stderr, G15_LOG_WARN, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); -+ return 0; -+ } - for (bus = usb_busses; bus; bus = bus->next) -+ for (ssize_t devno = 0; devno < cnt; devno++) ++ if (cnt < 0) { - for (dev = bus->devices; dev; dev = dev->next) ++ g15_log(stderr, G15_LOG_INFO, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); ++ return 0; ++ } ++ ++ for (ssize_t devno = 0; devno < cnt; devno++) ++ { + libusb_get_device_descriptor(list[devno], &desc); + if (desc.idVendor == handled_device.vendorid && desc.idProduct == handled_device.productid) { @@ -190,33 +194,38 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + } + + found_devicetype = device_index; ++ ++ g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); - usleep(50*1000); -+ g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); -+ + ret = libusb_open(dev, &devh); + libusb_free_device_list(list, 1); -+ + +- g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.bNumConfigurations); + if (ret || !devh) + { -+ g15_log(stderr,G15_LOG_WARN, "Error, could not open the keyboard: %s\n", libusb_strerror(ret)); ++ g15_log(stderr,G15_LOG_INFO, "Error, could not open the keyboard: %s\n", libusb_strerror(ret)); + return 0; + } + + usleep(50*1000); + + g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n", desc.bNumConfigurations); -+ + +- /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ +- if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) +- shared_device = 1; + /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ + if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) + shared_device = 1; -+ + +- for (j = 0; jdescriptor.bNumConfigurations;j++){ +- struct usb_config_descriptor *cfg = &dev->config[j]; + for (int j = 0; j < desc.bNumConfigurations; j++) + { + struct libusb_config_descriptor *cfg; + if (libusb_get_config_descriptor(dev, j, &cfg)) continue; - -- g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.bNumConfigurations); ++ + for (int i = 0; i < cfg->bNumInterfaces; i++) + { + if (g15DeviceCapabilities() & G15_DEVICE_G510) @@ -224,17 +233,15 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; + } -- /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ -- if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) -- shared_device = 1; +- for (i=0;ibNumInterfaces; i++){ +- if (g15DeviceCapabilities()&G15_DEVICE_G510){ +- if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; + const struct libusb_interface *ifp = &cfg->interface[i]; + /* if endpoints are already known, finish up */ + if (g15_keys_endpoint && g15_lcd_endpoint) + break; + g15_log(stderr, G15_LOG_INFO, "Device has %i Alternate Settings\n", ifp->num_altsetting); - -- for (j = 0; jdescriptor.bNumConfigurations;j++){ -- struct usb_config_descriptor *cfg = &dev->config[j]; ++ + for (int k=0; k < ifp->num_altsetting; k++) + { + const struct libusb_interface_descriptor *as = &ifp->altsetting[k]; @@ -243,10 +250,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + { + g15_log(stderr, G15_LOG_INFO, "Interface %i has %i Endpoints\n", i, as->bNumEndpoints); + usleep(50*1000); - -- for (i=0;ibNumInterfaces; i++){ -- if (g15DeviceCapabilities()&G15_DEVICE_G510){ -- if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; ++ + if (libusb_kernel_driver_active(devh, i) == 1) + { + g15_log(stderr, G15_LOG_INFO, "Trying to detach driver currently attached.\n"); @@ -414,7 +418,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 int i; for (i=0; g15_devices[i].name !=NULL ;i++){ g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name); -@@ -288,19 +309,13 @@ +@@ -288,19 +309,13 @@ static int closeKeyboardDevice() { int retval = G15_NO_ERROR; @@ -439,7 +443,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 keyboard_device=0; return retval; } -@@ -311,9 +326,6 @@ +@@ -311,9 +326,6 @@ int re_initLibG15() { closeKeyboardDevice(); @@ -449,7 +453,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 keyboard_device = findAndOpenG15(); if (!keyboard_device) return G15_ERROR_OPENING_USB_DEVICE; -@@ -330,10 +342,6 @@ +@@ -330,10 +342,6 @@ int initLibG15() g15_log(stderr,G15_LOG_INFO,"%s\n",PACKAGE_STRING); @@ -460,7 +464,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 g15NumberOfConnectedDevices(); keyboard_device = findAndOpenG15(); -@@ -347,7 +355,9 @@ +@@ -347,7 +355,9 @@ int initLibG15() int exitLibG15() { pthread_mutex_destroy(&libusb_mutex); @@ -471,7 +475,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 } static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data) -@@ -428,36 +438,6 @@ +@@ -428,36 +438,6 @@ static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char con } } @@ -508,7 +512,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 int writePixmapToLCD(unsigned char const *data) { int ret = 0; -@@ -474,43 +454,27 @@ +@@ -474,43 +454,27 @@ int writePixmapToLCD(unsigned char const *data) /* the keyboard needs this magic byte */ lcd_buffer[0] = 0x03; @@ -570,7 +574,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 return 0; } -@@ -535,7 +499,9 @@ +@@ -535,7 +499,9 @@ int setLCDContrast(unsigned int level) usb_data[3] = 18; } pthread_mutex_lock(&libusb_mutex); @@ -581,7 +585,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -553,7 +519,9 @@ +@@ -553,7 +519,9 @@ int setLEDs(unsigned int leds) return G15_ERROR_UNSUPPORTED; pthread_mutex_lock(&libusb_mutex); @@ -592,7 +596,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -578,7 +546,9 @@ +@@ -578,7 +546,9 @@ int setLCDBrightness(unsigned int level) usb_data[2] = 0x00; } pthread_mutex_lock(&libusb_mutex); @@ -603,7 +607,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -604,7 +574,9 @@ +@@ -604,7 +574,9 @@ int setKBBrightness(unsigned int level) usb_data[2] = 0x0; } pthread_mutex_lock(&libusb_mutex); @@ -614,7 +618,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -619,7 +591,9 @@ +@@ -619,7 +591,9 @@ int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b) usb_data[3] = b; pthread_mutex_lock(&libusb_mutex); @@ -625,7 +629,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -1033,18 +1007,30 @@ +@@ -1033,18 +1007,30 @@ static void processKeyEvent4Byte(unsigned int *pressed_keys, unsigned char *buff int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) { unsigned char buffer[G15_KEY_READ_LENGTH]; @@ -663,7 +667,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 return G15_ERROR_TRY_AGAIN; } -@@ -1054,7 +1040,7 @@ +@@ -1054,7 +1040,7 @@ int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) return G15_NO_ERROR; } @@ -672,7 +676,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 case 4: processKeyEvent4Byte(pressed_keys, buffer); return G15_NO_ERROR; -@@ -1065,6 +1051,6 @@ +@@ -1065,6 +1051,6 @@ int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) processKeyEvent9Byte(pressed_keys, buffer); return G15_NO_ERROR; default: From 80dac3d2d6d08ffab328538104bace23f4cd1b6b Mon Sep 17 00:00:00 2001 From: Alexander Ponyatykh Date: Sun, 17 Nov 2019 03:56:13 +0300 Subject: [PATCH 4/8] Use explict libusb_context --- ...from-legacy-libusb-0.1-to-libusb-1.0.patch | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch index 7e4f91c..e728f9d 100644 --- a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch +++ b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch @@ -7,11 +7,9 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 libg15.c | 476 +++++++++++++++++++++++++++++------------------------------ 2 files changed, 234 insertions(+), 247 deletions(-) -diff --git a/configure.in b/configure.in -index 074d98e..b533d2c 100644 --- a/configure.in +++ b/configure.in -@@ -31,7 +31,8 @@ case $host_os in +@@ -31,7 +31,8 @@ esac # Checks for libraries. @@ -21,7 +19,7 @@ index 074d98e..b533d2c 100644 dnl Some versions of libusb do not honour timeout and block. Suns' version is one of them. if test "x$libusb_blocks" == "xtrue"; then -@@ -41,7 +42,7 @@ fi +@@ -41,7 +42,7 @@ # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([string.h]) @@ -30,11 +28,9 @@ index 074d98e..b533d2c 100644 # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST -diff --git a/libg15.c b/libg15.c -index ba1c94b..435e396 100644 --- a/libg15.c +++ b/libg15.c -@@ -24,14 +24,15 @@ +@@ -24,20 +24,21 @@ #include "libg15.h" #include #include @@ -49,22 +45,28 @@ index ba1c94b..435e396 100644 +static libusb_device_handle *keyboard_device = 0; static int libg15_debugging_enabled = 0; -static int enospc_slowdown = 0; -+static int libusb_initialized = 0; static int found_devicetype = -1; static int shared_device = 0; -@@ -67,7 +68,9 @@ int g15DeviceCapabilities() { + static int g15_keys_endpoint = 0; + static int g15_lcd_endpoint = 0; + static pthread_mutex_t libusb_mutex; ++static libusb_context *libg15_libusb_context = NULL; + + /* to add a new device, simply create a new DEVICE() in this list */ + /* Fields are: "Name",VendorID,ProductID,Capabilities */ +@@ -67,7 +68,9 @@ void libg15Debug(int option) { libg15_debugging_enabled = option; - usb_set_debug(option); -+ if (option && libusb_initialized) { -+ libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_WARNING); ++ if (option && libg15_libusb_context) { ++ libusb_set_option(libg15_libusb_context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_WARNING); + } } /* debugging wrapper */ -@@ -86,191 +89,209 @@ static int g15_log (FILE *fd, unsigned int level, const char *fmt, ...) { +@@ -86,191 +89,207 @@ /* return number of connected and supported devices */ int g15NumberOfConnectedDevices() { @@ -77,7 +79,7 @@ index ba1c94b..435e396 100644 - for (i=0; g15_devices[i].name !=NULL;i++) - for (bus = usb_busses; bus; bus = bus->next) -+ ssize_t cnt = libusb_get_device_list(NULL, &list); ++ ssize_t cnt = libusb_get_device_list(libg15_libusb_context, &list); + + if (cnt < 0) + { @@ -108,13 +110,13 @@ index ba1c94b..435e396 100644 static int initLibUsb() { - usb_init(); -- ++ int errcode = libusb_init(&libg15_libusb_context); + - /** - * usb_find_busses and usb_find_devices both report the number of devices - * / busses added / removed since the last call. since this is the first - * call we have to return values != 0 or else we didnt find anything */ -+ int errcode = libusb_init(NULL); - +- - if (!usb_find_busses()) + if (errcode != 0) + { @@ -124,8 +126,6 @@ index ba1c94b..435e396 100644 - if (!usb_find_devices()) - return G15_ERROR_OPENING_USB_DEVICE; -+ libusb_initialized = 1; -+ + libg15Debug(libg15_debugging_enabled); return G15_NO_ERROR; @@ -147,7 +147,7 @@ index ba1c94b..435e396 100644 + int retries = 0; + int ret; + -+ ssize_t cnt = libusb_get_device_list(NULL, &list); ++ ssize_t cnt = libusb_get_device_list(libg15_libusb_context, &list); - for (bus = usb_busses; bus; bus = bus->next) + if (cnt < 0) @@ -418,7 +418,7 @@ index ba1c94b..435e396 100644 int i; for (i=0; g15_devices[i].name !=NULL ;i++){ g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name); -@@ -288,19 +309,13 @@ static int closeKeyboardDevice() +@@ -288,19 +307,13 @@ { int retval = G15_NO_ERROR; @@ -443,7 +443,7 @@ index ba1c94b..435e396 100644 keyboard_device=0; return retval; } -@@ -311,9 +326,6 @@ int re_initLibG15() +@@ -311,9 +324,6 @@ { closeKeyboardDevice(); @@ -453,7 +453,7 @@ index ba1c94b..435e396 100644 keyboard_device = findAndOpenG15(); if (!keyboard_device) return G15_ERROR_OPENING_USB_DEVICE; -@@ -330,10 +342,6 @@ int initLibG15() +@@ -330,10 +340,6 @@ g15_log(stderr,G15_LOG_INFO,"%s\n",PACKAGE_STRING); @@ -464,18 +464,18 @@ index ba1c94b..435e396 100644 g15NumberOfConnectedDevices(); keyboard_device = findAndOpenG15(); -@@ -347,7 +355,9 @@ int initLibG15() +@@ -347,7 +353,9 @@ int exitLibG15() { pthread_mutex_destroy(&libusb_mutex); - return closeKeyboardDevice(); + int ret = closeKeyboardDevice(); -+ libusb_exit(NULL); -+ libusb_initialized = 0; ++ libusb_exit(libg15_libusb_context); ++ libg15_libusb_context = NULL; } static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data) -@@ -428,36 +438,6 @@ static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char con +@@ -428,36 +436,6 @@ } } @@ -512,7 +512,7 @@ index ba1c94b..435e396 100644 int writePixmapToLCD(unsigned char const *data) { int ret = 0; -@@ -474,43 +454,27 @@ int writePixmapToLCD(unsigned char const *data) +@@ -474,43 +452,27 @@ /* the keyboard needs this magic byte */ lcd_buffer[0] = 0x03; @@ -574,7 +574,7 @@ index ba1c94b..435e396 100644 return 0; } -@@ -535,7 +499,9 @@ int setLCDContrast(unsigned int level) +@@ -535,7 +497,9 @@ usb_data[3] = 18; } pthread_mutex_lock(&libusb_mutex); @@ -585,7 +585,7 @@ index ba1c94b..435e396 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -553,7 +519,9 @@ int setLEDs(unsigned int leds) +@@ -553,7 +517,9 @@ return G15_ERROR_UNSUPPORTED; pthread_mutex_lock(&libusb_mutex); @@ -596,7 +596,7 @@ index ba1c94b..435e396 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -578,7 +546,9 @@ int setLCDBrightness(unsigned int level) +@@ -578,7 +544,9 @@ usb_data[2] = 0x00; } pthread_mutex_lock(&libusb_mutex); @@ -607,7 +607,7 @@ index ba1c94b..435e396 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -604,7 +574,9 @@ int setKBBrightness(unsigned int level) +@@ -604,7 +572,9 @@ usb_data[2] = 0x0; } pthread_mutex_lock(&libusb_mutex); @@ -618,7 +618,7 @@ index ba1c94b..435e396 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -619,7 +591,9 @@ int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b) +@@ -619,7 +589,9 @@ usb_data[3] = b; pthread_mutex_lock(&libusb_mutex); @@ -629,7 +629,7 @@ index ba1c94b..435e396 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -1033,18 +1007,30 @@ static void processKeyEvent4Byte(unsigned int *pressed_keys, unsigned char *buff +@@ -1033,18 +1005,30 @@ int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) { unsigned char buffer[G15_KEY_READ_LENGTH]; @@ -667,7 +667,7 @@ index ba1c94b..435e396 100644 return G15_ERROR_TRY_AGAIN; } -@@ -1054,7 +1040,7 @@ int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) +@@ -1054,7 +1038,7 @@ return G15_NO_ERROR; } @@ -676,7 +676,7 @@ index ba1c94b..435e396 100644 case 4: processKeyEvent4Byte(pressed_keys, buffer); return G15_NO_ERROR; -@@ -1065,6 +1051,6 @@ int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) +@@ -1065,6 +1049,6 @@ processKeyEvent9Byte(pressed_keys, buffer); return G15_NO_ERROR; default: From bd4495ec0157df9f0e9f1148580256afa705cdff Mon Sep 17 00:00:00 2001 From: Alexander Ponyatykh Date: Sun, 17 Nov 2019 14:28:42 +0300 Subject: [PATCH 5/8] Fix transfer error handling --- debian/changelog | 2 +- ...from-legacy-libusb-0.1-to-libusb-1.0.patch | 152 ++++++++++-------- 2 files changed, 90 insertions(+), 64 deletions(-) diff --git a/debian/changelog b/debian/changelog index 3edcc35..45ccc3d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,7 +3,7 @@ libg15 (1.3.0~svn324-2) unstable; urgency=medium * Migrate from legacy libusb-0.1 to libusb-1.0 (closes: bug#810409, bug#611649). - -- Alexander Ponyatykh Sun, 17 Nov 2019 03:14:55 +0300 + -- Alexander Ponyatykh Sun, 17 Nov 2019 14:29:55 +0300 libg15 (1.3.0~svn324-1) unstable; urgency=medium diff --git a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch index e728f9d..aee2cc4 100644 --- a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch +++ b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch @@ -4,12 +4,14 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 --- configure.in | 5 +- - libg15.c | 476 +++++++++++++++++++++++++++++------------------------------ - 2 files changed, 234 insertions(+), 247 deletions(-) + libg15.c | 504 +++++++++++++++++++++++++++++------------------------------ + 2 files changed, 249 insertions(+), 260 deletions(-) +diff --git a/configure.in b/configure.in +index 074d98e..b533d2c 100644 --- a/configure.in +++ b/configure.in -@@ -31,7 +31,8 @@ +@@ -31,7 +31,8 @@ case $host_os in esac # Checks for libraries. @@ -19,7 +21,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 dnl Some versions of libusb do not honour timeout and block. Suns' version is one of them. if test "x$libusb_blocks" == "xtrue"; then -@@ -41,7 +42,7 @@ +@@ -41,7 +42,7 @@ fi # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([string.h]) @@ -28,6 +30,8 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST +diff --git a/libg15.c b/libg15.c +index ba1c94b..ba01ae0 100644 --- a/libg15.c +++ b/libg15.c @@ -24,20 +24,21 @@ @@ -55,7 +59,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 /* to add a new device, simply create a new DEVICE() in this list */ /* Fields are: "Name",VendorID,ProductID,Capabilities */ -@@ -67,7 +68,9 @@ +@@ -67,7 +68,9 @@ int g15DeviceCapabilities() { void libg15Debug(int option) { libg15_debugging_enabled = option; @@ -66,7 +70,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 } /* debugging wrapper */ -@@ -86,191 +89,207 @@ +@@ -86,191 +89,207 @@ static int g15_log (FILE *fd, unsigned int level, const char *fmt, ...) { /* return number of connected and supported devices */ int g15NumberOfConnectedDevices() { @@ -110,13 +114,13 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 static int initLibUsb() { - usb_init(); -+ int errcode = libusb_init(&libg15_libusb_context); - +- - /** - * usb_find_busses and usb_find_devices both report the number of devices - * / busses added / removed since the last call. since this is the first - * call we have to return values != 0 or else we didnt find anything */ -- ++ int errcode = libusb_init(&libg15_libusb_context); + - if (!usb_find_busses()) + if (errcode != 0) + { @@ -148,17 +152,17 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + int ret; + + ssize_t cnt = libusb_get_device_list(libg15_libusb_context, &list); - -- for (bus = usb_busses; bus; bus = bus->next) ++ + if (cnt < 0) - { -- for (dev = bus->devices; dev; dev = dev->next) ++ { + g15_log(stderr, G15_LOG_INFO, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); + return 0; + } -+ + +- for (bus = usb_busses; bus; bus = bus->next) + for (ssize_t devno = 0; devno < cnt; devno++) -+ { + { +- for (dev = bus->devices; dev; dev = dev->next) + libusb_get_device_descriptor(list[devno], &desc); + if (desc.idVendor == handled_device.vendorid && desc.idProduct == handled_device.productid) { @@ -187,40 +191,40 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + break; + } + } -+ + +- usleep(50*1000); + if (!dev) { + libusb_free_device_list(list, 1); + return 0; + } -+ -+ found_devicetype = device_index; -+ -+ g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); - -- usleep(50*1000); -+ ret = libusb_open(dev, &devh); -+ libusb_free_device_list(list, 1); - g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.bNumConfigurations); ++ found_devicetype = device_index; + +- /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ +- if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) +- shared_device = 1; ++ g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); ++ ++ ret = libusb_open(dev, &devh); ++ libusb_free_device_list(list, 1); ++ + if (ret || !devh) + { + g15_log(stderr,G15_LOG_INFO, "Error, could not open the keyboard: %s\n", libusb_strerror(ret)); + return 0; + } -+ -+ usleep(50*1000); -+ -+ g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n", desc.bNumConfigurations); - -- /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ -- if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) -- shared_device = 1; -+ /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ -+ if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) -+ shared_device = 1; - for (j = 0; jdescriptor.bNumConfigurations;j++){ - struct usb_config_descriptor *cfg = &dev->config[j]; ++ usleep(50*1000); ++ ++ g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n", desc.bNumConfigurations); ++ ++ /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ ++ if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) ++ shared_device = 1; ++ + for (int j = 0; j < desc.bNumConfigurations; j++) + { + struct libusb_config_descriptor *cfg; @@ -232,16 +236,16 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + { + if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; + } - -- for (i=0;ibNumInterfaces; i++){ -- if (g15DeviceCapabilities()&G15_DEVICE_G510){ -- if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; ++ + const struct libusb_interface *ifp = &cfg->interface[i]; + /* if endpoints are already known, finish up */ + if (g15_keys_endpoint && g15_lcd_endpoint) + break; + g15_log(stderr, G15_LOG_INFO, "Device has %i Alternate Settings\n", ifp->num_altsetting); -+ + +- for (i=0;ibNumInterfaces; i++){ +- if (g15DeviceCapabilities()&G15_DEVICE_G510){ +- if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; + for (int k=0; k < ifp->num_altsetting; k++) + { + const struct libusb_interface_descriptor *as = &ifp->altsetting[k]; @@ -418,7 +422,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 int i; for (i=0; g15_devices[i].name !=NULL ;i++){ g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name); -@@ -288,19 +307,13 @@ +@@ -288,19 +307,13 @@ static int closeKeyboardDevice() { int retval = G15_NO_ERROR; @@ -443,7 +447,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 keyboard_device=0; return retval; } -@@ -311,9 +324,6 @@ +@@ -311,9 +324,6 @@ int re_initLibG15() { closeKeyboardDevice(); @@ -453,7 +457,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 keyboard_device = findAndOpenG15(); if (!keyboard_device) return G15_ERROR_OPENING_USB_DEVICE; -@@ -330,10 +340,6 @@ +@@ -330,10 +340,6 @@ int initLibG15() g15_log(stderr,G15_LOG_INFO,"%s\n",PACKAGE_STRING); @@ -464,7 +468,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 g15NumberOfConnectedDevices(); keyboard_device = findAndOpenG15(); -@@ -347,7 +353,9 @@ +@@ -347,7 +353,9 @@ int initLibG15() int exitLibG15() { pthread_mutex_destroy(&libusb_mutex); @@ -475,7 +479,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 } static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data) -@@ -428,36 +436,6 @@ +@@ -428,36 +436,6 @@ static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char con } } @@ -512,7 +516,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 int writePixmapToLCD(unsigned char const *data) { int ret = 0; -@@ -474,43 +452,27 @@ +@@ -474,43 +452,27 @@ int writePixmapToLCD(unsigned char const *data) /* the keyboard needs this magic byte */ lcd_buffer[0] = 0x03; @@ -574,7 +578,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 return 0; } -@@ -535,7 +497,9 @@ +@@ -535,7 +497,9 @@ int setLCDContrast(unsigned int level) usb_data[3] = 18; } pthread_mutex_lock(&libusb_mutex); @@ -585,7 +589,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -553,7 +517,9 @@ +@@ -553,7 +517,9 @@ int setLEDs(unsigned int leds) return G15_ERROR_UNSUPPORTED; pthread_mutex_lock(&libusb_mutex); @@ -596,7 +600,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -578,7 +544,9 @@ +@@ -578,7 +544,9 @@ int setLCDBrightness(unsigned int level) usb_data[2] = 0x00; } pthread_mutex_lock(&libusb_mutex); @@ -607,7 +611,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -604,7 +572,9 @@ +@@ -604,7 +572,9 @@ int setKBBrightness(unsigned int level) usb_data[2] = 0x0; } pthread_mutex_lock(&libusb_mutex); @@ -618,7 +622,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -619,7 +589,9 @@ +@@ -619,7 +589,9 @@ int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b) usb_data[3] = b; pthread_mutex_lock(&libusb_mutex); @@ -629,7 +633,7 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -1033,18 +1005,30 @@ +@@ -1033,38 +1005,54 @@ static void processKeyEvent4Byte(unsigned int *pressed_keys, unsigned char *buff int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) { unsigned char buffer[G15_KEY_READ_LENGTH]; @@ -661,26 +665,48 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 + //no break + default: + g15_log(stderr,G15_LOG_INFO,"USB error on keybaord read: %s.\n", libusb_strerror(ret)); ++ return G15_ERROR_READING_USB_DEVICE; + } + + if (transferred > 0 && buffer[0] == 1) { return G15_ERROR_TRY_AGAIN; } -@@ -1054,7 +1038,7 @@ - return G15_NO_ERROR; + caps = g15DeviceCapabilities(); +- if((caps & G15_DEVICE_G13) && buffer[0]==0x25){ +- processKeyEventG13(pressed_keys, buffer); +- return G15_NO_ERROR; ++ if ((caps & G15_DEVICE_G13) && buffer[0]==0x25) ++ { ++ processKeyEventG13(pressed_keys, buffer); ++ return G15_NO_ERROR; } - switch(ret) { -+ switch(transferred) { - case 4: - processKeyEvent4Byte(pressed_keys, buffer); - return G15_NO_ERROR; -@@ -1065,6 +1049,6 @@ - processKeyEvent9Byte(pressed_keys, buffer); - return G15_NO_ERROR; - default: +- case 4: +- processKeyEvent4Byte(pressed_keys, buffer); +- return G15_NO_ERROR; +- case 5: +- processKeyEvent5Byte(pressed_keys, buffer); +- return G15_NO_ERROR; +- case 9: +- processKeyEvent9Byte(pressed_keys, buffer); +- return G15_NO_ERROR; +- default: - return handle_usb_errors("Keyboard Read", ret); /* allow the app to deal with errors */ -+ return G15_ERROR_READING_USB_DEVICE; ++ switch (transferred) ++ { ++ case 4: ++ processKeyEvent4Byte(pressed_keys, buffer); ++ return G15_NO_ERROR; ++ case 5: ++ processKeyEvent5Byte(pressed_keys, buffer); ++ return G15_NO_ERROR; ++ case 9: ++ processKeyEvent9Byte(pressed_keys, buffer); ++ return G15_NO_ERROR; ++ default: ++ g15_log(stderr, G15_LOG_INFO,"USB error on keybaord read: unsupported packet size.\n"); ++ return G15_ERROR_READING_USB_DEVICE; } } From 0408478701915ed19b4925bde6df9a8e4ffc240c Mon Sep 17 00:00:00 2001 From: Alexander Ponyatykh Date: Mon, 18 Nov 2019 02:43:48 +0300 Subject: [PATCH 6/8] Rewrite of initialization and deinitialization functions Original code iterates through every possible descriptor in nested loops and tries to do initialization every iteration without considered what are those descriptors for nor stopping when interface is finally claimed. It has following problems: 1. It iterates through all configurations, but explicitly resets a device configuration to 1 every iteration. 2. It never configures a possibly shared device even it is currently unconfigured. 3. It treats alternative settings as independent interfaces and iterates through them while implicitly setting alternative setting to 0. 4. It can claim several interfaces but uses only the last one. 5. It doesn't track claimed interfaces' number and always deinitializes interface 0. This in fact works for a device with single configuration, single interface and no alternative settings, like most of the supported devices (except G510), but it is fundamentally incorrect. Therefore as part of migration to libusb 1.0 I've rewritten the initialization procedure in a more linear way. First it selects a configuration, which is 1 in most cases. Next it iterates through descriptors in this configuration to find a single compatible interface. Only after that it resets the device and claims the interface. --- debian/changelog | 2 +- ...from-legacy-libusb-0.1-to-libusb-1.0.patch | 462 +++++++++++------- 2 files changed, 284 insertions(+), 180 deletions(-) diff --git a/debian/changelog b/debian/changelog index 45ccc3d..a355542 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,7 +3,7 @@ libg15 (1.3.0~svn324-2) unstable; urgency=medium * Migrate from legacy libusb-0.1 to libusb-1.0 (closes: bug#810409, bug#611649). - -- Alexander Ponyatykh Sun, 17 Nov 2019 14:29:55 +0300 + -- Alexander Ponyatykh Mon, 18 Nov 2019 02:44:19 +0300 libg15 (1.3.0~svn324-1) unstable; urgency=medium diff --git a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch index aee2cc4..b5a21b1 100644 --- a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch +++ b/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch @@ -4,8 +4,8 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 --- configure.in | 5 +- - libg15.c | 504 +++++++++++++++++++++++++++++------------------------------ - 2 files changed, 249 insertions(+), 260 deletions(-) + libg15.c | 615 +++++++++++++++++++++++++++++++---------------------------- + 2 files changed, 327 insertions(+), 293 deletions(-) diff --git a/configure.in b/configure.in index 074d98e..b533d2c 100644 @@ -31,10 +31,10 @@ index 074d98e..b533d2c 100644 # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/libg15.c b/libg15.c -index ba1c94b..ba01ae0 100644 +index ba1c94b..4c0afc4 100644 --- a/libg15.c +++ b/libg15.c -@@ -24,20 +24,21 @@ +@@ -24,20 +24,22 @@ #include "libg15.h" #include #include @@ -54,12 +54,13 @@ index ba1c94b..ba01ae0 100644 static int shared_device = 0; static int g15_keys_endpoint = 0; static int g15_lcd_endpoint = 0; ++static int g15_interface_id = -1; static pthread_mutex_t libusb_mutex; +static libusb_context *libg15_libusb_context = NULL; /* to add a new device, simply create a new DEVICE() in this list */ /* Fields are: "Name",VendorID,ProductID,Capabilities */ -@@ -67,7 +68,9 @@ int g15DeviceCapabilities() { +@@ -67,7 +69,9 @@ int g15DeviceCapabilities() { void libg15Debug(int option) { libg15_debugging_enabled = option; @@ -70,7 +71,7 @@ index ba1c94b..ba01ae0 100644 } /* debugging wrapper */ -@@ -86,191 +89,207 @@ static int g15_log (FILE *fd, unsigned int level, const char *fmt, ...) { +@@ -86,234 +90,281 @@ static int g15_log (FILE *fd, unsigned int level, const char *fmt, ...) { /* return number of connected and supported devices */ int g15NumberOfConnectedDevices() { @@ -114,13 +115,13 @@ index ba1c94b..ba01ae0 100644 static int initLibUsb() { - usb_init(); -- ++ int errcode = libusb_init(&libg15_libusb_context); + - /** - * usb_find_busses and usb_find_devices both report the number of devices - * / busses added / removed since the last call. since this is the first - * call we have to return values != 0 or else we didnt find anything */ -+ int errcode = libusb_init(&libg15_libusb_context); - +- - if (!usb_find_busses()) + if (errcode != 0) + { @@ -136,19 +137,21 @@ index ba1c94b..ba01ae0 100644 } -static usb_dev_handle * findAndOpenDevice(libg15_devices_t handled_device, int device_index) -+static libusb_device_handle * findAndOpenDevice(libg15_devices_t handled_device, int device_index) ++static libusb_device_handle* findAndOpenG15() { - struct usb_bus *bus = 0; - struct usb_device *dev = 0; - int retries=0; - int j,i,k,l; - int interface=0; -+ struct libusb_device_descriptor desc; ++ struct libusb_config_descriptor *cfg = NULL; + libusb_device_handle *devh = 0; ++ libusb_device *dev = NULL; + libusb_device **list = 0; -+ libusb_device *dev = 0; -+ int interface = 0; -+ int retries = 0; ++ /* Use configuration 1 by default. */ ++ int configuration = 1; ++ int unconfigured = 0; ++ int found_dev = -1; + int ret; + + ssize_t cnt = libusb_get_device_list(libg15_libusb_context, &list); @@ -160,14 +163,16 @@ index ba1c94b..ba01ae0 100644 + } - for (bus = usb_busses; bus; bus = bus->next) -+ for (ssize_t devno = 0; devno < cnt; devno++) ++ for (ssize_t devno = 0; devno < cnt && found_dev == -1; devno++) { - for (dev = bus->devices; dev; dev = dev->next) -+ libusb_get_device_descriptor(list[devno], &desc); -+ if (desc.idVendor == handled_device.vendorid && desc.idProduct == handled_device.productid) - { +- { - if ((dev->descriptor.idVendor == handled_device.vendorid && dev->descriptor.idProduct == handled_device.productid)) -- { ++ struct libusb_device_descriptor desc; ++ libusb_get_device_descriptor(list[devno], &desc); ++ for (int i = 0; g15_devices[i].name != NULL && found_dev == -1; i++) { ++ if (desc.idVendor == g15_devices[i].vendorid && desc.idProduct == g15_devices[i].productid) + { - int ret=0; - char name_buffer[65535]; - name_buffer[0] = 0; @@ -187,89 +192,23 @@ index ba1c94b..ba01ae0 100644 - g15_log(stderr,G15_LOG_INFO, "Perhaps you don't have enough permissions to access it\n"); - return 0; - } -+ dev = list[devno]; -+ break; -+ } -+ } - +- - usleep(50*1000); -+ if (!dev) { -+ libusb_free_device_list(list, 1); -+ return 0; -+ } - +- - g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.bNumConfigurations); -+ found_devicetype = device_index; - +- - /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ - if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) - shared_device = 1; -+ g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name); -+ -+ ret = libusb_open(dev, &devh); -+ libusb_free_device_list(list, 1); -+ -+ if (ret || !devh) -+ { -+ g15_log(stderr,G15_LOG_INFO, "Error, could not open the keyboard: %s\n", libusb_strerror(ret)); -+ return 0; -+ } - +- - for (j = 0; jdescriptor.bNumConfigurations;j++){ - struct usb_config_descriptor *cfg = &dev->config[j]; -+ usleep(50*1000); -+ -+ g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n", desc.bNumConfigurations); -+ -+ /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */ -+ if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) -+ shared_device = 1; -+ -+ for (int j = 0; j < desc.bNumConfigurations; j++) -+ { -+ struct libusb_config_descriptor *cfg; -+ if (libusb_get_config_descriptor(dev, j, &cfg)) continue; -+ -+ for (int i = 0; i < cfg->bNumInterfaces; i++) -+ { -+ if (g15DeviceCapabilities() & G15_DEVICE_G510) -+ { -+ if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; -+ } -+ -+ const struct libusb_interface *ifp = &cfg->interface[i]; -+ /* if endpoints are already known, finish up */ -+ if (g15_keys_endpoint && g15_lcd_endpoint) -+ break; -+ g15_log(stderr, G15_LOG_INFO, "Device has %i Alternate Settings\n", ifp->num_altsetting); - +- - for (i=0;ibNumInterfaces; i++){ - if (g15DeviceCapabilities()&G15_DEVICE_G510){ - if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue; -+ for (int k=0; k < ifp->num_altsetting; k++) -+ { -+ const struct libusb_interface_descriptor *as = &ifp->altsetting[k]; -+ /* verify that the interface is for a HID device */ -+ if (as->bInterfaceClass == LIBUSB_CLASS_HID) -+ { -+ g15_log(stderr, G15_LOG_INFO, "Interface %i has %i Endpoints\n", i, as->bNumEndpoints); -+ usleep(50*1000); -+ -+ if (libusb_kernel_driver_active(devh, i) == 1) -+ { -+ g15_log(stderr, G15_LOG_INFO, "Trying to detach driver currently attached.\n"); -+ -+ ret = libusb_detach_kernel_driver(devh, i); -+ if (!ret) -+ { -+ g15_log(stderr,G15_LOG_INFO,"Success, detached the driver\n"); -+ } -+ else -+ { -+ g15_log(stderr,G15_LOG_INFO,"Could not detach the driver, giving up: %s\n", libusb_strerror(ret)); -+ break; - } - +- } +- - struct usb_interface *ifp = &cfg->interface[i]; - /* if endpoints are already known, finish up */ - if(g15_keys_endpoint && g15_lcd_endpoint) @@ -353,83 +292,209 @@ index ba1c94b..ba01ae0 100644 - g15_log(stderr, G15_LOG_INFO, "Error setting Alternate Interface\n"); - } - } -+ } -+ /* don't set configuration if device is shared */ -+ if (0 == shared_device) { -+ ret = libusb_set_configuration(devh, 1); -+ if (ret) -+ { -+ g15_log(stderr,G15_LOG_INFO,"Error setting the configuration, this is fatal: %s\n", libusb_strerror(ret)); -+ break; - } - } +- } +- } - } -+ usleep(50*1000); -+ while((ret = libusb_claim_interface(devh,i)) && retries <10) { -+ usleep(50*1000); -+ retries++; -+ g15_log(stderr,G15_LOG_INFO,"Trying to claim interface\n"); -+ } - -+ if (ret) -+ { -+ g15_log(stderr,G15_LOG_INFO,"Error claiming interface, good day cruel world: %s\n", libusb_strerror(ret)); -+ break; -+ } - +- +- - g15_log(stderr,G15_LOG_INFO,"Done opening the keyboard\n"); - usleep(500*1000); // sleep a bit for good measure - return devh; -+ for (int l = 0; l < as->bNumEndpoints; l++) -+ { -+ const struct libusb_endpoint_descriptor *ep=&as->endpoint[l]; -+ g15_log(stderr, G15_LOG_INFO, "Found %s endpoint %i with address 0x%X maxtransfersize=%i \n", -+ 0x80&ep->bEndpointAddress?"\"Extra Keys\"":"\"LCD\"", -+ ep->bEndpointAddress&0x0f,ep->bEndpointAddress, ep->wMaxPacketSize -+ ); -+ -+ if(0x80 & ep->bEndpointAddress) -+ { -+ g15_keys_endpoint = ep->bEndpointAddress; -+ } else { -+ g15_lcd_endpoint = ep->bEndpointAddress; -+ } -+ } -+ } ++ found_dev = i; ++ dev = list[devno]; ++ g15_log(stderr, G15_LOG_INFO, "Found bus %03u port %03u device %03u ID %04x:%04x %s\n", ++ libusb_get_bus_number(list[devno]), ++ libusb_get_port_number(list[devno]), ++ libusb_get_device_address(list[devno]), ++ desc.idVendor, ++ desc.idProduct, ++ g15_devices[i].name); ++ g15_log(stderr, G15_LOG_INFO, "Device has %u possible configuration%s\n", desc.bNumConfigurations, desc.bNumConfigurations > 1 ? "s" : ""); } } -+ -+ libusb_free_config_descriptor(cfg); -+ } -+ -+ if (g15_keys_endpoint || g15_lcd_endpoint) { -+ g15_log(stderr,G15_LOG_INFO,"Done opening the keyboard\n"); -+ usleep(500*1000); // sleep a bit for good measure -+ return devh; -+ } else { -+ found_devicetype = -1; -+ libusb_release_interface(devh, 0); -+ libusb_attach_kernel_driver(devh, 0); -+ libusb_close(devh); -+ return 0; } - return 0; - } +-} ++ if (found_dev == -1) { ++ libusb_free_device_list(list, 1); ++ g15_log(stderr, G15_LOG_INFO, "No supported devices found\n"); ++ return 0; ++ } -static usb_dev_handle * findAndOpenG15() { -+static libusb_device_handle * findAndOpenG15() { - int i; - for (i=0; g15_devices[i].name !=NULL ;i++){ - g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name); -@@ -288,19 +307,13 @@ static int closeKeyboardDevice() - { - int retval = G15_NO_ERROR; - -- enospc_slowdown = shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; +- int i; +- for (i=0; g15_devices[i].name !=NULL ;i++){ +- g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name); +- if(keyboard_device = findAndOpenDevice(g15_devices[i],i)){ ++ pthread_mutex_lock(&libusb_mutex); ++ ++ if (found_devicetype != -1) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Error, device is already open\n"); ++ goto error; ++ } ++ ++ found_devicetype = found_dev; ++ ret = libusb_open(dev, &devh); ++ libusb_free_device_list(list, 1); ++ list = NULL; ++ ++ if (ret || !devh) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Error, could not open the keyboard: %s\n", libusb_strerror(ret)); ++ goto error; ++ } ++ ++ /* If device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls. */ ++ if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED) ++ { ++ shared_device = 1; ++ ret = libusb_get_configuration(devh, &configuration); ++ if (ret) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Error, could not retrieve current configuration: %s\n", libusb_strerror(ret)); ++ goto error; ++ } ++ else if (configuration < 1) ++ { ++ unconfigured = 1; ++ configuration = 1; ++ } ++ else if (configuration != 1) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Warning, using unknown configuration %i for shared device\n", configuration); ++ } ++ } ++ ++ ret = libusb_get_config_descriptor_by_value(dev, configuration, &cfg); ++ ++ if (ret) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Error, could not retrieve descriptor for configuration %i: %s\n", ++ configuration, libusb_strerror(ret)); ++ ++ goto error; ++ } ++ ++ g15_log(stderr, G15_LOG_INFO, "Device has %u possible interface%s for configuration %i\n", ++ cfg->bNumInterfaces, cfg->bNumInterfaces > 1 ? "s" : "", configuration); ++ ++ const struct libusb_interface_descriptor *iface = NULL; ++ for (int i = 0; i < cfg->bNumInterfaces; i++) ++ { ++ /* Always use altsetting 0, others are not supported even if exist. */ ++ iface = &cfg->interface[i].altsetting[0]; ++ if ((g15DeviceCapabilities() & G15_DEVICE_G510) && iface->bInterfaceNumber == G510_STANDARD_KEYBOARD_INTERFACE) continue; ++ ++ if (iface->bInterfaceClass == LIBUSB_CLASS_HID && iface->bNumEndpoints > 0) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Selecting HID interface %u, it has %u possible altsetting%s\n", ++ iface->bInterfaceNumber, cfg->interface[i].num_altsetting, cfg->interface[i].num_altsetting > 1 ? "s" : ""); ++ ++ g15_interface_id = iface->bInterfaceNumber; + break; + } ++ } ++ ++ if (g15_interface_id == -1) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Error, could not find suitable HID interface\n"); ++ goto error; ++ } ++ ++ for (int i = 0; i < iface->bNumEndpoints; i++) ++ { ++ const struct libusb_endpoint_descriptor *ep = &iface->endpoint[i]; ++ g15_log(stderr, G15_LOG_INFO, "Found %s endpoint %i with address 0x%X maxtransfersize=%i\n", ++ 0x80 & ep->bEndpointAddress ? "\"Extra Keys\"" : "\"LCD\"", ++ ep->bEndpointAddress & 0x0f, ep->bEndpointAddress, ep->wMaxPacketSize); ++ ++ if (0x80 & ep->bEndpointAddress) ++ { ++ g15_keys_endpoint = ep->bEndpointAddress; ++ } + else +- g15_log(stderr,G15_LOG_INFO,"%s not found\n",g15_devices[i].name); ++ { ++ g15_lcd_endpoint = ep->bEndpointAddress; ++ } ++ } ++ ++ if (libusb_kernel_driver_active(devh, g15_interface_id) == 1) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Trying to detach driver currently attached\n"); ++ ++ ret = libusb_detach_kernel_driver(devh, g15_interface_id); ++ if (!ret) ++ { ++ g15_log(stderr,G15_LOG_INFO,"Success, detached the driver\n"); ++ } ++ else ++ { ++ g15_log(stderr,G15_LOG_INFO,"Could not detach the driver, giving up: %s\n", libusb_strerror(ret)); ++ goto error; ++ } ++ } ++ ++ if(!shared_device || unconfigured) ++ { ++ /* Set configuration, reset state, reset altsetting to 0 */ ++ ret = libusb_set_configuration(devh, 1); ++ if (ret) ++ { ++ g15_log(stderr,G15_LOG_INFO,"Error setting the configuration: %s\n", libusb_strerror(ret)); ++ goto error; ++ } ++ } ++ ++ ret = 1; ++ for (int i = 0; i < 10 && ret; i++) ++ { ++ usleep(50 * 1000); ++ g15_log(stderr, G15_LOG_INFO, "Trying to claim interface\n"); ++ ret = libusb_claim_interface(devh, g15_interface_id); ++ } ++ ++ if (ret) ++ { ++ g15_log(stderr, G15_LOG_INFO, "Error claiming interface, good day cruel world: %s\n", libusb_strerror(ret)); ++ goto error; ++ } ++ ++ libusb_free_config_descriptor(cfg); ++ ++ g15_log(stderr, G15_LOG_INFO, "Done opening the keyboard\n"); ++ ++ pthread_mutex_unlock(&libusb_mutex); ++ ++ return devh; ++ ++error: ++ if (devh) ++ { ++ libusb_attach_kernel_driver(devh, 0); ++ libusb_close(devh); + } +- return keyboard_device; ++ if (cfg) libusb_free_config_descriptor(cfg); ++ if (list) libusb_free_device_list(list, 1); + shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; - found_devicetype = -1; ++ g15_interface_id = found_devicetype = -1; ++ pthread_mutex_unlock(&libusb_mutex); ++ ++ return 0; + } ++ + /* reset the keyboard, returning it to a known state */ + static int closeKeyboardDevice() + { +- int retval = G15_NO_ERROR; +- +- enospc_slowdown = shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; +- found_devicetype = -1; +- - if (keyboard_device){ -#ifndef SUN_LIBUSB - retval = usb_release_interface (keyboard_device, 0); @@ -440,14 +505,28 @@ index ba1c94b..ba01ae0 100644 - usleep(50*1000); -#endif - usb_close(keyboard_device); +- keyboard_device=0; +- return retval; ++ int retval = G15_ERROR_OPENING_USB_DEVICE; ++ ++ pthread_mutex_lock(&libusb_mutex); + if (keyboard_device) { + retval = libusb_release_interface(keyboard_device, 0); + libusb_attach_kernel_driver(keyboard_device, 0); + libusb_close(keyboard_device); - keyboard_device=0; - return retval; ++ keyboard_device = NULL; ++ retval = G15_NO_ERROR; } -@@ -311,9 +324,6 @@ int re_initLibG15() +- return -1; ++ ++ shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; ++ g15_interface_id = found_devicetype = -1; ++ pthread_mutex_unlock(&libusb_mutex); ++ ++ return retval; + } + + int re_initLibG15() { closeKeyboardDevice(); @@ -457,29 +536,54 @@ index ba1c94b..ba01ae0 100644 keyboard_device = findAndOpenG15(); if (!keyboard_device) return G15_ERROR_OPENING_USB_DEVICE; -@@ -330,10 +340,6 @@ int initLibG15() +@@ -323,31 +374,33 @@ int re_initLibG15() - g15_log(stderr,G15_LOG_INFO,"%s\n",PACKAGE_STRING); + int initLibG15() + { +- int retval = G15_NO_ERROR; +- retval = initLibUsb(); +- if (retval) +- return retval; ++ int retval = initLibUsb(); + +- g15_log(stderr,G15_LOG_INFO,"%s\n",PACKAGE_STRING); ++ if (retval) return retval; -#ifdef SUN_LIBUSB - g15_log(stderr,G15_LOG_INFO,"Using Sun libusb.\n"); -#endif -- - g15NumberOfConnectedDevices(); ++ g15_log(stderr, G15_LOG_INFO, "%s\n", PACKAGE_STRING); +- g15NumberOfConnectedDevices(); ++ if (libg15_debugging_enabled) g15NumberOfConnectedDevices(); + ++ pthread_mutex_init(&libusb_mutex, NULL); keyboard_device = findAndOpenG15(); -@@ -347,7 +353,9 @@ int initLibG15() +- if (!keyboard_device) ++ if (!keyboard_device) ++ { ++ pthread_mutex_destroy(&libusb_mutex); + return G15_ERROR_OPENING_USB_DEVICE; ++ } + +- pthread_mutex_init(&libusb_mutex, NULL); +- return retval; ++ return G15_NO_ERROR; + } + int exitLibG15() { ++ closeKeyboardDevice(); ++ if (libg15_libusb_context) libusb_exit(libg15_libusb_context); ++ libg15_libusb_context = NULL; ++ pthread_mutex_destroy(&libusb_mutex); - return closeKeyboardDevice(); -+ int ret = closeKeyboardDevice(); -+ libusb_exit(libg15_libusb_context); -+ libg15_libusb_context = NULL; ++ return G15_NO_ERROR; } static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data) -@@ -428,36 +436,6 @@ static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char con +@@ -428,36 +481,6 @@ static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char con } } @@ -516,7 +620,7 @@ index ba1c94b..ba01ae0 100644 int writePixmapToLCD(unsigned char const *data) { int ret = 0; -@@ -474,43 +452,27 @@ int writePixmapToLCD(unsigned char const *data) +@@ -474,43 +497,27 @@ int writePixmapToLCD(unsigned char const *data) /* the keyboard needs this magic byte */ lcd_buffer[0] = 0x03; @@ -546,9 +650,9 @@ index ba1c94b..ba01ae0 100644 + if (ret || transferred != G15_BUFFER_LEN) + { + if (!ret) { -+ g15_log(stderr,G15_LOG_INFO,"LCDPixmap write error: short write.\n"); ++ g15_log(stderr,G15_LOG_INFO,"LCDPixmap write error: short write\n"); + } else { -+ g15_log(stderr,G15_LOG_INFO,"LCDPixmap write error: %s.\n", libusb_strerror(ret)); ++ g15_log(stderr,G15_LOG_INFO,"LCDPixmap write error: %s\n", libusb_strerror(ret)); } -#ifndef LIBUSB_BLOCKS - pthread_mutex_unlock(&libusb_mutex); @@ -578,7 +682,7 @@ index ba1c94b..ba01ae0 100644 return 0; } -@@ -535,7 +497,9 @@ int setLCDContrast(unsigned int level) +@@ -535,7 +542,9 @@ int setLCDContrast(unsigned int level) usb_data[3] = 18; } pthread_mutex_lock(&libusb_mutex); @@ -589,7 +693,7 @@ index ba1c94b..ba01ae0 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -553,7 +517,9 @@ int setLEDs(unsigned int leds) +@@ -553,7 +562,9 @@ int setLEDs(unsigned int leds) return G15_ERROR_UNSUPPORTED; pthread_mutex_lock(&libusb_mutex); @@ -600,7 +704,7 @@ index ba1c94b..ba01ae0 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -578,7 +544,9 @@ int setLCDBrightness(unsigned int level) +@@ -578,7 +589,9 @@ int setLCDBrightness(unsigned int level) usb_data[2] = 0x00; } pthread_mutex_lock(&libusb_mutex); @@ -611,7 +715,7 @@ index ba1c94b..ba01ae0 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -604,7 +572,9 @@ int setKBBrightness(unsigned int level) +@@ -604,7 +617,9 @@ int setKBBrightness(unsigned int level) usb_data[2] = 0x0; } pthread_mutex_lock(&libusb_mutex); @@ -622,7 +726,7 @@ index ba1c94b..ba01ae0 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -619,7 +589,9 @@ int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b) +@@ -619,7 +634,9 @@ int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b) usb_data[3] = b; pthread_mutex_lock(&libusb_mutex); @@ -633,7 +737,7 @@ index ba1c94b..ba01ae0 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -1033,38 +1005,54 @@ static void processKeyEvent4Byte(unsigned int *pressed_keys, unsigned char *buff +@@ -1033,38 +1050,54 @@ static void processKeyEvent4Byte(unsigned int *pressed_keys, unsigned char *buff int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) { unsigned char buffer[G15_KEY_READ_LENGTH]; @@ -664,7 +768,7 @@ index ba1c94b..ba01ae0 100644 + pthread_mutex_unlock(&libusb_mutex); + //no break + default: -+ g15_log(stderr,G15_LOG_INFO,"USB error on keybaord read: %s.\n", libusb_strerror(ret)); ++ g15_log(stderr,G15_LOG_INFO,"USB error on keybaord read: %s\n", libusb_strerror(ret)); + return G15_ERROR_READING_USB_DEVICE; + } + @@ -706,7 +810,7 @@ index ba1c94b..ba01ae0 100644 + processKeyEvent9Byte(pressed_keys, buffer); + return G15_NO_ERROR; + default: -+ g15_log(stderr, G15_LOG_INFO,"USB error on keybaord read: unsupported packet size.\n"); ++ g15_log(stderr, G15_LOG_INFO,"USB error on keybaord read: unsupported packet size\n"); + return G15_ERROR_READING_USB_DEVICE; } } From 3e35fe10615855b557a3ad76b1a4b88a36710994 Mon Sep 17 00:00:00 2001 From: Alexander Ponyatykh Date: Mon, 18 Nov 2019 02:58:36 +0300 Subject: [PATCH 7/8] Use debhelper-compat instead of debian/compat --- debian/changelog | 3 ++- debian/compat | 1 - debian/control | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 debian/compat diff --git a/debian/changelog b/debian/changelog index a355542..6200419 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,8 +2,9 @@ libg15 (1.3.0~svn324-2) unstable; urgency=medium * Migrate from legacy libusb-0.1 to libusb-1.0 (closes: bug#810409, bug#611649). + * Use debhelper-compat instead of debian/compat. - -- Alexander Ponyatykh Mon, 18 Nov 2019 02:44:19 +0300 + -- Alexander Ponyatykh Mon, 18 Nov 2019 02:57:48 +0300 libg15 (1.3.0~svn324-1) unstable; urgency=medium diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 48082f7..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -12 diff --git a/debian/control b/debian/control index ff00fd0..b648422 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: libg15 Section: libs Priority: optional Maintainer: Alexander Ponyatykh -Build-Depends: debhelper (>=12), libusb-1.0-0-dev (>=2:1.0.22) +Build-Depends: debhelper-compat (=12), libusb-1.0-0-dev (>=2:1.0.22) Standards-Version: 4.4.1 Homepage: https://sourceforge.net/projects/g15tools/ Vcs-Git: https://salsa.debian.org/debian/libg15.git From 02ea3752d090e08c087f2858c49991f522a8a3d9 Mon Sep 17 00:00:00 2001 From: Alexander Ponyatykh Date: Tue, 19 Nov 2019 00:33:42 +0300 Subject: [PATCH 8/8] Remove 00-fix-reinit.patch Initialization and deinitialization functions were rewritten as part of switch to libusb 1.0 path. There is no point in keeping a separate patch that changes them slightly. --- debian/changelog | 7 +- debian/patches/00-fix-reinit.patch | 94 ------------- debian/patches/01-fix-spelling.path | 4 +- ....0.patch => 02-switch-to-libusb-1.0.patch} | 124 +++++++++--------- debian/patches/series | 1 - 5 files changed, 70 insertions(+), 160 deletions(-) delete mode 100644 debian/patches/00-fix-reinit.patch rename debian/patches/{02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch => 02-switch-to-libusb-1.0.patch} (95%) diff --git a/debian/changelog b/debian/changelog index 6200419..2ac0d11 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,11 @@ libg15 (1.3.0~svn324-2) unstable; urgency=medium - * Migrate from legacy libusb-0.1 to libusb-1.0 (closes: bug#810409, - bug#611649). + * Switch from legacy libusb 0.1 to libusb 1.0 (closes: bug#810409, + bug#611649, LP: #1357556). + * Remove 00-fix-reinit.patch obsoleted by 02-switch-to-libusb-1.0.patch. * Use debhelper-compat instead of debian/compat. - -- Alexander Ponyatykh Mon, 18 Nov 2019 02:57:48 +0300 + -- Alexander Ponyatykh Tue, 19 Nov 2019 00:32:46 +0300 libg15 (1.3.0~svn324-1) unstable; urgency=medium diff --git a/debian/patches/00-fix-reinit.patch b/debian/patches/00-fix-reinit.patch deleted file mode 100644 index 09721f8..0000000 --- a/debian/patches/00-fix-reinit.patch +++ /dev/null @@ -1,94 +0,0 @@ -From: Alexander Ponyatykh -Date: Fri, 15 Nov 2019 02:19:01 +0300 -Subject: fix re_initLibG15() to properly reset internal state. - -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libusb/+bug/1357556 -Forwarded: no -Last-Update: 2015-05-17 - -=================================================================== ---- - libg15.c | 55 ++++++++++++++++++++++++++++--------------------------- - 1 file changed, 28 insertions(+), 27 deletions(-) - -diff --git a/libg15.c b/libg15.c -index 31b2bd6..369ed40 100644 ---- a/libg15.c -+++ b/libg15.c -@@ -283,19 +283,36 @@ static usb_dev_handle * findAndOpenG15() { - return keyboard_device; - } - -- --int re_initLibG15() -+/* reset the keyboard, returning it to a known state */ -+static int closeKeyboardDevice() - { -+ int retval = G15_NO_ERROR; - -- usb_init(); -+ enospc_slowdown = shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; -+ found_devicetype = -1; - -- /** -- * usb_find_busses and usb_find_devices both report the number of devices -- * / busses added / removed since the last call. since this is the first -- * call we have to return values != 0 or else we didnt find anything */ -+ if (keyboard_device){ -+#ifndef SUN_LIBUSB -+ retval = usb_release_interface (keyboard_device, 0); -+ usleep(50*1000); -+#endif -+#if 0 -+ retval = usb_reset(keyboard_device); -+ usleep(50*1000); -+#endif -+ usb_close(keyboard_device); -+ keyboard_device=0; -+ return retval; -+ } -+ return -1; -+} - -- if (!usb_find_devices()) -- return G15_ERROR_OPENING_USB_DEVICE; -+int re_initLibG15() -+{ -+ closeKeyboardDevice(); -+ -+ usb_find_busses(); -+ usb_find_devices(); - - keyboard_device = findAndOpenG15(); - if (!keyboard_device) -@@ -327,28 +344,12 @@ int initLibG15() - return retval; - } - --/* reset the keyboard, returning it to a known state */ - int exitLibG15() - { -- int retval = G15_NO_ERROR; -- if (keyboard_device){ --#ifndef SUN_LIBUSB -- retval = usb_release_interface (keyboard_device, 0); -- usleep(50*1000); --#endif --#if 0 -- retval = usb_reset(keyboard_device); -- usleep(50*1000); --#endif -- usb_close(keyboard_device); -- keyboard_device=0; -- pthread_mutex_destroy(&libusb_mutex); -- return retval; -- } -- return -1; -+ pthread_mutex_destroy(&libusb_mutex); -+ return closeKeyboardDevice(); - } - -- - static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data) - { - /* diff --git a/debian/patches/01-fix-spelling.path b/debian/patches/01-fix-spelling.path index abe4ae9..4d07d10 100644 --- a/debian/patches/01-fix-spelling.path +++ b/debian/patches/01-fix-spelling.path @@ -7,7 +7,7 @@ Subject: fix spelling error 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libg15.c b/libg15.c -index 369ed40..ba1c94b 100644 +index 31b2bd6..56df958 100644 --- a/libg15.c +++ b/libg15.c @@ -152,7 +152,7 @@ static usb_dev_handle * findAndOpenDevice(libg15_devices_t handled_device, int d @@ -19,7 +19,7 @@ index 369ed40..ba1c94b 100644 return 0; } -@@ -434,7 +434,7 @@ int handle_usb_errors(const char *prefix, int ret) { +@@ -433,7 +433,7 @@ int handle_usb_errors(const char *prefix, int ret) { case -ETIMEDOUT: return G15_ERROR_READING_USB_DEVICE; /* backward-compatibility */ break; diff --git a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch b/debian/patches/02-switch-to-libusb-1.0.patch similarity index 95% rename from debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch rename to debian/patches/02-switch-to-libusb-1.0.patch index b5a21b1..bc560e8 100644 --- a/debian/patches/02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch +++ b/debian/patches/02-switch-to-libusb-1.0.patch @@ -4,8 +4,8 @@ Subject: Migrate from legacy libusb-0.1 to libusb-1.0 --- configure.in | 5 +- - libg15.c | 615 +++++++++++++++++++++++++++++++---------------------------- - 2 files changed, 327 insertions(+), 293 deletions(-) + libg15.c | 624 +++++++++++++++++++++++++++++++---------------------------- + 2 files changed, 332 insertions(+), 297 deletions(-) diff --git a/configure.in b/configure.in index 074d98e..b533d2c 100644 @@ -31,7 +31,7 @@ index 074d98e..b533d2c 100644 # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/libg15.c b/libg15.c -index ba1c94b..4c0afc4 100644 +index 56df958..4c0afc4 100644 --- a/libg15.c +++ b/libg15.c @@ -24,20 +24,22 @@ @@ -71,7 +71,7 @@ index ba1c94b..4c0afc4 100644 } /* debugging wrapper */ -@@ -86,234 +90,281 @@ static int g15_log (FILE *fd, unsigned int level, const char *fmt, ...) { +@@ -86,216 +90,280 @@ static int g15_log (FILE *fd, unsigned int level, const char *fmt, ...) { /* return number of connected and supported devices */ int g15NumberOfConnectedDevices() { @@ -87,14 +87,14 @@ index ba1c94b..4c0afc4 100644 + ssize_t cnt = libusb_get_device_list(libg15_libusb_context, &list); + + if (cnt < 0) -+ { + { +- for (dev = bus->devices; dev; dev = dev->next) + g15_log(stderr, G15_LOG_INFO, "Unable to list USB devices: %s\n", libusb_strerror(cnt)); + return 0; + } + + for (ssize_t i = 0; i < cnt; i++) - { -- for (dev = bus->devices; dev; dev = dev->next) ++ { + libusb_get_device_descriptor(list[i], &desc); + + for (int j = 0; g15_devices[i].name != NULL; j++) @@ -115,13 +115,13 @@ index ba1c94b..4c0afc4 100644 static int initLibUsb() { - usb_init(); -+ int errcode = libusb_init(&libg15_libusb_context); - +- - /** - * usb_find_busses and usb_find_devices both report the number of devices - * / busses added / removed since the last call. since this is the first - * call we have to return values != 0 or else we didnt find anything */ -- ++ int errcode = libusb_init(&libg15_libusb_context); + - if (!usb_find_busses()) + if (errcode != 0) + { @@ -414,8 +414,7 @@ index ba1c94b..4c0afc4 100644 + { + g15_keys_endpoint = ep->bEndpointAddress; + } - else -- g15_log(stderr,G15_LOG_INFO,"%s not found\n",g15_devices[i].name); ++ else + { + g15_lcd_endpoint = ep->bEndpointAddress; + } @@ -430,7 +429,8 @@ index ba1c94b..4c0afc4 100644 + { + g15_log(stderr,G15_LOG_INFO,"Success, detached the driver\n"); + } -+ else + else +- g15_log(stderr,G15_LOG_INFO,"%s not found\n",g15_devices[i].name); + { + g15_log(stderr,G15_LOG_INFO,"Could not detach the driver, giving up: %s\n", libusb_strerror(ret)); + goto error; @@ -486,29 +486,14 @@ index ba1c94b..4c0afc4 100644 + return 0; } -+ - /* reset the keyboard, returning it to a known state */ - static int closeKeyboardDevice() + +-int re_initLibG15() ++/* reset the keyboard, returning it to a known state */ ++static int closeKeyboardDevice() { -- int retval = G15_NO_ERROR; -- -- enospc_slowdown = shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; -- found_devicetype = -1; -- -- if (keyboard_device){ --#ifndef SUN_LIBUSB -- retval = usb_release_interface (keyboard_device, 0); -- usleep(50*1000); --#endif --#if 0 -- retval = usb_reset(keyboard_device); -- usleep(50*1000); --#endif -- usb_close(keyboard_device); -- keyboard_device=0; -- return retval; + int retval = G15_ERROR_OPENING_USB_DEVICE; -+ + +- usb_init(); + pthread_mutex_lock(&libusb_mutex); + if (keyboard_device) { + retval = libusb_release_interface(keyboard_device, 0); @@ -516,27 +501,28 @@ index ba1c94b..4c0afc4 100644 + libusb_close(keyboard_device); + keyboard_device = NULL; + retval = G15_NO_ERROR; - } -- return -1; -+ ++ } + +- /** +- * usb_find_busses and usb_find_devices both report the number of devices +- * / busses added / removed since the last call. since this is the first +- * call we have to return values != 0 or else we didnt find anything */ + shared_device = g15_keys_endpoint = g15_lcd_endpoint = 0; + g15_interface_id = found_devicetype = -1; + pthread_mutex_unlock(&libusb_mutex); -+ + +- if (!usb_find_devices()) +- return G15_ERROR_OPENING_USB_DEVICE; + return retval; - } ++} ++ ++int re_initLibG15() ++{ ++ closeKeyboardDevice(); - int re_initLibG15() - { - closeKeyboardDevice(); - -- usb_find_busses(); -- usb_find_devices(); -- keyboard_device = findAndOpenG15(); if (!keyboard_device) - return G15_ERROR_OPENING_USB_DEVICE; -@@ -323,31 +374,33 @@ int re_initLibG15() +@@ -306,48 +374,34 @@ int re_initLibG15() int initLibG15() { @@ -571,19 +557,37 @@ index ba1c94b..4c0afc4 100644 + return G15_NO_ERROR; } +-/* reset the keyboard, returning it to a known state */ int exitLibG15() { +- int retval = G15_NO_ERROR; +- if (keyboard_device){ +-#ifndef SUN_LIBUSB +- retval = usb_release_interface (keyboard_device, 0); +- usleep(50*1000); +-#endif +-#if 0 +- retval = usb_reset(keyboard_device); +- usleep(50*1000); +-#endif +- usb_close(keyboard_device); +- keyboard_device=0; +- pthread_mutex_destroy(&libusb_mutex); +- return retval; +- } +- return -1; +-} + closeKeyboardDevice(); + if (libg15_libusb_context) libusb_exit(libg15_libusb_context); + libg15_libusb_context = NULL; -+ - pthread_mutex_destroy(&libusb_mutex); -- return closeKeyboardDevice(); + ++ pthread_mutex_destroy(&libusb_mutex); + return G15_NO_ERROR; - } ++} static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data) -@@ -428,36 +481,6 @@ static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char con + { +@@ -427,36 +481,6 @@ static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char con } } @@ -620,7 +624,7 @@ index ba1c94b..4c0afc4 100644 int writePixmapToLCD(unsigned char const *data) { int ret = 0; -@@ -474,43 +497,27 @@ int writePixmapToLCD(unsigned char const *data) +@@ -473,43 +497,27 @@ int writePixmapToLCD(unsigned char const *data) /* the keyboard needs this magic byte */ lcd_buffer[0] = 0x03; @@ -682,7 +686,7 @@ index ba1c94b..4c0afc4 100644 return 0; } -@@ -535,7 +542,9 @@ int setLCDContrast(unsigned int level) +@@ -534,7 +542,9 @@ int setLCDContrast(unsigned int level) usb_data[3] = 18; } pthread_mutex_lock(&libusb_mutex); @@ -693,7 +697,7 @@ index ba1c94b..4c0afc4 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -553,7 +562,9 @@ int setLEDs(unsigned int leds) +@@ -552,7 +562,9 @@ int setLEDs(unsigned int leds) return G15_ERROR_UNSUPPORTED; pthread_mutex_lock(&libusb_mutex); @@ -704,7 +708,7 @@ index ba1c94b..4c0afc4 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -578,7 +589,9 @@ int setLCDBrightness(unsigned int level) +@@ -577,7 +589,9 @@ int setLCDBrightness(unsigned int level) usb_data[2] = 0x00; } pthread_mutex_lock(&libusb_mutex); @@ -715,7 +719,7 @@ index ba1c94b..4c0afc4 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -604,7 +617,9 @@ int setKBBrightness(unsigned int level) +@@ -603,7 +617,9 @@ int setKBBrightness(unsigned int level) usb_data[2] = 0x0; } pthread_mutex_lock(&libusb_mutex); @@ -726,7 +730,7 @@ index ba1c94b..4c0afc4 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -619,7 +634,9 @@ int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b) +@@ -618,7 +634,9 @@ int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b) usb_data[3] = b; pthread_mutex_lock(&libusb_mutex); @@ -737,7 +741,7 @@ index ba1c94b..4c0afc4 100644 pthread_mutex_unlock(&libusb_mutex); return retval; } -@@ -1033,38 +1050,54 @@ static void processKeyEvent4Byte(unsigned int *pressed_keys, unsigned char *buff +@@ -1032,38 +1050,54 @@ static void processKeyEvent4Byte(unsigned int *pressed_keys, unsigned char *buff int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout) { unsigned char buffer[G15_KEY_READ_LENGTH]; diff --git a/debian/patches/series b/debian/patches/series index 3c0b3b6..d89bfe4 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,2 @@ -00-fix-reinit.patch 01-fix-spelling.path 02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch