Merge the USB backend rework branch into debian/master

This commit is contained in:
Andrej Shadura committed 2019-12-05 14:23:46 +00:00
commit 8ddb076537
7 files changed
+845 -92

No files matched your search

+9
View File
@@ -1,3 +1,12 @@
libg15 (1.3.0~svn324-2) unstable; urgency=medium
* 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 <lazyranma@gmail.com> Tue, 19 Nov 2019 00:32:46 +0300
libg15 (1.3.0~svn324-1) unstable; urgency=medium
* New upstream version 1.3.0~svn324.
-1
View File
@@ -1 +0,0 @@
12
+2 -2
View File
@@ -2,7 +2,7 @@ Source: libg15
Section: libs
Priority: optional
Maintainer: Alexander Ponyatykh <lazyranma@gmail.com>
Build-Depends: debhelper (>=12), libusb-dev
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
@@ -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)
-85
View File
@@ -1,85 +0,0 @@
Description: fix re_initLibG15() to properly reset internal state.
Author: Alexander Ponyatykh <lazyranma@gmail.com>
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libusb/+bug/1357556
Forwarded: no
Last-Update: 2015-05-17
===================================================================
--- a/libg15.c
+++ b/libg15.c
@@ -283,19 +283,36 @@
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 @@
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)
{
/*
@@ -1,6 +1,16 @@
From: Alexander Ponyatykh <lazyranma@gmail.com>
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 31b2bd6..56df958 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 @@
@@ -433,7 +433,7 @@ int handle_usb_errors(const char *prefix, int ret) {
case -ETIMEDOUT:
return G15_ERROR_READING_USB_DEVICE; /* backward-compatibility */
break;
+820
View File
@@ -0,0 +1,820 @@
From: Alexander Ponyatykh <lazyranma@gmail.com>
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 | 624 +++++++++++++++++++++++++++++++----------------------------
2 files changed, 332 insertions(+), 297 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
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 @@ fi
# 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
diff --git a/libg15.c b/libg15.c
index 56df958..4c0afc4 100644
--- a/libg15.c
+++ b/libg15.c
@@ -24,20 +24,22 @@
#include "libg15.h"
#include <stdio.h>
#include <stdarg.h>
-#include <usb.h>
+#include <libusb-1.0/libusb.h>
#include <string.h>
#include <errno.h>
+#include <unistd.h>
#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;
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 +69,9 @@ int g15DeviceCapabilities() {
void libg15Debug(int option) {
libg15_debugging_enabled = option;
- usb_set_debug(option);
+ if (option && libg15_libusb_context) {
+ libusb_set_option(libg15_libusb_context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_WARNING);
+ }
}
/* debugging wrapper */
@@ -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() {
- 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(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++)
+ {
+ 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(&libg15_libusb_context);
- if (!usb_find_busses())
+ if (errcode != 0)
+ {
+ g15_log(stderr, G15_LOG_INFO, "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;
+ libg15Debug(libg15_debugging_enabled);
return G15_NO_ERROR;
}
-static usb_dev_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_config_descriptor *cfg = NULL;
+ libusb_device_handle *devh = 0;
+ libusb_device *dev = NULL;
+ libusb_device **list = 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);
+
+ if (cnt < 0)
+ {
+ 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 && found_dev == -1; devno++)
{
- for (dev = bus->devices; dev; dev = dev->next)
- {
- 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;
- 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;
- }
-
- usleep(50*1000);
-
- g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.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 (j = 0; j<dev->descriptor.bNumConfigurations;j++){
- struct usb_config_descriptor *cfg = &dev->config[j];
-
- for (i=0;i<cfg->bNumInterfaces; i++){
- if (g15DeviceCapabilities()&G15_DEVICE_G510){
- if (i==G510_STANDARD_KEYBOARD_INTERFACE) continue;
- }
-
- 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;k<ifp->num_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");
- }
- }
- }
- }
- }
-
-
- g15_log(stderr,G15_LOG_INFO,"Done opening the keyboard\n");
- usleep(500*1000); // sleep a bit for good measure
- return devh;
+ 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" : "");
}
}
}
- 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() {
- 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_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,"%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;
+ }
+ }
+
+ 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;
+ g15_interface_id = found_devicetype = -1;
+ pthread_mutex_unlock(&libusb_mutex);
+
+ return 0;
}
-int re_initLibG15()
+/* reset the keyboard, returning it to a known state */
+static int closeKeyboardDevice()
{
+ int retval = G15_ERROR_OPENING_USB_DEVICE;
- usb_init();
+ 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 = NULL;
+ retval = G15_NO_ERROR;
+ }
- /**
- * 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();
keyboard_device = findAndOpenG15();
if (!keyboard_device)
@@ -306,48 +374,34 @@ int re_initLibG15()
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
+ 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();
- 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;
}
-/* 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 G15_NO_ERROR;
+}
static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data)
{
@@ -427,36 +481,6 @@ static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char con
}
}
-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;
@@ -473,43 +497,27 @@ int writePixmapToLCD(unsigned char const *data)
/* 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;
}
@@ -534,7 +542,9 @@ int setLCDContrast(unsigned int level)
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;
}
@@ -552,7 +562,9 @@ int setLEDs(unsigned int leds)
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;
}
@@ -577,7 +589,9 @@ int setLCDBrightness(unsigned int level)
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;
}
@@ -603,7 +617,9 @@ int setKBBrightness(unsigned int level)
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;
}
@@ -618,7 +634,9 @@ int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b)
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;
}
@@ -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];
+ 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));
+ return G15_ERROR_READING_USB_DEVICE;
+ }
+
+ if (transferred > 0 && buffer[0] == 1) {
return G15_ERROR_TRY_AGAIN;
}
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) {
- 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 */
+ 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;
}
}
+2 -2
View File
@@ -1,2 +1,2 @@
00-fix-reinit.patch
01-fix-spelling-error
01-fix-spelling.path
02-Migrate-from-legacy-libusb-0.1-to-libusb-1.0.patch