mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-23 12:35:41 +00:00
parent
7e1692d997
commit
55d709a175
1
repos/libports/lib/import/import-libusb.mk
Normal file
1
repos/libports/lib/import/import-libusb.mk
Normal file
@ -0,0 +1 @@
|
||||
INC_DIR += $(call select_from_ports,libusb)/include/libusb
|
23
repos/libports/lib/mk/libusb.mk
Normal file
23
repos/libports/lib/mk/libusb.mk
Normal file
@ -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
|
1
repos/libports/ports/libusb.hash
Normal file
1
repos/libports/ports/libusb.hash
Normal file
@ -0,0 +1 @@
|
||||
a0f714f4389fbdbbc4b9e638d4212c12e69b993a
|
13
repos/libports/ports/libusb.port
Normal file
13
repos/libports/ports/libusb.port
Normal file
@ -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
|
13
repos/libports/src/lib/libusb/README
Normal file
13
repos/libports/src/lib/libusb/README
Normal file
@ -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.
|
159
repos/libports/src/lib/libusb/config.h
Normal file
159
repos/libports/src/lib/libusb/config.h
Normal file
@ -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
|
590
repos/libports/src/lib/libusb/genode_usb_raw.cc
Normal file
590
repos/libports/src/lib/libusb/genode_usb_raw.cc
Normal file
@ -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,
|
||||
};
|
44
repos/libports/src/lib/libusb/libusb.patch
Normal file
44
repos/libports/src/lib/libusb/libusb.patch
Normal file
@ -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;
|
Loading…
x
Reference in New Issue
Block a user