summaryrefslogtreecommitdiff
path: root/emulators/qemu-devel/files/patch-bsdusb.patch
diff options
context:
space:
mode:
authorPav Lucistnik <pav@FreeBSD.org>2006-03-18 21:23:42 +0000
committerPav Lucistnik <pav@FreeBSD.org>2006-03-18 21:23:42 +0000
commitb56ad1448df9cd4f220225a8c951cde64671f5aa (patch)
tree6317e394b6fd6ffa40390811446d567021887102 /emulators/qemu-devel/files/patch-bsdusb.patch
parentPuyos are fancy smiling bubbles... But they can really be invading (diff)
- Add Lonnie's usb host support patches and a bunch of other fixes mostly from
cvs, including a workaround for the -nographic crash. PR: ports/94654 Submitted by: Juergen Lock <nox@jelal.kn-bremen.de> (maintainer)
Notes
Notes: svn path=/head/; revision=157608
Diffstat (limited to 'emulators/qemu-devel/files/patch-bsdusb.patch')
-rw-r--r--emulators/qemu-devel/files/patch-bsdusb.patch741
1 files changed, 741 insertions, 0 deletions
diff --git a/emulators/qemu-devel/files/patch-bsdusb.patch b/emulators/qemu-devel/files/patch-bsdusb.patch
new file mode 100644
index 000000000000..9a90b930cbea
--- /dev/null
+++ b/emulators/qemu-devel/files/patch-bsdusb.patch
@@ -0,0 +1,741 @@
+Index: qemu/configure
+@@ -122,6 +122,7 @@
+ *)
+ oss="yes"
+ linux="yes"
++usb="linux"
+ if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+ kqemu="yes"
+ fi
+@@ -131,6 +132,7 @@
+ if [ "$bsd" = "yes" ] ; then
+ if [ ! "$darwin" = "yes" ] ; then
+ make="gmake"
++ usb="bsd"
+ fi
+ fi
+
+@@ -656,6 +675,19 @@
+ echo "#define _BSD 1" >> $config_h
+ fi
+
++# USB host support
++case "$usb" in
++linux)
++ echo "HOST_USB=linux" >> $conig_mak
++;;
++bsd)
++ echo "HOST_USB=bsd" >> $config_mak
++;;
++*)
++ echo "HOST_USB=stub" >> $config_mak
++;;
++esac
++
+ for target in $target_list; do
+
+ target_dir="$target"
+Index: qemu/Makefile.target
+@@ -303,7 +303,7 @@
+ endif
+
+ # USB layer
+-VL_OBJS+= usb.o usb-uhci.o usb-linux.o usb-hid.o
++VL_OBJS+= usb.o usb-uhci.o usb-$(HOST_USB).o usb-hid.o
+
+ ifeq ($(TARGET_BASE_ARCH), i386)
+ # Hardware support
+Index: qemu/usb-stub.c
+@@ -0,0 +1,11 @@
++#include "vl.h"
++
++void usb_host_info(void)
++{
++ term_printf("USB host devices not supported\n");
++}
++
++USBDevice *usb_host_device_open(const char *devname)
++{
++ return NULL;
++}
+Index: qemu/usb-bsd.c
+@@ -0,0 +1,592 @@
++/*
++ * BSD host USB redirector
++ *
++ * Copyright (c) 2005 Lonnie Mendez
++ * Portions of code and concepts borrowed from
++ * usb-linux.c and libusb's bsd.c and are copyright their respective owners.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++ * THE SOFTWARE.
++ */
++
++#include "vl.h"
++
++/* usb.h declares these */
++#undef USB_SPEED_HIGH
++#undef USB_SPEED_FULL
++#undef USB_SPEED_LOW
++
++#include <sys/ioctl.h>
++#include <dev/usb/usb.h>
++#include <signal.h>
++
++/* This value has maximum potential at 16.
++ * You should also set hw.usb.debug to gain
++ * more detailed view.
++ */
++//#define DEBUG
++#define UGEN_DEBUG_LEVEL 0
++
++
++typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
++ int vendor_id, int product_id,
++ const char *product_name, int speed);
++static int usb_host_find_device(int *pbus_num, int *paddr,
++ const char *devname);
++
++typedef struct USBHostDevice {
++ USBDevice dev;
++ int ep_fd[USB_MAX_ENDPOINTS];
++ int devfd;
++ char devpath[32];
++} USBHostDevice;
++
++
++static int ensure_ep_open(USBHostDevice *dev, int ep, int mode)
++{
++ char buf[32];
++ int fd;
++
++ /* Get the address for this endpoint */
++ ep = UE_GET_ADDR(ep);
++
++ if (dev->ep_fd[ep] < 0) {
++#if __FreeBSD__
++ snprintf(buf, sizeof(buf) - 1, "%s.%d", dev->devpath, ep);
++#else
++ snprintf(buf, sizeof(buf) - 1, "%s.%02d", dev->devpath, ep);
++#endif
++ /* Try to open it O_RDWR first for those devices which have in and out
++ * endpoints with the same address (eg 0x02 and 0x82)
++ */
++ fd = open(buf, O_RDWR);
++ if (fd < 0 && errno == ENXIO)
++ fd = open(buf, mode);
++ if (fd < 0) {
++#ifdef DEBUG
++ printf("ensure_ep_open: failed to open device endpoint %s: %s\n",
++ buf, strerror(errno));
++#endif
++ }
++ dev->ep_fd[ep] = fd;
++ }
++
++ return dev->ep_fd[ep];
++}
++
++static void ensure_eps_closed(USBHostDevice *dev)
++{
++ int epnum = 1;
++
++ if (!dev)
++ return;
++
++ while (epnum < USB_MAX_ENDPOINTS) {
++ if (dev->ep_fd[epnum] >= 0) {
++ close(dev->ep_fd[epnum]);
++ dev->ep_fd[epnum] = -1;
++ }
++ epnum++;
++ }
++}
++
++static void usb_host_handle_reset(USBDevice *dev)
++{
++#if 0
++ USBHostDevice *s = (USBHostDevice *)dev;
++#endif
++}
++
++/* XXX:
++ * -check device states against transfer requests
++ * and return appropriate response
++ */
++static int usb_host_handle_control(USBDevice *dev,
++ int request,
++ int value,
++ int index,
++ int length,
++ uint8_t *data)
++{
++ USBHostDevice *s = (USBHostDevice *)dev;
++ struct usb_ctl_request req;
++ struct usb_alt_interface aiface;
++ int ret, timeout = 50;
++
++ if ((request >> 8) == UT_WRITE_DEVICE &&
++ (request & 0xff) == UR_SET_ADDRESS) {
++
++ /* specific SET_ADDRESS support */
++ dev->addr = value;
++ return 0;
++ } else if ((request >> 8) == UT_WRITE_DEVICE &&
++ (request & 0xff) == UR_SET_CONFIG) {
++
++ ensure_eps_closed(s); /* can't do this without all eps closed */
++
++ ret = ioctl(s->devfd, USB_SET_CONFIG, &value);
++ if (ret < 0) {
++#ifdef DEBUG
++ printf("handle_control: failed to set configuration - %s\n",
++ strerror(errno));
++#endif
++ return USB_RET_STALL;
++ }
++
++ return 0;
++ } else if ((request >> 8) == UT_WRITE_INTERFACE &&
++ (request & 0xff) == UR_SET_INTERFACE) {
++
++ aiface.uai_interface_index = index;
++ aiface.uai_alt_no = value;
++
++ ensure_eps_closed(s); /* can't do this without all eps closed */
++ ret = ioctl(s->devfd, USB_SET_ALTINTERFACE, &aiface);
++ if (ret < 0) {
++#ifdef DEBUG
++ printf("handle_control: failed to set alternate interface - %s\n",
++ strerror(errno));
++#endif
++ return USB_RET_STALL;
++ }
++
++ return 0;
++ } else {
++ req.ucr_request.bmRequestType = request >> 8;
++ req.ucr_request.bRequest = request & 0xff;
++ USETW(req.ucr_request.wValue, value);
++ USETW(req.ucr_request.wIndex, index);
++ USETW(req.ucr_request.wLength, length);
++ req.ucr_data = data;
++ req.ucr_flags = USBD_SHORT_XFER_OK;
++
++ ret = ioctl(s->devfd, USB_SET_TIMEOUT, &timeout);
++#if (__NetBSD__ || __OpenBSD__)
++ if (ret < 0 && errno != EINVAL) {
++#else
++ if (ret < 0) {
++#endif
++#ifdef DEBUG
++ printf("handle_control: setting timeout failed - %s\n",
++ strerror(errno));
++#endif
++ }
++
++ ret = ioctl(s->devfd, USB_DO_REQUEST, &req);
++ /* ugen returns EIO for usbd_do_request_ no matter what
++ * happens with the transfer */
++ if (ret < 0) {
++#ifdef DEBUG
++ printf("handle_control: error after request - %s\n",
++ strerror(errno));
++#endif
++ return USB_RET_NAK; // STALL
++ } else {
++ return req.ucr_actlen;
++ }
++ }
++}
++
++static int usb_host_handle_data(USBDevice *dev, int pid,
++ uint8_t devep,
++ uint8_t *data, int len)
++{
++ USBHostDevice *s = (USBHostDevice *)dev;
++ int ret, fd, mode;
++ int one = 1, shortpacket = 0, timeout = 50;
++ sigset_t new_mask, old_mask;
++
++ /* protect data transfers from SIGALRM signal */
++ sigemptyset(&new_mask);
++ sigaddset(&new_mask, SIGALRM);
++ sigprocmask(SIG_BLOCK, &new_mask, &old_mask);
++
++ /* XXX: optimize and handle all data types by looking at the
++ config descriptor */
++ if (pid == USB_TOKEN_IN) {
++ devep |= 0x80;
++ mode = O_RDONLY;
++ shortpacket = 1;
++ } else {
++ mode = O_WRONLY;
++ }
++
++ fd = ensure_ep_open(s, devep, mode);
++ if (fd < 0) {
++ sigprocmask(SIG_SETMASK, &old_mask, NULL);
++ return USB_RET_NODEV;
++ }
++
++ if (ioctl(fd, USB_SET_TIMEOUT, &timeout) < 0) {
++#ifdef DEBUG
++ printf("handle_data: failed to set timeout - %s\n",
++ strerror(errno));
++#endif
++ }
++
++ if (shortpacket) {
++ if (ioctl(fd, USB_SET_SHORT_XFER, &one) < 0) {
++#ifdef DEBUG
++ printf("handle_data: failed to set short xfer mode - %s\n",
++ strerror(errno));
++#endif
++ sigprocmask(SIG_SETMASK, &old_mask, NULL);
++ }
++ }
++
++ if (pid == USB_TOKEN_IN)
++ ret = read(fd, data, len);
++ else
++ ret = write(fd, data, len);
++
++ sigprocmask(SIG_SETMASK, &old_mask, NULL);
++
++ if (ret < 0) {
++#ifdef DEBUG
++ printf("handle_data: error after %s data - %s\n",
++ pid == USB_TOKEN_IN ? "reading" : "writing", strerror(errno));
++#endif
++ switch(errno) {
++ case ETIMEDOUT:
++ case EINTR:
++ return USB_RET_NAK;
++ default:
++ return USB_RET_STALL;
++ }
++ } else {
++ return ret;
++ }
++}
++
++USBDevice *usb_host_device_open(const char *devname)
++{
++ struct usb_device_info bus_info, dev_info;
++ USBHostDevice *dev;
++ char ctlpath[PATH_MAX + 1];
++ char buspath[PATH_MAX + 1];
++ int bfd, dfd, bus, address, i;
++ int ugendebug = UGEN_DEBUG_LEVEL;
++
++ if (usb_host_find_device(&bus, &address, devname) < 0)
++ return NULL;
++
++ snprintf(buspath, PATH_MAX, "/dev/usb%d", bus);
++
++ bfd = open(buspath, O_RDWR);
++ if (bfd < 0) {
++#ifdef DEBUG
++ printf("usb_host_device_open: failed to open usb bus - %s\n",
++ strerror(errno));
++#endif
++ return NULL;
++ }
++
++ bus_info.udi_addr = address;
++ if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0) {
++#ifdef DEBUG
++ printf("usb_host_device_open: failed to grab bus information - %s\n",
++ strerror(errno));
++#endif
++ return NULL;
++ }
++
++#if __FreeBSD__
++ snprintf(ctlpath, PATH_MAX, "/dev/%s", bus_info.udi_devnames[0]);
++#else
++ snprintf(ctlpath, PATH_MAX, "/dev/%s.00", bus_info.udi_devnames[0]);
++#endif
++
++ dfd = open(ctlpath, O_RDWR);
++ if (dfd < 0) {
++ dfd = open(ctlpath, O_RDONLY);
++ if (dfd < 0) {
++#ifdef DEBUG
++ printf("usb_host_device_open: failed to open usb device %s - %s\n",
++ ctlpath, strerror(errno));
++#endif
++ }
++ }
++
++ if (dfd >= 0) {
++ dev = qemu_mallocz(sizeof(USBHostDevice));
++ if (!dev)
++ goto fail;
++ dev->devfd = dfd;
++
++ if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0) {
++#ifdef DEBUG
++ printf("usb_host_device_open: failed to grab device info - %s\n",
++ strerror(errno));
++#endif
++ goto fail;
++ }
++
++ if (dev_info.udi_speed == 1)
++ dev->dev.speed = USB_SPEED_LOW - 1;
++ else
++ dev->dev.speed = USB_SPEED_FULL - 1;
++
++ dev->dev.handle_packet = usb_generic_handle_packet;
++
++ dev->dev.handle_reset = usb_host_handle_reset;
++ dev->dev.handle_control = usb_host_handle_control;
++ dev->dev.handle_data = usb_host_handle_data;
++
++ strcpy(dev->devpath, "/dev/");
++ strcat(dev->devpath, dev_info.udi_devnames[0]);
++
++ /* Mark the endpoints as not yet open */
++ for (i = 0; i < USB_MAX_ENDPOINTS; i++)
++ dev->ep_fd[i] = -1;
++
++ ioctl(dfd, USB_SETDEBUG, &ugendebug);
++
++ return (USBDevice *)dev;
++ }
++
++fail:
++ return NULL;
++}
++
++void usb_host_device_close(USBDevice *opaque)
++{
++ USBHostDevice *s = (USBHostDevice *)opaque;
++ int i;
++
++ for (i = 0; i < USB_MAX_ENDPOINTS; i++)
++ if (s->ep_fd[i] >= 0)
++ close(s->ep_fd[i]);
++
++ if (s->devfd < 0)
++ return;
++
++ close(s->devfd);
++}
++
++static int usb_host_scan(void *opaque, USBScanFunc *func)
++{
++ struct usb_device_info bus_info;
++ struct usb_device_info dev_info;
++ uint16_t vendor_id, product_id, class_id, speed;
++ int bfd, dfd, bus, address;
++ char busbuf[20], devbuf[20], product_name[256];
++ int ret = 0;
++
++ for (bus = 0; bus < 10; bus++) {
++
++ snprintf(busbuf, sizeof(busbuf) - 1, "/dev/usb%d", bus);
++ bfd = open(busbuf, O_RDWR);
++ if (bfd < 0)
++ continue;
++
++ for (address = 1; address < 127; address++) {
++
++ bus_info.udi_addr = address;
++ if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0)
++ continue;
++
++ /* only list devices that can be used by generic layer */
++ if (strncmp(bus_info.udi_devnames[0], "ugen", 4) != 0)
++ continue;
++
++#if __FreeBSD__
++ snprintf(devbuf, sizeof(devbuf) - 1, "/dev/%s", bus_info.udi_devnames[0]);
++#else
++ snprintf(devbuf, sizeof(devbuf) - 1, "/dev/%s.00", bus_info.udi_devnames[0]);
++#endif
++
++ dfd = open(devbuf, O_RDONLY);
++ if (dfd < 0) {
++#ifdef DEBUG
++ printf("usb_host_scan: couldn't open device %s - %s\n", devbuf,
++ strerror(errno));
++#endif
++ continue;
++ }
++
++ if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0)
++ printf("usb_host_scan: couldn't get device information for %s - %s\n",
++ devbuf, strerror(errno));
++
++ // XXX: might need to fixup endianess of word values before copying over
++
++ vendor_id = dev_info.udi_vendorNo;
++ product_id = dev_info.udi_productNo;
++ class_id = dev_info.udi_class;
++ speed = dev_info.udi_speed;
++
++ if (strncmp(dev_info.udi_product, "product", 7) != 0)
++ strcpy(product_name, dev_info.udi_product);
++ else
++ product_name[0] = '\0';
++
++ ret = func(opaque, bus, address, class_id, vendor_id,
++ product_id, product_name, speed);
++
++ close(dfd);
++
++ if (ret)
++ goto the_end;
++ }
++
++ close(bfd);
++ }
++
++the_end:
++ return ret;
++}
++
++typedef struct FindDeviceState {
++ int vendor_id;
++ int product_id;
++ int bus_num;
++ int addr;
++} FindDeviceState;
++
++static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
++ int class_id,
++ int vendor_id, int product_id,
++ const char *product_name, int speed)
++{
++ FindDeviceState *s = opaque;
++ if (vendor_id == s->vendor_id &&
++ product_id == s->product_id) {
++ s->bus_num = bus_num;
++ s->addr = addr;
++ return 1;
++ } else {
++ return 0;
++ }
++}
++
++
++/* the syntax is :
++ 'bus.addr' (decimal numbers) or
++ 'vendor_id:product_id' (hexa numbers) */
++static int usb_host_find_device(int *pbus_num, int *paddr,
++ const char *devname)
++{
++ const char *p;
++ int ret;
++ FindDeviceState fs;
++
++ p = strchr(devname, '.');
++ if (p) {
++ *pbus_num = strtoul(devname, NULL, 0);
++ *paddr = strtoul(p + 1, NULL, 0);
++ return 0;
++ }
++ p = strchr(devname, ':');
++ if (p) {
++ fs.vendor_id = strtoul(devname, NULL, 16);
++ fs.product_id = strtoul(p + 1, NULL, 16);
++ ret = usb_host_scan(&fs, usb_host_find_device_scan);
++ if (ret) {
++ *pbus_num = fs.bus_num;
++ *paddr = fs.addr;
++ return 0;
++ }
++ }
++ return -1;
++}
++
++/**********************/
++/* USB host device info */
++
++struct usb_class_info {
++ int class;
++ const char *class_name;
++};
++
++static const struct usb_class_info usb_class_info[] = {
++ { USB_CLASS_AUDIO, "Audio"},
++ { USB_CLASS_COMM, "Communication"},
++ { USB_CLASS_HID, "HID"},
++ { USB_CLASS_HUB, "Hub" },
++ { USB_CLASS_PHYSICAL, "Physical" },
++ { USB_CLASS_PRINTER, "Printer" },
++ { USB_CLASS_MASS_STORAGE, "Storage" },
++ { USB_CLASS_CDC_DATA, "Data" },
++ { USB_CLASS_APP_SPEC, "Application Specific" },
++ { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
++ { USB_CLASS_STILL_IMAGE, "Still Image" },
++ { USB_CLASS_CSCID, "Smart Card" },
++ { USB_CLASS_CONTENT_SEC, "Content Security" },
++ { -1, NULL }
++};
++
++static const char *usb_class_str(uint8_t class)
++{
++ const struct usb_class_info *p;
++ for (p = usb_class_info; p->class != -1; p++) {
++ if (p->class == class)
++ break;
++ }
++ return p->class_name;
++}
++
++void usb_info_device(int bus_num, int addr, int class_id,
++ int vendor_id, int product_id,
++ const char *product_name,
++ int speed)
++{
++ const char *class_str, *speed_str;
++
++ switch(speed) {
++ case USB_SPEED_LOW:
++ speed_str = "1.5";
++ break;
++ case USB_SPEED_FULL:
++ speed_str = "12";
++ break;
++ case USB_SPEED_HIGH:
++ speed_str = "480";
++ break;
++ default:
++ speed_str = "?";
++ break;
++ }
++
++ term_printf(" Device %d.%d, speed %s Mb/s\n",
++ bus_num, addr, speed_str);
++ class_str = usb_class_str(class_id);
++ if (class_str)
++ term_printf(" %s:", class_str);
++ else
++ term_printf(" Class %02x:", class_id);
++ term_printf(" USB device %04x:%04x", vendor_id, product_id);
++ if (product_name[0] != '\0')
++ term_printf(", %s", product_name);
++ term_printf("\n");
++}
++
++static int usb_host_info_device(void *opaque, int bus_num, int addr,
++ int class_id,
++ int vendor_id, int product_id,
++ const char *product_name,
++ int speed)
++{
++ usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
++ product_name, speed);
++ return 0;
++}
++
++void usb_host_info(void)
++{
++ usb_host_scan(NULL, usb_host_info_device);
++}
+Index: qemu/vl.c
+@@ -2820,10 +2822,12 @@
+ dev = usb_host_device_open(p);
+ if (!dev)
+ return -1;
++ dev->isproxied = 1;
+ } else if (!strcmp(devname, "mouse")) {
+ dev = usb_mouse_init();
+ if (!dev)
+ return -1;
++ dev->isproxied = 0;
+ } else {
+ return -1;
+ }
+@@ -2852,6 +2856,8 @@
+ if (dev && dev->addr == addr)
+ break;
+ }
++ if (dev && dev->isproxied)
++ usb_host_device_close(dev);
+ if (i == MAX_VM_USB_PORTS)
+ return -1;
+ usb_attach(vm_usb_ports[i], NULL);
+Index: qemu/hw/usb.h
+@@ -135,6 +146,8 @@
+ int setup_state;
+ int setup_len;
+ int setup_index;
++
++ int isproxied;
+ };
+
+ /* USB port on which a device can be connected */
+@@ -157,8 +170,9 @@
+ /* usb-uhci.c */
+ void usb_uhci_init(PCIBus *bus, USBPort **usb_ports);
+
+-/* usb-linux.c */
++/* host proxy functions */
+ USBDevice *usb_host_device_open(const char *devname);
++void usb_host_device_close(USBDevice *dev);
+ void usb_host_info(void);
+
+ /* usb-hid.c */
+Index: qemu/usb-linux.c
+@@ -23,7 +23,6 @@
+ */
+ #include "vl.h"
+
+-#if defined(__linux__)
+ #include <dirent.h>
+ #include <sys/ioctl.h>
+ #include <linux/usbdevice_fs.h>
+@@ -255,6 +254,14 @@
+ return q - buf;
+ }
+
++void usb_host_device_close(USBDevice *opaque)
++{
++ USBHostDevice *s = (USBHostDevice *)opaque;
++
++ if (s->fd >= 0)
++ close(s->fd);
++}
++
+ static int usb_host_scan(void *opaque, USBScanFunc *func)
+ {
+ FILE *f;
+@@ -468,18 +475,3 @@
+ {
+ usb_host_scan(NULL, usb_host_info_device);
+ }
+-
+-#else
+-
+-void usb_host_info(void)
+-{
+- term_printf("USB host devices not supported\n");
+-}
+-
+-/* XXX: modify configure to compile the right host driver */
+-USBDevice *usb_host_device_open(const char *devname)
+-{
+- return NULL;
+-}
+-
+-#endif