summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libusb/io.c3
-rw-r--r--libusb/libusbi.h5
-rw-r--r--libusb/os/linux_usbfs.c309
-rw-r--r--libusb/os/linux_usbfs.h4
-rw-r--r--libusb/os/sunos_usb.c10
-rw-r--r--libusb/version_nano.h2
6 files changed, 90 insertions, 243 deletions
diff --git a/libusb/io.c b/libusb/io.c
index 883c4e1..af322ed 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1138,8 +1138,7 @@ int usbi_io_init(struct libusb_context *ctx)
goto err_close_pipe;
#ifdef HAVE_TIMERFD
- ctx->timerfd = timerfd_create(usbi_backend.get_timerfd_clockid(),
- TFD_NONBLOCK | TFD_CLOEXEC);
+ ctx->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
if (ctx->timerfd >= 0) {
usbi_dbg("using timerfd for timeouts");
r = usbi_add_pollfd(ctx, ctx->timerfd, POLLIN);
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index 6cc6f92..2ce448a 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -1157,11 +1157,6 @@ struct usbi_os_backend {
*/
int (*clock_gettime)(int clkid, struct timespec *tp);
-#ifdef HAVE_TIMERFD
- /* clock ID of the clock that should be used for timerfd */
- clockid_t (*get_timerfd_clockid)(void);
-#endif
-
/* Number of bytes to reserve for per-context private backend data.
* This private data area is accessible through the "os_priv" field of
* struct libusb_context. */
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 58d5f6c..b997b46 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -5,6 +5,7 @@
* Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
* Copyright © 2013 Nathan Hjelm <hjelmn@mac.com>
* Copyright © 2012-2013 Hans de Goede <hdegoede@redhat.com>
+ * Copyright © 2020 Chris Dickens <christopher.a.dickens@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,27 +22,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <config.h>
+#include "libusbi.h"
+#include "linux_usbfs.h"
#include <alloca.h>
-#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#include <poll.h>
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
#include <sys/utsname.h>
-#include <time.h>
-
-#include "libusbi.h"
-#include "linux_usbfs.h"
+#include <sys/vfs.h>
/* sysfs vs usbfs:
* opening a usbfs node causes the device to be resumed, so we attempt to
@@ -88,50 +82,14 @@ static int usbdev_names = 0;
* (commit 3612242e527eb47ee4756b5350f8bdf791aa5ede) increased this value to
* 8,192 bytes to support higher bandwidth devices. Linux 3.10
* (commit e2e2f0ea1c935edcf53feb4c4c8fdb4f86d57dd9) further increased this
- * value to 49,152 bytes to support super speed devices.
+ * value to 49,152 bytes to support super speed devices. Linux 5.2
+ * (commit 8a1dbc8d91d3d1602282c7e6b4222c7759c916fa) even further increased
+ * this value to 98,304 bytes to support super speed plus devices.
*/
static unsigned int max_iso_packet_len = 0;
-/* Linux 2.6.23 adds support for O_CLOEXEC when opening files, which marks the
- * close-on-exec flag in the underlying file descriptor. */
-static int supports_flag_cloexec = -1;
-
-/* Linux 2.6.32 adds support for a bulk continuation URB flag. this basically
- * allows us to mark URBs as being part of a specific logical transfer when
- * we submit them to the kernel. then, on any error except a cancellation, all
- * URBs within that transfer will be cancelled and no more URBs will be
- * accepted for the transfer, meaning that no more data can creep in.
- *
- * The BULK_CONTINUATION flag must be set on all URBs within a bulk transfer
- * (in either direction) except the first.
- * For IN transfers, we must also set SHORT_NOT_OK on all URBs except the
- * last; it means that the kernel should treat a short reply as an error.
- * For OUT transfers, SHORT_NOT_OK must not be set. it isn't needed (OUT
- * transfers can't be short unless there's already some sort of error), and
- * setting this flag is disallowed (a kernel with USB debugging enabled will
- * reject such URBs).
- */
-static int supports_flag_bulk_continuation = -1;
-
-/* Linux 2.6.31 fixes support for the zero length packet URB flag. This
- * allows us to mark URBs that should be followed by a zero length data
- * packet, which can be required by device- or class-specific protocols.
- */
-static int supports_flag_zero_packet = -1;
-
-/* clock ID for monotonic clock, as not all clock sources are available on all
- * systems. appropriate choice made at initialization time. */
-static clockid_t monotonic_clkid = -1;
-
-/* Linux 2.6.22 (commit 83f7d958eab2fbc6b159ee92bf1493924e1d0f72) adds a busnum
- * to sysfs, so we can relate devices. This also implies that we can read
- * the active configuration through bConfigurationValue */
-static int sysfs_can_relate_devices = -1;
-
-/* Linux 2.6.26 (commit 217a9081d8e69026186067711131b77f0ce219ed) adds all
- * config descriptors (rather then just the active config) to the sysfs
- * descriptors file, so from then on we can use them. */
-static int sysfs_has_descriptors = -1;
+/* is sysfs available (mounted) ? */
+static int sysfs_available = -1;
/* how many times have we initted (and not exited) ? */
static int init_count = 0;
@@ -158,7 +116,7 @@ struct linux_device_priv {
char *sysfs_dir;
unsigned char *descriptors;
int descriptors_len;
- int active_config; /* cache val for !sysfs_can_relate_devices */
+ int active_config; /* cache val for !sysfs_available */
};
struct linux_device_handle_priv {
@@ -199,16 +157,6 @@ struct linux_transfer_priv {
int iso_packet_offset;
};
-static int __open(const char *path, int flags)
-{
-#if defined(O_CLOEXEC)
- if (supports_flag_cloexec)
- return open(path, flags | O_CLOEXEC);
- else
-#endif
- return open(path, flags);
-}
-
static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
{
struct libusb_context *ctx = DEVICE_CTX(dev);
@@ -222,7 +170,7 @@ static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
sprintf(path, USB_DEVTMPFS_PATH "/%03u/%03u",
dev->bus_number, dev->device_address);
- fd = __open(path, mode);
+ fd = open(path, mode | O_CLOEXEC);
if (fd != -1)
return fd; /* Success */
@@ -236,7 +184,7 @@ static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
/* Wait 10ms for USB device path creation.*/
nanosleep(&delay_ts, NULL);
- fd = __open(path, mode);
+ fd = open(path, mode | O_CLOEXEC);
if (fd != -1)
return fd; /* Success */
}
@@ -267,7 +215,7 @@ static struct linux_device_handle_priv *_device_handle_priv(
/* check dirent for a /dev/usbdev%d.%d name
* optionally return bus/device on success */
-static int _is_usbdev_entry(const char *name, uint8_t *bus_p, uint8_t *dev_p)
+static int is_usbdev_entry(const char *name, uint8_t *bus_p, uint8_t *dev_p)
{
int busnum, devnum;
@@ -286,59 +234,48 @@ static int _is_usbdev_entry(const char *name, uint8_t *bus_p, uint8_t *dev_p)
return 1;
}
-static int check_usb_vfs(const char *dirname)
+static const char *find_usbfs_path(void)
{
+ const char *path;
DIR *dir;
struct dirent *entry;
- int found = 0;
- dir = opendir(dirname);
- if (!dir)
- return 0;
+ path = USB_DEVTMPFS_PATH;
+ dir = opendir(path);
+ if (dir) {
+ while ((entry = readdir(dir))) {
+ if (entry->d_name[0] == '.')
+ continue;
- while ((entry = readdir(dir))) {
- if (entry->d_name[0] == '.')
- continue;
+ /* We assume if we find any files that it must be the right place */
+ break;
+ }
- /* We assume if we find any files that it must be the right place */
- found = 1;
- break;
- }
+ closedir(dir);
- closedir(dir);
- return found;
-}
+ if (entry)
+ return path;
+ }
-static const char *find_usbfs_path(void)
-{
- const char *path = "/dev/bus/usb";
- const char *ret = NULL;
+ /* look for /dev/usbdev*.* if the normal place fails */
+ path = USBDEV_PATH;
+ dir = opendir(path);
+ if (dir) {
+ while ((entry = readdir(dir))) {
+ if (entry->d_name[0] == '.')
+ continue;
- if (check_usb_vfs(path)) {
- ret = path;
- } else {
- path = "/proc/bus/usb";
- if (check_usb_vfs(path))
- ret = path;
- }
-
- /* look for /dev/usbdev*.* if the normal places fail */
- if (!ret) {
- struct dirent *entry;
- DIR *dir;
-
- path = "/dev";
- dir = opendir(path);
- if (dir) {
- while ((entry = readdir(dir))) {
- if (_is_usbdev_entry(entry->d_name, NULL, NULL)) {
- /* found one; that's enough */
- ret = path;
- usbdev_names = 1;
- break;
- }
+ if (is_usbdev_entry(entry->d_name, NULL, NULL)) {
+ /* found one; that's enough */
+ break;
}
- closedir(dir);
+ }
+
+ closedir(dir);
+
+ if (entry) {
+ usbdev_names = 1;
+ return path;
}
}
@@ -348,33 +285,10 @@ static const char *find_usbfs_path(void)
* Make the same assumption for Android where SELinux policies might block us
* from reading /dev on newer devices. */
#if defined(HAVE_LIBUDEV) || defined(__ANDROID__)
- if (!ret)
- ret = "/dev/bus/usb";
-#endif
-
- if (ret)
- usbi_dbg("found usbfs at %s", ret);
-
- return ret;
-}
-
-/* the monotonic clock is not usable on all systems (e.g. embedded ones often
- * seem to lack it). fall back to REALTIME if we have to. */
-static clockid_t find_monotonic_clock(void)
-{
-#ifdef CLOCK_MONOTONIC
- struct timespec ts;
- int r;
-
- /* Linux 2.6.28 adds CLOCK_MONOTONIC_RAW but we don't use it
- * because it's not available through timerfd */
- r = clock_gettime(CLOCK_MONOTONIC, &ts);
- if (r == 0)
- return CLOCK_MONOTONIC;
- usbi_dbg("monotonic clock doesn't work, errno=%d", errno);
+ return USB_DEVTMPFS_PATH;
+#else
+ return NULL;
#endif
-
- return CLOCK_REALTIME;
}
static int get_kernel_version(struct libusb_context *ctx,
@@ -426,77 +340,51 @@ static int kernel_version_ge(const struct kernel_version *ver,
static int op_init(struct libusb_context *ctx)
{
struct kernel_version kversion;
- struct stat statbuf;
+ const char *usbfs_path;
int r;
- if (!find_usbfs_path()) {
- usbi_err(ctx, "could not find usbfs");
- return LIBUSB_ERROR_OTHER;
- }
-
- if (monotonic_clkid == -1)
- monotonic_clkid = find_monotonic_clock();
-
if (get_kernel_version(ctx, &kversion) < 0)
return LIBUSB_ERROR_OTHER;
- if (supports_flag_cloexec == -1) {
- /* O_CLOEXEC flag available from Linux 2.6.23 */
- supports_flag_cloexec = kernel_version_ge(&kversion, 2, 6, 23);
- }
-
- if (supports_flag_bulk_continuation == -1) {
- /* bulk continuation URB flag available from Linux 2.6.32 */
- supports_flag_bulk_continuation = kernel_version_ge(&kversion,2,6,32);
+ if (!kernel_version_ge(&kversion, 2, 6, 32)) {
+ usbi_err(ctx, "kernel version is too old (reported as %d.%d.%d)",
+ kversion.major, kversion.minor,
+ kversion.sublevel != -1 ? kversion.sublevel : 0);
+ return LIBUSB_ERROR_NOT_SUPPORTED;
}
- if (supports_flag_bulk_continuation)
- usbi_dbg("bulk continuation flag supported");
-
- if (supports_flag_zero_packet == -1) {
- /* zero length packet URB flag fixed since Linux 2.6.31 */
- supports_flag_zero_packet = kernel_version_ge(&kversion, 2, 6, 31);
+ usbfs_path = find_usbfs_path();
+ if (!usbfs_path) {
+ usbi_err(ctx, "could not find usbfs");
+ return LIBUSB_ERROR_OTHER;
}
- if (supports_flag_zero_packet)
- usbi_dbg("zero length packet flag supported");
+ usbi_dbg("found usbfs at %s", usbfs_path);
if (!max_iso_packet_len) {
- if (kernel_version_ge(&kversion, 3, 10, 0))
+ if (kernel_version_ge(&kversion, 5, 2, 0))
+ max_iso_packet_len = 98304;
+ else if (kernel_version_ge(&kversion, 3, 10, 0))
max_iso_packet_len = 49152;
- else if (kernel_version_ge(&kversion, 2, 6, 18))
- max_iso_packet_len = 8192;
else
- max_iso_packet_len = 1023;
+ max_iso_packet_len = 8192;
}
usbi_dbg("max iso packet length is (likely) %u bytes", max_iso_packet_len);
- if (sysfs_has_descriptors == -1) {
- /* sysfs descriptors has all descriptors since Linux 2.6.26 */
- sysfs_has_descriptors = kernel_version_ge(&kversion, 2, 6, 26);
- }
-
- if (sysfs_can_relate_devices == -1) {
- /* sysfs has busnum since Linux 2.6.22 */
- sysfs_can_relate_devices = kernel_version_ge(&kversion, 2, 6, 22);
- }
+ if (sysfs_available == -1) {
+ struct statfs statfsbuf;
- if (sysfs_can_relate_devices || sysfs_has_descriptors) {
- r = stat(SYSFS_DEVICE_PATH, &statbuf);
- if (r < 0 || !S_ISDIR(statbuf.st_mode)) {
+ r = statfs(SYSFS_MOUNT_PATH, &statfsbuf);
+ if (r == 0 && statfsbuf.f_type == SYSFS_MAGIC) {
+ usbi_dbg("sysfs is available");
+ sysfs_available = 1;
+ } else {
usbi_warn(ctx, "sysfs not mounted");
- sysfs_can_relate_devices = 0;
- sysfs_has_descriptors = 0;
+ sysfs_available = 0;
}
}
- if (sysfs_can_relate_devices)
- usbi_dbg("sysfs can relate devices");
-
- if (sysfs_has_descriptors)
- usbi_dbg("sysfs has complete descriptors");
-
usbi_mutex_static_lock(&linux_hotplug_startstop_lock);
r = LIBUSB_SUCCESS;
if (init_count == 0) {
@@ -558,7 +446,7 @@ static int open_sysfs_attr(struct libusb_context *ctx,
int fd;
snprintf(filename, sizeof(filename), SYSFS_DEVICE_PATH "/%s/%s", sysfs_dir, attr);
- fd = __open(filename, O_RDONLY);
+ fd = open(filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
if (errno == ENOENT) {
/* File doesn't exist. Assume the device has been
@@ -644,7 +532,7 @@ static int op_get_device_descriptor(struct libusb_device *dev,
{
struct linux_device_priv *priv = _device_priv(dev);
- *host_endian = (priv->sysfs_dir && sysfs_has_descriptors) ? 0 : 1;
+ *host_endian = priv->sysfs_dir != NULL;
memcpy(buffer, priv->descriptors, DEVICE_DESC_LENGTH);
return 0;
@@ -689,7 +577,7 @@ int linux_get_device_address(struct libusb_context *ctx, int detached,
usbi_dbg("getting address for device: %s detached: %d", sys_name, detached);
/* can't use sysfs to read the bus and device number if the
* device has been detached */
- if (!sysfs_can_relate_devices || detached || !sys_name) {
+ if (!sysfs_available || detached || !sys_name) {
if (!dev_node && fd >= 0) {
char *fd_path = alloca(PATH_MAX);
char proc_path[32];
@@ -709,8 +597,6 @@ int linux_get_device_address(struct libusb_context *ctx, int detached,
/* will this work with all supported kernel versions? */
if (!strncmp(dev_node, "/dev/bus/usb", 12))
sscanf(dev_node, "/dev/bus/usb/%hhu/%hhu", busnum, devaddr);
- else if (!strncmp(dev_node, "/proc/bus/usb", 13))
- sscanf(dev_node, "/proc/bus/usb/%hhu/%hhu", busnum, devaddr);
else
return LIBUSB_ERROR_OTHER;
@@ -790,7 +676,7 @@ static int seek_to_next_config(struct libusb_device *dev,
* config descriptor with verified bLength fields, with descriptors
* with an invalid bLength removed.
*/
- if (priv->sysfs_dir && sysfs_has_descriptors) {
+ if (priv->sysfs_dir) {
int next = seek_to_next_descriptor(ctx, LIBUSB_DT_CONFIG, buffer, size);
if (next == LIBUSB_ERROR_NOT_FOUND)
@@ -855,7 +741,7 @@ static int op_get_active_config_descriptor(struct libusb_device *dev,
int r, config;
unsigned char *config_desc;
- if (priv->sysfs_dir && sysfs_can_relate_devices) {
+ if (priv->sysfs_dir) {
r = sysfs_get_active_config(dev, &config);
if (r < 0)
return r;
@@ -981,7 +867,7 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
}
/* cache descriptors in memory */
- if (sysfs_dir && sysfs_has_descriptors) {
+ if (sysfs_dir) {
fd = open_sysfs_attr(ctx, sysfs_dir, "descriptors");
} else if (wrapped_fd < 0) {
fd = get_usbfs_fd(dev, O_RDONLY, 0);
@@ -1005,7 +891,7 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
return LIBUSB_ERROR_NO_MEM;
}
/* usbfs has holes in the file */
- if (!(sysfs_dir && sysfs_has_descriptors)) {
+ if (!sysfs_dir) {
memset(priv->descriptors + priv->descriptors_len,
0, descriptors_size - priv->descriptors_len);
}
@@ -1028,7 +914,7 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
return LIBUSB_ERROR_IO;
}
- if (sysfs_dir && sysfs_can_relate_devices)
+ if (sysfs_dir)
return LIBUSB_SUCCESS;
/* cache active config */
@@ -1285,7 +1171,7 @@ static int usbfs_get_device_list(struct libusb_context *ctx)
continue;
if (usbdev_names) {
- if (!_is_usbdev_entry(entry->d_name, &busnum, &devaddr))
+ if (!is_usbdev_entry(entry->d_name, &busnum, &devaddr))
continue;
r = linux_enumerate_device(ctx, busnum, devaddr, NULL);
@@ -1352,13 +1238,8 @@ static int linux_default_scan_devices(struct libusb_context *ctx)
* sysfs is preferable, because if we use usbfs we end up resuming
* any autosuspended USB devices. however, sysfs is not available
* everywhere, so we need a usbfs fallback too.
- *
- * as described in the "sysfs vs usbfs" comment at the top of this
- * file, sometimes we have sysfs but not enough information to
- * relate sysfs devices to usbfs nodes. op_init() determines the
- * adequacy of sysfs and sets sysfs_can_relate_devices.
*/
- if (sysfs_can_relate_devices != 0)
+ if (sysfs_available)
return sysfs_get_device_list(ctx);
else
return usbfs_get_device_list(ctx);
@@ -1378,11 +1259,7 @@ static int initialize_handle(struct libusb_device_handle *handle, int fd)
usbi_dbg("getcap not available");
else
usbi_err(HANDLE_CTX(handle), "getcap failed, errno=%d", errno);
- hpriv->caps = 0;
- if (supports_flag_zero_packet)
- hpriv->caps |= USBFS_CAP_ZERO_PACKET;
- if (supports_flag_bulk_continuation)
- hpriv->caps |= USBFS_CAP_BULK_CONTINUATION;
+ hpriv->caps = USBFS_CAP_BULK_CONTINUATION;
}
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);
@@ -1482,7 +1359,7 @@ static int op_get_configuration(struct libusb_device_handle *handle,
struct linux_device_priv *priv = _device_priv(handle->dev);
int r;
- if (priv->sysfs_dir && sysfs_can_relate_devices) {
+ if (priv->sysfs_dir) {
r = sysfs_get_active_config(handle->dev, config);
} else {
r = usbfs_get_active_config(handle->dev, _device_handle_priv(handle)->fd);
@@ -1943,10 +1820,6 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
int r;
int i;
- if (is_out && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) &&
- !(dpriv->caps & USBFS_CAP_ZERO_PACKET))
- return LIBUSB_ERROR_NOT_SUPPORTED;
-
/*
* Older versions of usbfs place a 16kb limit on bulk URBs. We work
* around this by splitting large transfers into 16k blocks, and then
@@ -2794,21 +2667,13 @@ static int op_clock_gettime(int clk_id, struct timespec *tp)
{
switch (clk_id) {
case USBI_CLOCK_MONOTONIC:
- return clock_gettime(monotonic_clkid, tp);
+ return clock_gettime(CLOCK_MONOTONIC, tp);
case USBI_CLOCK_REALTIME:
return clock_gettime(CLOCK_REALTIME, tp);
default:
return LIBUSB_ERROR_INVALID_PARAM;
- }
-}
-
-#ifdef HAVE_TIMERFD
-static clockid_t op_get_timerfd_clockid(void)
-{
- return monotonic_clkid;
-
+ }
}
-#endif
const struct usbi_os_backend usbi_backend = {
.name = "Linux usbfs",
@@ -2853,10 +2718,6 @@ const struct usbi_os_backend usbi_backend = {
.clock_gettime = op_clock_gettime,
-#ifdef HAVE_TIMERFD
- .get_timerfd_clockid = op_get_timerfd_clockid,
-#endif
-
.device_priv_size = sizeof(struct linux_device_priv),
.device_handle_priv_size = sizeof(struct linux_device_handle_priv),
.transfer_priv_size = sizeof(struct linux_transfer_priv),
diff --git a/libusb/os/linux_usbfs.h b/libusb/os/linux_usbfs.h
index 91d3f49..060aa35 100644
--- a/libusb/os/linux_usbfs.h
+++ b/libusb/os/linux_usbfs.h
@@ -21,9 +21,11 @@
#ifndef LIBUSB_USBFS_H
#define LIBUSB_USBFS_H
+#include <linux/magic.h>
#include <linux/types.h>
-#define SYSFS_DEVICE_PATH "/sys/bus/usb/devices"
+#define SYSFS_MOUNT_PATH "/sys"
+#define SYSFS_DEVICE_PATH SYSFS_MOUNT_PATH "/bus/usb/devices"
struct usbfs_ctrltransfer {
/* keep in sync with usbdevice_fs.h:usbdevfs_ctrltransfer */
diff --git a/libusb/os/sunos_usb.c b/libusb/os/sunos_usb.c
index 85d0fdf..5d951c9 100644
--- a/libusb/os/sunos_usb.c
+++ b/libusb/os/sunos_usb.c
@@ -1641,13 +1641,6 @@ sunos_usb_get_status(int fd)
return (status);
}
-#ifdef HAVE_TIMERFD
-static clockid_t op_get_timerfd_clockid(void)
-{
- return CLOCK_MONOTONIC;
-}
-#endif
-
const struct usbi_os_backend usbi_backend = {
.name = "Solaris",
.caps = 0,
@@ -1672,9 +1665,6 @@ const struct usbi_os_backend usbi_backend = {
.cancel_transfer = sunos_cancel_transfer,
.handle_transfer_completion = sunos_handle_transfer_completion,
.clock_gettime = sunos_clock_gettime,
-#ifdef HAVE_TIMERFD
- .get_timerfd_clockid = op_get_timerfd_clockid,
-#endif
.device_priv_size = sizeof(sunos_dev_priv_t),
.device_handle_priv_size = sizeof(sunos_dev_handle_priv_t),
.transfer_priv_size = sizeof(sunos_xfer_priv_t),
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index f335fad..9cef97f 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11450
+#define LIBUSB_NANO 11451