Commit 6806364989f71456a65c630bc380249c9462204c

Authored by blueswir1
1 parent 6972f935

Native BSD host USB support (Juergen Lock, Lonnie Mendez)

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5780 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -74,7 +74,7 @@ OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o
74 74 OBJS+=tmp105.o lm832x.o
75 75 OBJS+=scsi-disk.o cdrom.o
76 76 OBJS+=scsi-generic.o
77   -OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o
  77 +OBJS+=usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
78 78 OBJS+=usb-serial.o usb-net.o
79 79 OBJS+=sd.o ssi-sd.o
80 80 OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
... ...
configure
... ... @@ -221,6 +221,7 @@ audio_drv_list="oss"
221 221 audio_possible_drivers="oss alsa sdl esd pa"
222 222 linux="yes"
223 223 linux_user="yes"
  224 +usb="linux"
224 225 if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
225 226 kqemu="yes"
226 227 audio_possible_drivers="$audio_possible_drivers fmod"
... ... @@ -231,6 +232,7 @@ esac
231 232 if [ "$bsd" = "yes" ] ; then
232 233 if [ "$darwin" != "yes" ] ; then
233 234 make="gmake"
  235 + usb="bsd"
234 236 fi
235 237 bsd_user="yes"
236 238 fi
... ... @@ -1365,6 +1367,19 @@ fi
1365 1367  
1366 1368 echo "#define CONFIG_UNAME_RELEASE \"$uname_release\"" >> $config_h
1367 1369  
  1370 +# USB host support
  1371 +case "$usb" in
  1372 +linux)
  1373 + echo "HOST_USB=linux" >> $config_mak
  1374 +;;
  1375 +bsd)
  1376 + echo "HOST_USB=bsd" >> $config_mak
  1377 +;;
  1378 +*)
  1379 + echo "HOST_USB=stub" >> $config_mak
  1380 +;;
  1381 +esac
  1382 +
1368 1383 tools=
1369 1384 if test `expr "$target_list" : ".*softmmu.*"` != 0 ; then
1370 1385 tools="qemu-img\$(EXESUF) $tools"
... ...
usb-bsd.c 0 → 100644
  1 +/*
  2 + * BSD host USB redirector
  3 + *
  4 + * Copyright (c) 2006 Lonnie Mendez
  5 + * Portions of code and concepts borrowed from
  6 + * usb-linux.c and libusb's bsd.c and are copyright their respective owners.
  7 + *
  8 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  9 + * of this software and associated documentation files (the "Software"), to deal
  10 + * in the Software without restriction, including without limitation the rights
  11 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 + * copies of the Software, and to permit persons to whom the Software is
  13 + * furnished to do so, subject to the following conditions:
  14 + *
  15 + * The above copyright notice and this permission notice shall be included in
  16 + * all copies or substantial portions of the Software.
  17 + *
  18 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 + * THE SOFTWARE.
  25 + */
  26 +
  27 +#include "qemu-common.h"
  28 +#include "console.h"
  29 +#include "hw/usb.h"
  30 +
  31 +/* usb.h declares these */
  32 +#undef USB_SPEED_HIGH
  33 +#undef USB_SPEED_FULL
  34 +#undef USB_SPEED_LOW
  35 +
  36 +#include <sys/ioctl.h>
  37 +#include <dev/usb/usb.h>
  38 +#include <signal.h>
  39 +
  40 +/* This value has maximum potential at 16.
  41 + * You should also set hw.usb.debug to gain
  42 + * more detailed view.
  43 + */
  44 +//#define DEBUG
  45 +#define UGEN_DEBUG_LEVEL 0
  46 +
  47 +
  48 +typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
  49 + int vendor_id, int product_id,
  50 + const char *product_name, int speed);
  51 +static int usb_host_find_device(int *pbus_num, int *paddr,
  52 + const char *devname);
  53 +
  54 +typedef struct USBHostDevice {
  55 + USBDevice dev;
  56 + int ep_fd[USB_MAX_ENDPOINTS];
  57 + int devfd;
  58 + char devpath[32];
  59 +} USBHostDevice;
  60 +
  61 +
  62 +static int ensure_ep_open(USBHostDevice *dev, int ep, int mode)
  63 +{
  64 + char buf[32];
  65 + int fd;
  66 +
  67 + /* Get the address for this endpoint */
  68 + ep = UE_GET_ADDR(ep);
  69 +
  70 + if (dev->ep_fd[ep] < 0) {
  71 +#if __FreeBSD__
  72 + snprintf(buf, sizeof(buf) - 1, "%s.%d", dev->devpath, ep);
  73 +#else
  74 + snprintf(buf, sizeof(buf) - 1, "%s.%02d", dev->devpath, ep);
  75 +#endif
  76 + /* Try to open it O_RDWR first for those devices which have in and out
  77 + * endpoints with the same address (eg 0x02 and 0x82)
  78 + */
  79 + fd = open(buf, O_RDWR);
  80 + if (fd < 0 && errno == ENXIO)
  81 + fd = open(buf, mode);
  82 + if (fd < 0) {
  83 +#ifdef DEBUG
  84 + printf("ensure_ep_open: failed to open device endpoint %s: %s\n",
  85 + buf, strerror(errno));
  86 +#endif
  87 + }
  88 + dev->ep_fd[ep] = fd;
  89 + }
  90 +
  91 + return dev->ep_fd[ep];
  92 +}
  93 +
  94 +static void ensure_eps_closed(USBHostDevice *dev)
  95 +{
  96 + int epnum = 1;
  97 +
  98 + if (!dev)
  99 + return;
  100 +
  101 + while (epnum < USB_MAX_ENDPOINTS) {
  102 + if (dev->ep_fd[epnum] >= 0) {
  103 + close(dev->ep_fd[epnum]);
  104 + dev->ep_fd[epnum] = -1;
  105 + }
  106 + epnum++;
  107 + }
  108 +}
  109 +
  110 +static void usb_host_handle_reset(USBDevice *dev)
  111 +{
  112 +#if 0
  113 + USBHostDevice *s = (USBHostDevice *)dev;
  114 +#endif
  115 +}
  116 +
  117 +/* XXX:
  118 + * -check device states against transfer requests
  119 + * and return appropriate response
  120 + */
  121 +static int usb_host_handle_control(USBDevice *dev,
  122 + int request,
  123 + int value,
  124 + int index,
  125 + int length,
  126 + uint8_t *data)
  127 +{
  128 + USBHostDevice *s = (USBHostDevice *)dev;
  129 + struct usb_ctl_request req;
  130 + struct usb_alt_interface aiface;
  131 + int ret, timeout = 50;
  132 +
  133 + if ((request >> 8) == UT_WRITE_DEVICE &&
  134 + (request & 0xff) == UR_SET_ADDRESS) {
  135 +
  136 + /* specific SET_ADDRESS support */
  137 + dev->addr = value;
  138 + return 0;
  139 + } else if ((request >> 8) == UT_WRITE_DEVICE &&
  140 + (request & 0xff) == UR_SET_CONFIG) {
  141 +
  142 + ensure_eps_closed(s); /* can't do this without all eps closed */
  143 +
  144 + ret = ioctl(s->devfd, USB_SET_CONFIG, &value);
  145 + if (ret < 0) {
  146 +#ifdef DEBUG
  147 + printf("handle_control: failed to set configuration - %s\n",
  148 + strerror(errno));
  149 +#endif
  150 + return USB_RET_STALL;
  151 + }
  152 +
  153 + return 0;
  154 + } else if ((request >> 8) == UT_WRITE_INTERFACE &&
  155 + (request & 0xff) == UR_SET_INTERFACE) {
  156 +
  157 + aiface.uai_interface_index = index;
  158 + aiface.uai_alt_no = value;
  159 +
  160 + ensure_eps_closed(s); /* can't do this without all eps closed */
  161 + ret = ioctl(s->devfd, USB_SET_ALTINTERFACE, &aiface);
  162 + if (ret < 0) {
  163 +#ifdef DEBUG
  164 + printf("handle_control: failed to set alternate interface - %s\n",
  165 + strerror(errno));
  166 +#endif
  167 + return USB_RET_STALL;
  168 + }
  169 +
  170 + return 0;
  171 + } else {
  172 + req.ucr_request.bmRequestType = request >> 8;
  173 + req.ucr_request.bRequest = request & 0xff;
  174 + USETW(req.ucr_request.wValue, value);
  175 + USETW(req.ucr_request.wIndex, index);
  176 + USETW(req.ucr_request.wLength, length);
  177 + req.ucr_data = data;
  178 + req.ucr_flags = USBD_SHORT_XFER_OK;
  179 +
  180 + ret = ioctl(s->devfd, USB_SET_TIMEOUT, &timeout);
  181 +#if (__NetBSD__ || __OpenBSD__)
  182 + if (ret < 0 && errno != EINVAL) {
  183 +#else
  184 + if (ret < 0) {
  185 +#endif
  186 +#ifdef DEBUG
  187 + printf("handle_control: setting timeout failed - %s\n",
  188 + strerror(errno));
  189 +#endif
  190 + }
  191 +
  192 + ret = ioctl(s->devfd, USB_DO_REQUEST, &req);
  193 + /* ugen returns EIO for usbd_do_request_ no matter what
  194 + * happens with the transfer */
  195 + if (ret < 0) {
  196 +#ifdef DEBUG
  197 + printf("handle_control: error after request - %s\n",
  198 + strerror(errno));
  199 +#endif
  200 + return USB_RET_NAK; // STALL
  201 + } else {
  202 + return req.ucr_actlen;
  203 + }
  204 + }
  205 +}
  206 +
  207 +static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
  208 +{
  209 + USBHostDevice *s = (USBHostDevice *)dev;
  210 + int ret, fd, mode;
  211 + int one = 1, shortpacket = 0, timeout = 50;
  212 + sigset_t new_mask, old_mask;
  213 + uint8_t devep = p->devep;
  214 +
  215 + /* protect data transfers from SIGALRM signal */
  216 + sigemptyset(&new_mask);
  217 + sigaddset(&new_mask, SIGALRM);
  218 + sigprocmask(SIG_BLOCK, &new_mask, &old_mask);
  219 +
  220 + if (p->pid == USB_TOKEN_IN) {
  221 + devep |= 0x80;
  222 + mode = O_RDONLY;
  223 + shortpacket = 1;
  224 + } else {
  225 + mode = O_WRONLY;
  226 + }
  227 +
  228 + fd = ensure_ep_open(s, devep, mode);
  229 + if (fd < 0) {
  230 + sigprocmask(SIG_SETMASK, &old_mask, NULL);
  231 + return USB_RET_NODEV;
  232 + }
  233 +
  234 + if (ioctl(fd, USB_SET_TIMEOUT, &timeout) < 0) {
  235 +#ifdef DEBUG
  236 + printf("handle_data: failed to set timeout - %s\n",
  237 + strerror(errno));
  238 +#endif
  239 + }
  240 +
  241 + if (shortpacket) {
  242 + if (ioctl(fd, USB_SET_SHORT_XFER, &one) < 0) {
  243 +#ifdef DEBUG
  244 + printf("handle_data: failed to set short xfer mode - %s\n",
  245 + strerror(errno));
  246 +#endif
  247 + sigprocmask(SIG_SETMASK, &old_mask, NULL);
  248 + }
  249 + }
  250 +
  251 + if (p->pid == USB_TOKEN_IN)
  252 + ret = read(fd, p->data, p->len);
  253 + else
  254 + ret = write(fd, p->data, p->len);
  255 +
  256 + sigprocmask(SIG_SETMASK, &old_mask, NULL);
  257 +
  258 + if (ret < 0) {
  259 +#ifdef DEBUG
  260 + printf("handle_data: error after %s data - %s\n",
  261 + pid == USB_TOKEN_IN ? "reading" : "writing", strerror(errno));
  262 +#endif
  263 + switch(errno) {
  264 + case ETIMEDOUT:
  265 + case EINTR:
  266 + return USB_RET_NAK;
  267 + default:
  268 + return USB_RET_STALL;
  269 + }
  270 + } else {
  271 + return ret;
  272 + }
  273 +}
  274 +
  275 +static void usb_host_handle_destroy(USBDevice *opaque)
  276 +{
  277 + USBHostDevice *s = (USBHostDevice *)opaque;
  278 + int i;
  279 +
  280 + for (i = 0; i < USB_MAX_ENDPOINTS; i++)
  281 + if (s->ep_fd[i] >= 0)
  282 + close(s->ep_fd[i]);
  283 +
  284 + if (s->devfd < 0)
  285 + return;
  286 +
  287 + close(s->devfd);
  288 +
  289 + qemu_free(s);
  290 +}
  291 +
  292 +USBDevice *usb_host_device_open(const char *devname)
  293 +{
  294 + struct usb_device_info bus_info, dev_info;
  295 + USBHostDevice *dev;
  296 + char ctlpath[PATH_MAX + 1];
  297 + char buspath[PATH_MAX + 1];
  298 + int bfd, dfd, bus, address, i;
  299 + int ugendebug = UGEN_DEBUG_LEVEL;
  300 +
  301 + if (usb_host_find_device(&bus, &address, devname) < 0)
  302 + return NULL;
  303 +
  304 + snprintf(buspath, PATH_MAX, "/dev/usb%d", bus);
  305 +
  306 + bfd = open(buspath, O_RDWR);
  307 + if (bfd < 0) {
  308 +#ifdef DEBUG
  309 + printf("usb_host_device_open: failed to open usb bus - %s\n",
  310 + strerror(errno));
  311 +#endif
  312 + return NULL;
  313 + }
  314 +
  315 + bus_info.udi_addr = address;
  316 + if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0) {
  317 +#ifdef DEBUG
  318 + printf("usb_host_device_open: failed to grab bus information - %s\n",
  319 + strerror(errno));
  320 +#endif
  321 + return NULL;
  322 + }
  323 +
  324 +#if __FreeBSD__
  325 + snprintf(ctlpath, PATH_MAX, "/dev/%s", bus_info.udi_devnames[0]);
  326 +#else
  327 + snprintf(ctlpath, PATH_MAX, "/dev/%s.00", bus_info.udi_devnames[0]);
  328 +#endif
  329 +
  330 + dfd = open(ctlpath, O_RDWR);
  331 + if (dfd < 0) {
  332 + dfd = open(ctlpath, O_RDONLY);
  333 + if (dfd < 0) {
  334 +#ifdef DEBUG
  335 + printf("usb_host_device_open: failed to open usb device %s - %s\n",
  336 + ctlpath, strerror(errno));
  337 +#endif
  338 + }
  339 + }
  340 +
  341 + if (dfd >= 0) {
  342 + dev = qemu_mallocz(sizeof(USBHostDevice));
  343 + if (!dev)
  344 + goto fail;
  345 + dev->devfd = dfd;
  346 +
  347 + if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0) {
  348 +#ifdef DEBUG
  349 + printf("usb_host_device_open: failed to grab device info - %s\n",
  350 + strerror(errno));
  351 +#endif
  352 + goto fail;
  353 + }
  354 +
  355 + if (dev_info.udi_speed == 1)
  356 + dev->dev.speed = USB_SPEED_LOW - 1;
  357 + else
  358 + dev->dev.speed = USB_SPEED_FULL - 1;
  359 +
  360 + dev->dev.handle_packet = usb_generic_handle_packet;
  361 +
  362 + dev->dev.handle_reset = usb_host_handle_reset;
  363 + dev->dev.handle_control = usb_host_handle_control;
  364 + dev->dev.handle_data = usb_host_handle_data;
  365 + dev->dev.handle_destroy = usb_host_handle_destroy;
  366 +
  367 + if (strncmp(dev_info.udi_product, "product", 7) != 0)
  368 + pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
  369 + dev_info.udi_product);
  370 + else
  371 + snprintf(dev->dev.devname, sizeof(dev->dev.devname),
  372 + "host:%s", devname);
  373 +
  374 + pstrcpy(dev->devpath, sizeof(dev->devpath), "/dev/");
  375 + strcat(dev->devpath, dev_info.udi_devnames[0]);
  376 +
  377 + /* Mark the endpoints as not yet open */
  378 + for (i = 0; i < USB_MAX_ENDPOINTS; i++)
  379 + dev->ep_fd[i] = -1;
  380 +
  381 + ioctl(dfd, USB_SETDEBUG, &ugendebug);
  382 +
  383 + return (USBDevice *)dev;
  384 + }
  385 +
  386 +fail:
  387 + return NULL;
  388 +}
  389 +
  390 +static int usb_host_scan(void *opaque, USBScanFunc *func)
  391 +{
  392 + struct usb_device_info bus_info;
  393 + struct usb_device_info dev_info;
  394 + uint16_t vendor_id, product_id, class_id, speed;
  395 + int bfd, dfd, bus, address;
  396 + char busbuf[20], devbuf[20], product_name[256];
  397 + int ret = 0;
  398 +
  399 + for (bus = 0; bus < 10; bus++) {
  400 +
  401 + snprintf(busbuf, sizeof(busbuf) - 1, "/dev/usb%d", bus);
  402 + bfd = open(busbuf, O_RDWR);
  403 + if (bfd < 0)
  404 + continue;
  405 +
  406 + for (address = 1; address < 127; address++) {
  407 +
  408 + bus_info.udi_addr = address;
  409 + if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0)
  410 + continue;
  411 +
  412 + /* only list devices that can be used by generic layer */
  413 + if (strncmp(bus_info.udi_devnames[0], "ugen", 4) != 0)
  414 + continue;
  415 +
  416 +#if __FreeBSD__
  417 + snprintf(devbuf, sizeof(devbuf) - 1, "/dev/%s", bus_info.udi_devnames[0]);
  418 +#else
  419 + snprintf(devbuf, sizeof(devbuf) - 1, "/dev/%s.00", bus_info.udi_devnames[0]);
  420 +#endif
  421 +
  422 + dfd = open(devbuf, O_RDONLY);
  423 + if (dfd < 0) {
  424 +#ifdef DEBUG
  425 + printf("usb_host_scan: couldn't open device %s - %s\n", devbuf,
  426 + strerror(errno));
  427 +#endif
  428 + continue;
  429 + }
  430 +
  431 + if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0)
  432 + printf("usb_host_scan: couldn't get device information for %s - %s\n",
  433 + devbuf, strerror(errno));
  434 +
  435 + // XXX: might need to fixup endianess of word values before copying over
  436 +
  437 + vendor_id = dev_info.udi_vendorNo;
  438 + product_id = dev_info.udi_productNo;
  439 + class_id = dev_info.udi_class;
  440 + speed = dev_info.udi_speed;
  441 +
  442 + if (strncmp(dev_info.udi_product, "product", 7) != 0)
  443 + pstrcpy(product_name, sizeof(product_name),
  444 + dev_info.udi_product);
  445 + else
  446 + product_name[0] = '\0';
  447 +
  448 + ret = func(opaque, bus, address, class_id, vendor_id,
  449 + product_id, product_name, speed);
  450 +
  451 + close(dfd);
  452 +
  453 + if (ret)
  454 + goto the_end;
  455 + }
  456 +
  457 + close(bfd);
  458 + }
  459 +
  460 +the_end:
  461 + return ret;
  462 +}
  463 +
  464 +typedef struct FindDeviceState {
  465 + int vendor_id;
  466 + int product_id;
  467 + int bus_num;
  468 + int addr;
  469 +} FindDeviceState;
  470 +
  471 +static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
  472 + int class_id,
  473 + int vendor_id, int product_id,
  474 + const char *product_name, int speed)
  475 +{
  476 + FindDeviceState *s = opaque;
  477 + if (vendor_id == s->vendor_id &&
  478 + product_id == s->product_id) {
  479 + s->bus_num = bus_num;
  480 + s->addr = addr;
  481 + return 1;
  482 + } else {
  483 + return 0;
  484 + }
  485 +}
  486 +
  487 +
  488 +/* the syntax is :
  489 + 'bus.addr' (decimal numbers) or
  490 + 'vendor_id:product_id' (hexa numbers) */
  491 +static int usb_host_find_device(int *pbus_num, int *paddr,
  492 + const char *devname)
  493 +{
  494 + const char *p;
  495 + int ret;
  496 + FindDeviceState fs;
  497 +
  498 + p = strchr(devname, '.');
  499 + if (p) {
  500 + *pbus_num = strtoul(devname, NULL, 0);
  501 + *paddr = strtoul(p + 1, NULL, 0);
  502 + return 0;
  503 + }
  504 + p = strchr(devname, ':');
  505 + if (p) {
  506 + fs.vendor_id = strtoul(devname, NULL, 16);
  507 + fs.product_id = strtoul(p + 1, NULL, 16);
  508 + ret = usb_host_scan(&fs, usb_host_find_device_scan);
  509 + if (ret) {
  510 + *pbus_num = fs.bus_num;
  511 + *paddr = fs.addr;
  512 + return 0;
  513 + }
  514 + }
  515 + return -1;
  516 +}
  517 +
  518 +/**********************/
  519 +/* USB host device info */
  520 +
  521 +struct usb_class_info {
  522 + int class;
  523 + const char *class_name;
  524 +};
  525 +
  526 +static const struct usb_class_info usb_class_info[] = {
  527 + { USB_CLASS_AUDIO, "Audio"},
  528 + { USB_CLASS_COMM, "Communication"},
  529 + { USB_CLASS_HID, "HID"},
  530 + { USB_CLASS_HUB, "Hub" },
  531 + { USB_CLASS_PHYSICAL, "Physical" },
  532 + { USB_CLASS_PRINTER, "Printer" },
  533 + { USB_CLASS_MASS_STORAGE, "Storage" },
  534 + { USB_CLASS_CDC_DATA, "Data" },
  535 + { USB_CLASS_APP_SPEC, "Application Specific" },
  536 + { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
  537 + { USB_CLASS_STILL_IMAGE, "Still Image" },
  538 + { USB_CLASS_CSCID, "Smart Card" },
  539 + { USB_CLASS_CONTENT_SEC, "Content Security" },
  540 + { -1, NULL }
  541 +};
  542 +
  543 +static const char *usb_class_str(uint8_t class)
  544 +{
  545 + const struct usb_class_info *p;
  546 + for (p = usb_class_info; p->class != -1; p++) {
  547 + if (p->class == class)
  548 + break;
  549 + }
  550 + return p->class_name;
  551 +}
  552 +
  553 +void usb_info_device(int bus_num, int addr, int class_id,
  554 + int vendor_id, int product_id,
  555 + const char *product_name,
  556 + int speed)
  557 +{
  558 + const char *class_str, *speed_str;
  559 +
  560 + switch(speed) {
  561 + case USB_SPEED_LOW:
  562 + speed_str = "1.5";
  563 + break;
  564 + case USB_SPEED_FULL:
  565 + speed_str = "12";
  566 + break;
  567 + case USB_SPEED_HIGH:
  568 + speed_str = "480";
  569 + break;
  570 + default:
  571 + speed_str = "?";
  572 + break;
  573 + }
  574 +
  575 + term_printf(" Device %d.%d, speed %s Mb/s\n",
  576 + bus_num, addr, speed_str);
  577 + class_str = usb_class_str(class_id);
  578 + if (class_str)
  579 + term_printf(" %s:", class_str);
  580 + else
  581 + term_printf(" Class %02x:", class_id);
  582 + term_printf(" USB device %04x:%04x", vendor_id, product_id);
  583 + if (product_name[0] != '\0')
  584 + term_printf(", %s", product_name);
  585 + term_printf("\n");
  586 +}
  587 +
  588 +static int usb_host_info_device(void *opaque, int bus_num, int addr,
  589 + int class_id,
  590 + int vendor_id, int product_id,
  591 + const char *product_name,
  592 + int speed)
  593 +{
  594 + usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
  595 + product_name, speed);
  596 + return 0;
  597 +}
  598 +
  599 +void usb_host_info(void)
  600 +{
  601 + usb_host_scan(NULL, usb_host_info_device);
  602 +}
  603 +
  604 +/* XXX add this */
  605 +int usb_host_device_close(const char *devname)
  606 +{
  607 + return 0;
  608 +}
... ...
usb-linux.c
... ... @@ -34,7 +34,6 @@
34 34 #include "qemu-timer.h"
35 35 #include "console.h"
36 36  
37   -#if defined(__linux__)
38 37 #include <dirent.h>
39 38 #include <sys/ioctl.h>
40 39 #include <signal.h>
... ... @@ -1697,25 +1696,3 @@ void usb_host_info(void)
1697 1696 term_printf(" Device %s.%s ID %s:%s\n", bus, addr, vid, pid);
1698 1697 }
1699 1698 }
1700   -
1701   -#else
1702   -
1703   -#include "hw/usb.h"
1704   -
1705   -void usb_host_info(void)
1706   -{
1707   - term_printf("USB host devices not supported\n");
1708   -}
1709   -
1710   -/* XXX: modify configure to compile the right host driver */
1711   -USBDevice *usb_host_device_open(const char *devname)
1712   -{
1713   - return NULL;
1714   -}
1715   -
1716   -int usb_host_device_close(const char *devname)
1717   -{
1718   - return 0;
1719   -}
1720   -
1721   -#endif
... ...
usb-stub.c 0 → 100644
  1 +/*
  2 + * Stub host USB redirector
  3 + *
  4 + * Copyright (c) 2005 Fabrice Bellard
  5 + *
  6 + * Copyright (c) 2008 Max Krasnyansky
  7 + * Support for host device auto connect & disconnect
  8 + * Major rewrite to support fully async operation
  9 + *
  10 + * Copyright 2008 TJ <linux@tjworld.net>
  11 + * Added flexible support for /dev/bus/usb /sys/bus/usb/devices in addition
  12 + * to the legacy /proc/bus/usb USB device discovery and handling
  13 + *
  14 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  15 + * of this software and associated documentation files (the "Software"), to deal
  16 + * in the Software without restriction, including without limitation the rights
  17 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18 + * copies of the Software, and to permit persons to whom the Software is
  19 + * furnished to do so, subject to the following conditions:
  20 + *
  21 + * The above copyright notice and this permission notice shall be included in
  22 + * all copies or substantial portions of the Software.
  23 + *
  24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  27 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  30 + * THE SOFTWARE.
  31 + */
  32 +
  33 +#include "hw/usb.h"
  34 +
  35 +void usb_host_info(void)
  36 +{
  37 + term_printf("USB host devices not supported\n");
  38 +}
  39 +
  40 +/* XXX: modify configure to compile the right host driver */
  41 +USBDevice *usb_host_device_open(const char *devname)
  42 +{
  43 + return NULL;
  44 +}
  45 +
  46 +int usb_host_device_close(const char *devname)
  47 +{
  48 + return 0;
  49 +}
... ...