diff --git a/repos/libports/lib/import/import-libusb.mk b/repos/libports/lib/import/import-libusb.mk new file mode 100644 index 0000000000..fbba7ffa39 --- /dev/null +++ b/repos/libports/lib/import/import-libusb.mk @@ -0,0 +1 @@ +INC_DIR += $(call select_from_ports,libusb)/include/libusb diff --git a/repos/libports/lib/mk/libusb.mk b/repos/libports/lib/mk/libusb.mk new file mode 100644 index 0000000000..d952893c73 --- /dev/null +++ b/repos/libports/lib/mk/libusb.mk @@ -0,0 +1,23 @@ +LIBUSB_DIR := $(call select_from_ports,libusb)/src/lib/libusb +LIBS += libc libc_pipe pthread + +# find 'config.h' +INC_DIR += $(REP_DIR)/src/lib/libusb + +INC_DIR += $(LIBUSB_DIR)/libusb + +SRC_C = core.c \ + descriptor.c \ + io.c \ + strerror.c \ + sync.c \ + hotplug.c \ + os/poll_posix.c \ + os/threads_posix.c + +SRC_CC = genode_usb_raw.cc + +vpath %.c $(LIBUSB_DIR)/libusb +vpath %.cc $(REP_DIR)/src/lib/libusb + +SHARED_LIB = yes diff --git a/repos/libports/ports/libusb.hash b/repos/libports/ports/libusb.hash new file mode 100644 index 0000000000..e66f9c3d2e --- /dev/null +++ b/repos/libports/ports/libusb.hash @@ -0,0 +1 @@ +a0f714f4389fbdbbc4b9e638d4212c12e69b993a diff --git a/repos/libports/ports/libusb.port b/repos/libports/ports/libusb.port new file mode 100644 index 0000000000..311dbf76b1 --- /dev/null +++ b/repos/libports/ports/libusb.port @@ -0,0 +1,13 @@ +LICENSE := LGPL +DOWNLOADS := libusb.archive +VERSION := 1.0.20 + +URL(libusb) := http://prdownloads.sourceforge.net/libusb/libusb-$(VERSION).tar.bz2 +SHA(libusb) := 9537243f165927bde74ad742e6b3effb0bd50cd2 +DIR(libusb) := src/lib/libusb + +DIRS := include/libusb +DIR_CONTENT(include/libusb) := src/lib/libusb/libusb/libusb.h + +PATCHES := src/lib/libusb/libusb.patch +PATCH_OPT := -p1 -d src/lib/libusb diff --git a/repos/libports/src/lib/libusb/README b/repos/libports/src/lib/libusb/README new file mode 100644 index 0000000000..97462f0452 --- /dev/null +++ b/repos/libports/src/lib/libusb/README @@ -0,0 +1,13 @@ +Currently, libusb supports a single USB device, which it requests from the USB +driver with the 'usb_device' label. + +The policy of the USB driver configures the actual device to be provided to +the application using libusb: + +<config> + <raw> + <policy label="application -> usb_device" vendor_id="0xXXXX" product_id="0xXXXX"/> + </raw> +</config> + +See also the README file of the USB driver for additional policy attributes. diff --git a/repos/libports/src/lib/libusb/config.h b/repos/libports/src/lib/libusb/config.h new file mode 100644 index 0000000000..c4e51ced4a --- /dev/null +++ b/repos/libports/src/lib/libusb/config.h @@ -0,0 +1,159 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Default visibility */ +#define DEFAULT_VISIBILITY __attribute__((visibility("default"))) + +/* Start with debug message logging enabled */ +/* #undef ENABLE_DEBUG_LOGGING */ + +/* Message logging */ +#define ENABLE_LOGGING 1 + +/* Define to 1 if you have the <asm/types.h> header file. */ +#define HAVE_ASM_TYPES_H 1 + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `udev' library (-ludev). */ +/* #undef HAVE_LIBUDEV */ + +/* Define to 1 if you have the <libudev.h> header file. */ +/* #undef HAVE_LIBUDEV_H */ + +/* Define to 1 if you have the <linux/filter.h> header file. */ +#define HAVE_LINUX_FILTER_H 1 + +/* Define to 1 if you have the <linux/netlink.h> header file. */ +#define HAVE_LINUX_NETLINK_H 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the <poll.h> header file. */ +#define HAVE_POLL_H 1 + +/* Define to 1 if you have the <signal.h> header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if the system has the type `struct timespec'. */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* syslog() function available */ +#define HAVE_SYSLOG_FUNC 1 + +/* Define to 1 if you have the <syslog.h> header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Darwin backend */ +/* #undef OS_DARWIN */ + +/* Genode backend */ +#define OS_GENODE 1 + +/* Haiku backend */ +/* #undef OS_HAIKU */ + +/* Linux backend */ +/* #undef OS_LINUX */ + +/* NetBSD backend */ +/* #undef OS_NETBSD */ + +/* OpenBSD backend */ +/* #undef OS_OPENBSD */ + +/* Windows backend */ +/* #undef OS_WINDOWS */ + +/* Name of package */ +#define PACKAGE "libusb" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "libusb-devel@lists.sourceforge.net" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libusb" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libusb 1.0.20" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libusb" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "http://libusb.info" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.0.20" + +/* type of second poll() argument */ +#define POLL_NFDS_TYPE nfds_t + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Use POSIX Threads */ +#define THREADS_POSIX 1 + +/* timerfd headers available */ +/* #undef USBI_TIMERFD_AVAILABLE */ + +/* Enable output to system log */ +/* #undef USE_SYSTEM_LOGGING_FACILITY */ + +/* Use udev for device enumeration/hotplug */ +/* #undef USE_UDEV */ + +/* Version number of package */ +#define VERSION "1.0.20" + +/* Oldest Windows version supported */ +/* #undef WINVER */ + +/* Use GNU extensions */ +#define _GNU_SOURCE 1 + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/repos/libports/src/lib/libusb/genode_usb_raw.cc b/repos/libports/src/lib/libusb/genode_usb_raw.cc new file mode 100644 index 0000000000..da38068338 --- /dev/null +++ b/repos/libports/src/lib/libusb/genode_usb_raw.cc @@ -0,0 +1,590 @@ +/* + * \brief Genode backend for libusb + * \author Christian Prochaska + * \date 2016-09-19 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include <base/log.h> +#include <base/allocator_avl.h> +#include <base/signal.h> +#include <usb/usb.h> +#include <usb_session/connection.h> + +#include <time.h> + +#include "libusbi.h" + +static Genode::Signal_receiver &signal_receiver() +{ + static Genode::Signal_receiver instance; + return instance; +} + + +struct Completion : Usb::Completion +{ + struct usbi_transfer *itransfer; + + Completion(struct usbi_transfer *itransfer) + : itransfer(itransfer) { } + + void complete(Usb::Packet_descriptor &p) override { } +}; + + +struct Usb_device +{ + Genode::Allocator_avl alloc { Genode::env()->heap() }; + Genode::Signal_context state_changed_signal_context; + Genode::Signal_receiver state_changed_signal_receiver; + Usb::Connection usb_connection { &alloc, + "usb_device", + 512*1024, + state_changed_signal_receiver.manage( + &state_changed_signal_context) }; + + Genode::Signal_dispatcher<Usb_device> ack_avail_signal_dispatcher + { signal_receiver(), *this, + &Usb_device::ack_avail }; + + Usb::Device_descriptor device_descriptor; + Usb::Config_descriptor config_descriptor; + char *raw_config_descriptor = nullptr; + + Usb_device() + { + while (!usb_connection.plugged()) { + Genode::log("libusb: waiting until device is plugged..."); + state_changed_signal_receiver.wait_for_signal(); + Genode::log("libusb: device is plugged"); + } + + usb_connection.config_descriptor(&device_descriptor, &config_descriptor); + + raw_config_descriptor = (char*)malloc(config_descriptor.total_length); + + Usb::Packet_descriptor p = + usb_connection.source()->alloc_packet(config_descriptor.total_length); + + p.type = Usb::Packet_descriptor::CTRL; + p.control.request = LIBUSB_REQUEST_GET_DESCRIPTOR; + p.control.request_type = LIBUSB_ENDPOINT_IN; + p.control.value = (LIBUSB_DT_CONFIG << 8) | 0; + p.control.index = 0; + + usb_connection.source()->submit_packet(p); + + p = usb_connection.source()->get_acked_packet(); + + if (!p.succeded) + Genode::error(__PRETTY_FUNCTION__, + ": could not read raw configuration descriptor"); + + if (p.control.actual_size != config_descriptor.total_length) + Genode::error(__PRETTY_FUNCTION__, + ": received configuration descriptor of unexpected size"); + + char *packet_content = usb_connection.source()->packet_content(p); + Genode::memcpy(raw_config_descriptor, packet_content, + config_descriptor.total_length); + + usb_connection.tx_channel()->sigh_ack_avail(ack_avail_signal_dispatcher); + } + + ~Usb_device() + { + free(raw_config_descriptor); + } + + void ack_avail(unsigned) + { + while (usb_connection.source()->ack_avail()) { + + Usb::Packet_descriptor p = + usb_connection.source()->get_acked_packet(); + + Completion *completion = static_cast<Completion*>(p.completion); + struct usbi_transfer *itransfer = completion->itransfer; + destroy(Genode::env()->heap(), completion); + + if (!p.succeded) { + Genode::error("USB transfer failed"); + itransfer->transferred = -1; + usb_connection.source()->release_packet(p); + usbi_signal_transfer_completion(itransfer); + continue; + } + + char *packet_content = usb_connection.source()->packet_content(p); + + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + + case LIBUSB_TRANSFER_TYPE_CONTROL: { + + itransfer->transferred = p.control.actual_size; + + struct libusb_control_setup *setup = + (struct libusb_control_setup*)transfer->buffer; + + if ((setup->bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == + LIBUSB_ENDPOINT_IN) { + Genode::memcpy(transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, + packet_content, p.control.actual_size); + } + + break; + } + + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: { + + itransfer->transferred = p.transfer.actual_size; + + if (IS_XFERIN(transfer)) + Genode::memcpy(transfer->buffer, packet_content, + p.transfer.actual_size); + + break; + } + + default: + Genode::error(__PRETTY_FUNCTION__, + ": unsupported transfer type"); + usb_connection.source()->release_packet(p); + continue; + } + + usb_connection.source()->release_packet(p); + + usbi_signal_transfer_completion(itransfer); + } + } +}; + + +static void *signal_handler_thread_entry(void *) +{ + for (;;) { + + Genode::Signal signal = signal_receiver().wait_for_signal(); + + Genode::Signal_dispatcher_base *dispatcher = + static_cast<Genode::Signal_dispatcher_base *>(signal.context()); + + dispatcher->dispatch(signal.num()); + } +} + + +static int genode_init(struct libusb_context* ctx) +{ + pthread_t signal_handler_thread; + if (pthread_create(&signal_handler_thread, nullptr, + signal_handler_thread_entry, nullptr) < 0) { + Genode::error("Could not create signal handler thread"); + return LIBUSB_ERROR_OTHER; + } + + return LIBUSB_SUCCESS; +} + + +static void genode_exit(void) { } + + +int genode_get_device_list(struct libusb_context *ctx, + struct discovered_devs **discdevs) +{ + unsigned long session_id; + struct libusb_device *dev; + + uint8_t busnum = 1; + uint8_t devaddr = 1; + + session_id = busnum << 8 | devaddr; + usbi_dbg("busnum %d devaddr %d session_id %ld", busnum, devaddr, + session_id); + + dev = usbi_get_device_by_session_id(ctx, session_id); + + if (!dev) { + + usbi_dbg("allocating new device for %d/%d (session %ld)", + busnum, devaddr, session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) + return LIBUSB_ERROR_NO_MEM; + + /* initialize device structure */ + dev->bus_number = busnum; + dev->device_address = devaddr; + + /* FIXME: find place to free the allocated memory */ + Usb_device *usb_device = new (Genode::env()->heap()) Usb_device; + *(Usb_device**)dev->os_priv = usb_device; + + switch (usb_device->device_descriptor.speed) { + case Usb::Device::SPEED_LOW: + dev->speed = LIBUSB_SPEED_LOW; + break; + case Usb::Device::SPEED_FULL: + dev->speed = LIBUSB_SPEED_FULL; + break; + case Usb::Device::SPEED_HIGH: + dev->speed = LIBUSB_SPEED_HIGH; + break; + case Usb::Device::SPEED_SUPER: + dev->speed = LIBUSB_SPEED_SUPER; + break; + default: + Genode::warning(__PRETTY_FUNCTION__, ": unknown device speed"); + dev->speed = LIBUSB_SPEED_UNKNOWN; + } + + int result = usbi_sanitize_device(dev); + if (result < 0) { + libusb_unref_device(dev); + return result; + } + + } else { + usbi_dbg("session_id %ld already exists", session_id); + } + + if (discovered_devs_append(*discdevs, dev) == NULL) { + libusb_unref_device(dev); + return LIBUSB_ERROR_NO_MEM; + } + + libusb_unref_device(dev); + + return LIBUSB_SUCCESS; +} + + +static int genode_open(struct libusb_device_handle *dev_handle) +{ + return LIBUSB_SUCCESS; +} + + +static void genode_close(struct libusb_device_handle *dev_handle) +{ +} + + +static int genode_get_device_descriptor(struct libusb_device *device, + unsigned char* buffer, + int *host_endian) +{ + Usb_device *usb_device = *(Usb_device**)device->os_priv; + + Genode::memcpy(buffer, &usb_device->device_descriptor, + sizeof(libusb_device_descriptor)); + + *host_endian = 0; + + return LIBUSB_SUCCESS; +} + + +static int genode_get_config_descriptor(struct libusb_device *device, + uint8_t config_index, + unsigned char *buffer, + size_t len, + int *host_endian) +{ + if (config_index != 0) { + Genode::error(__PRETTY_FUNCTION__, + ": only the first configuration is supported"); + return LIBUSB_ERROR_NOT_SUPPORTED; + } + + Usb_device *usb_device = *(Usb_device**)device->os_priv; + + Genode::memcpy(buffer, usb_device->raw_config_descriptor, len); + + *host_endian = 0; + + return len; +} + + +static int genode_get_active_config_descriptor(struct libusb_device *device, + unsigned char *buffer, + size_t len, + int *host_endian) +{ + /* only configuration 0 is currently supported */ + return genode_get_config_descriptor(device, 0, buffer, len, host_endian); +} + + +static int genode_set_configuration(struct libusb_device_handle *dev_handle, + int config) +{ + Genode::error(__PRETTY_FUNCTION__, + ": not implemented (return address: ", + Genode::Hex((Genode::addr_t)__builtin_return_address(0)), + ") \n"); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + + +static int genode_claim_interface(struct libusb_device_handle *dev_handle, + int interface_number) +{ + Usb_device *usb_device = *(Usb_device**)dev_handle->dev->os_priv; + + try { + usb_device->usb_connection.claim_interface(interface_number); + } catch (Usb::Session::Interface_not_found) { + Genode::error(__PRETTY_FUNCTION__, ": interface not found"); + return LIBUSB_ERROR_NOT_FOUND; + } catch (Usb::Session::Interface_already_claimed) { + Genode::error(__PRETTY_FUNCTION__, ": interface already claimed"); + return LIBUSB_ERROR_BUSY; + } catch (...) { + Genode::error(__PRETTY_FUNCTION__, ": unknown exception"); + return LIBUSB_ERROR_OTHER; + } + + return LIBUSB_SUCCESS; +} + + +static int genode_release_interface(struct libusb_device_handle *dev_handle, + int interface_number) +{ + Usb_device *usb_device = *(Usb_device**)dev_handle->dev->os_priv; + + try { + usb_device->usb_connection.release_interface(interface_number); + } catch (Usb::Session::Interface_not_found) { + Genode::error(__PRETTY_FUNCTION__, ": interface not found"); + return LIBUSB_ERROR_NOT_FOUND; + } catch (...) { + Genode::error(__PRETTY_FUNCTION__, ": unknown exception"); + return LIBUSB_ERROR_OTHER; + } + + return LIBUSB_SUCCESS; +} + + +static int genode_set_interface_altsetting(struct libusb_device_handle* dev_handle, + int interface_number, + int altsetting) +{ + Genode::error(__PRETTY_FUNCTION__, + ": not implemented (return address: ", + Genode::Hex((Genode::addr_t)__builtin_return_address(0)), + ") \n"); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + + +static int genode_submit_transfer(struct usbi_transfer * itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + Usb_device *usb_device = *(Usb_device**)transfer->dev_handle->dev->os_priv; + + switch (transfer->type) { + + case LIBUSB_TRANSFER_TYPE_CONTROL: { + + struct libusb_control_setup *setup = + (struct libusb_control_setup*)transfer->buffer; + + Usb::Packet_descriptor p; + + try { + p = usb_device->usb_connection.source()->alloc_packet(transfer->length); + } catch (Usb::Session::Tx::Source::Packet_alloc_failed) { + Genode::error(__PRETTY_FUNCTION__, ": packet allocation failed"); + return LIBUSB_ERROR_BUSY; + } + + p.completion = new (Genode::env()->heap()) Completion(itransfer); + + p.type = Usb::Packet_descriptor::CTRL; + p.control.request = setup->bRequest; + p.control.request_type = setup->bmRequestType; + p.control.value = setup->wValue; + p.control.index = setup->wIndex; + p.control.timeout = transfer->timeout; + + if ((setup->bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == + LIBUSB_ENDPOINT_OUT) { + + char *packet_content = + usb_device->usb_connection.source()->packet_content(p); + + Genode::memcpy(packet_content, + transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, + setup->wLength); + } + + try { + usb_device->usb_connection.source()->submit_packet(p); + } catch (...) { + Genode::error(__PRETTY_FUNCTION__, + ": could not submit packet"); + } + + return LIBUSB_SUCCESS; + } + + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: { + + if (IS_XFEROUT(transfer) && + transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { + Genode::error(__PRETTY_FUNCTION__, + ": zero packet not supported"); + return LIBUSB_ERROR_NOT_SUPPORTED; + } + + Usb::Packet_descriptor p; + + try { + p = usb_device->usb_connection.source()->alloc_packet(transfer->length); + } catch (Usb::Session::Tx::Source::Packet_alloc_failed) { + Genode::error(__PRETTY_FUNCTION__, + ": packet allocation failed"); + return LIBUSB_ERROR_BUSY; + } + + if (transfer->type == LIBUSB_TRANSFER_TYPE_INTERRUPT) { + p.type = Usb::Packet_descriptor::IRQ; + p.transfer.polling_interval = + Usb::Packet_descriptor::DEFAULT_POLLING_INTERVAL; + } else + p.type = Usb::Packet_descriptor::BULK; + + p.completion = new (Genode::env()->heap()) Completion(itransfer); + p.transfer.ep = transfer->endpoint; + + if (IS_XFEROUT(transfer)) { + char *packet_content = + usb_device->usb_connection.source()->packet_content(p); + Genode::memcpy(packet_content, transfer->buffer, + transfer->length); + } + + try { + usb_device->usb_connection.source()->submit_packet(p); + } catch (...) { + Genode::error(__PRETTY_FUNCTION__, + ": could not submit packet"); + } + + return LIBUSB_SUCCESS; + } + + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + Genode::error(__PRETTY_FUNCTION__, + ": isochronous transfer - not implemented"); + return LIBUSB_ERROR_NOT_SUPPORTED; + + default: + usbi_err(TRANSFER_CTX(transfer), + "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + + +static int genode_cancel_transfer(struct usbi_transfer * itransfer) +{ + return LIBUSB_ERROR_NOT_SUPPORTED; +} + + +static void genode_clear_transfer_priv(struct usbi_transfer * itransfer) { } + + +static int genode_handle_transfer_completion(struct usbi_transfer * itransfer) +{ + return usbi_handle_transfer_completion(itransfer, + LIBUSB_TRANSFER_COMPLETED); +} + + +static int genode_clock_gettime(int clkid, struct timespec *tp) +{ + switch (clkid) { + case USBI_CLOCK_MONOTONIC: + return clock_gettime(CLOCK_MONOTONIC, tp); + case USBI_CLOCK_REALTIME: + return clock_gettime(CLOCK_REALTIME, tp); + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +} + + +const struct usbi_os_backend genode_usb_raw_backend = { + /*.name =*/ "Genode", + /*.caps =*/ 0, + /*.init =*/ genode_init, + /*.exit =*/ genode_exit, + /*.get_device_list =*/ genode_get_device_list, + /*.hotplug_poll =*/ NULL, + /*.open =*/ genode_open, + /*.close =*/ genode_close, + /*.get_device_descriptor =*/ genode_get_device_descriptor, + /*.get_active_config_descriptor =*/ genode_get_active_config_descriptor, + /*.get_config_descriptor =*/ genode_get_config_descriptor, + /*.get_config_descriptor_by_value =*/ NULL, + + + /*.get_configuration =*/ NULL, + /*.set_configuration =*/ genode_set_configuration, + /*.claim_interface =*/ genode_claim_interface, + /*.release_interface =*/ genode_release_interface, + + /*.set_interface_altsetting =*/ genode_set_interface_altsetting, + /*.clear_halt =*/ NULL, + /*.reset_device =*/ NULL, + + /*.alloc_streams =*/ NULL, + /*.free_streams =*/ NULL, + + /*.kernel_driver_active =*/ NULL, + /*.detach_kernel_driver =*/ NULL, + /*.attach_kernel_driver =*/ NULL, + + /*.destroy_device =*/ NULL, + + /*.submit_transfer =*/ genode_submit_transfer, + /*.cancel_transfer =*/ genode_cancel_transfer, + /*.clear_transfer_priv =*/ genode_clear_transfer_priv, + + /*.handle_events =*/ NULL, + /*.handle_transfer_completion =*/ genode_handle_transfer_completion, + + /*.clock_gettime =*/ genode_clock_gettime, + +#ifdef USBI_TIMERFD_AVAILABLE + /*.get_timerfd_clockid =*/ NULL, +#endif + + /*.device_priv_size =*/ sizeof(Usb_device*), + /*.device_handle_priv_size =*/ 0, + /*.transfer_priv_size =*/ 0, +}; diff --git a/repos/libports/src/lib/libusb/libusb.patch b/repos/libports/src/lib/libusb/libusb.patch new file mode 100644 index 0000000000..8d9b6e6d37 --- /dev/null +++ b/repos/libports/src/lib/libusb/libusb.patch @@ -0,0 +1,44 @@ +libusb.patch + +From: Christian Prochaska <christian.prochaska@genode-labs.com> + + +--- + libusb/core.c | 2 ++ + libusb/libusbi.h | 3 ++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libusb/core.c b/libusb/core.c +index 5884dcf..eae852f 100644 +--- a/libusb/core.c ++++ b/libusb/core.c +@@ -58,6 +58,8 @@ const struct usbi_os_backend * const usbi_backend = &windows_backend; + const struct usbi_os_backend * const usbi_backend = &wince_backend; + #elif defined(OS_HAIKU) + const struct usbi_os_backend * const usbi_backend = &haiku_usb_raw_backend; ++#elif defined(OS_GENODE) ++const struct usbi_os_backend * const usbi_backend = &genode_usb_raw_backend; + #else + #error "Unsupported OS" + #endif +diff --git a/libusb/libusbi.h b/libusb/libusbi.h +index 822612e..8777ede 100644 +--- a/libusb/libusbi.h ++++ b/libusb/libusbi.h +@@ -493,7 +493,7 @@ int usbi_signal_event(struct libusb_context *ctx); + int usbi_clear_event(struct libusb_context *ctx); + + /* Internal abstraction for poll (needs struct usbi_transfer on Windows) */ +-#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU) ++#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU) || defined(OS_GENODE) + #include <unistd.h> + #include "os/poll_posix.h" + #elif defined(OS_WINDOWS) || defined(OS_WINCE) +@@ -1091,6 +1091,7 @@ extern const struct usbi_os_backend netbsd_backend; + extern const struct usbi_os_backend windows_backend; + extern const struct usbi_os_backend wince_backend; + extern const struct usbi_os_backend haiku_usb_raw_backend; ++extern const struct usbi_os_backend genode_usb_raw_backend; + + extern struct list_head active_contexts_list; + extern usbi_mutex_static_t active_contexts_lock;