socsvn commit: r257657 - in soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb: . gpl include/hw

syuu at FreeBSD.org syuu at FreeBSD.org
Mon Sep 23 18:31:21 UTC 2013


Author: syuu
Date: Mon Sep 23 18:31:20 2013
New Revision: 257657
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=257657

Log:
  move timer func to core.c, host device handling fix

Added:
  soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/gpl/combined-packet.c
Modified:
  soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/core.c
  soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c
  soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/host-libusb.c
  soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/include/hw/usb.h

Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/core.c
==============================================================================
--- soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/core.c	Mon Sep 23 17:35:23 2013	(r257656)
+++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/core.c	Mon Sep 23 18:31:20 2013	(r257657)
@@ -869,3 +869,61 @@
 
     return NULL;
 }
+
+static void timer_handler(union sigval sigv)
+{
+	Timer *timer = (Timer *)sigv.sigval_ptr;
+	timer->func(timer->arg);
+}
+
+Timer *new_timer(timer_func_t func, void *arg)
+{
+	Timer *timer = (Timer *)calloc(1, sizeof(*timer));
+	if (!timer) {
+		perror("calloc");
+		exit(1);
+	}
+	timer->se.sigev_notify = SIGEV_THREAD;
+	timer->se.sigev_value.sigval_ptr = (Timer *)timer;
+	timer->se.sigev_notify_function = timer_handler;
+	timer->func = func;
+	timer->arg = arg;
+	if (timer_create(CLOCK_MONOTONIC, &timer->se, &timer->timerid)) {
+		perror("timer_create");
+		exit(1);
+	}
+	return timer;
+}
+
+void mod_timer(Timer *timer, int64_t ns)
+{
+	struct itimerspec its;
+
+	memset(&its, 0, sizeof(its));
+	its.it_value = ns_to_timerspec(ns);
+	timer_settime(timer->timerid, 0, &its, 0);
+}
+
+void del_timer(Timer *timer)
+{
+	struct itimerspec its;
+
+	memset(&its, 0, sizeof(its));
+	timer_settime(timer->timerid, 0, &its, 0);
+}
+
+int64_t get_clock_ns(void)
+{
+	struct timespec ts;
+	if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
+		perror("clock_gettime");
+		exit(1);
+	}
+	return timespec_to_ns(&ts);
+}
+
+int64_t get_ticks_per_sec(void)
+{
+	return (1000000000L);
+}
+

Added: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/gpl/combined-packet.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/gpl/combined-packet.c	Mon Sep 23 18:31:20 2013	(r257657)
@@ -0,0 +1,187 @@
+/*
+ * QEMU USB packet combining code (for input pipelining)
+ *
+ * Copyright(c) 2012 Red Hat, Inc.
+ *
+ * Red Hat Authors:
+ * Hans de Goede <hdegoede at redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or(at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdlib.h>
+#include <malloc_np.h>
+#include "hw/usb.h"
+#include "usb/gpl/iov.h"
+#include "trace.h"
+
+static void usb_combined_packet_add(USBCombinedPacket *combined, USBPacket *p)
+{
+    qemu_iovec_concat(&combined->iov, &p->iov, 0, p->iov.size);
+    QTAILQ_INSERT_TAIL(&combined->packets, p, combined_entry);
+    p->combined = combined;
+}
+
+/* Note will free combined when the last packet gets removed */
+static void usb_combined_packet_remove(USBCombinedPacket *combined,
+                                       USBPacket *p)
+{
+    assert(p->combined == combined);
+    p->combined = NULL;
+    QTAILQ_REMOVE(&combined->packets, p, combined_entry);
+    if (QTAILQ_EMPTY(&combined->packets)) {
+        free(combined);
+    }
+}
+
+/* Also handles completion of non combined packets for pipelined input eps */
+void usb_combined_input_packet_complete(USBDevice *dev, USBPacket *p)
+{
+    USBCombinedPacket *combined = p->combined;
+    USBEndpoint *ep = p->ep;
+    USBPacket *next;
+    int status, actual_length;
+    bool short_not_ok, done = false;
+
+    if (combined == NULL) {
+        usb_packet_complete_one(dev, p);
+        goto leave;
+    }
+
+    assert(combined->first == p && p == QTAILQ_FIRST(&combined->packets));
+
+    status = combined->first->status;
+    actual_length = combined->first->actual_length;
+    short_not_ok = QTAILQ_LAST(&combined->packets, packets_head)->short_not_ok;
+
+    QTAILQ_FOREACH_SAFE(p, &combined->packets, combined_entry, next) {
+        if (!done) {
+            /* Distribute data over uncombined packets */
+            if (actual_length >= p->iov.size) {
+                p->actual_length = p->iov.size;
+            } else {
+                /* Send short or error packet to complete the transfer */
+                p->actual_length = actual_length;
+                done = true;
+            }
+            /* Report status on the last packet */
+            if (done || next == NULL) {
+                p->status = status;
+            } else {
+                p->status = USB_RET_SUCCESS;
+            }
+            p->short_not_ok = short_not_ok;
+            /* Note will free combined when the last packet gets removed! */
+            usb_combined_packet_remove(combined, p);
+            usb_packet_complete_one(dev, p);
+            actual_length -= p->actual_length;
+        } else {
+            /* Remove any leftover packets from the queue */
+            p->status = USB_RET_REMOVE_FROM_QUEUE;
+            /* Note will free combined on the last packet! */
+            dev->port->ops->complete(dev->port, p);
+        }
+    }
+    /* Do not use combined here, it has been freed! */
+leave:
+    /* Check if there are packets in the queue waiting for our completion */
+    usb_ep_combine_input_packets(ep);
+}
+
+/* May only be called for combined packets! */
+void usb_combined_packet_cancel(USBDevice *dev, USBPacket *p)
+{
+    USBCombinedPacket *combined = p->combined;
+    assert(combined != NULL);
+    USBPacket *first = p->combined->first;
+
+    /* Note will free combined on the last packet! */
+    usb_combined_packet_remove(combined, p);
+    if (p == first) {
+        usb_device_cancel_packet(dev, p);
+    }
+}
+
+/*
+ * Large input transfers can get split into multiple input packets, this
+ * function recombines them, removing the short_not_ok checks which all but
+ * the last packet of such splits transfers have, thereby allowing input
+ * transfer pipelining (which we cannot do on short_not_ok transfers)
+ */
+void usb_ep_combine_input_packets(USBEndpoint *ep)
+{
+    USBPacket *p, *u, *next, *prev = NULL, *first = NULL;
+    USBPort *port = ep->dev->port;
+    int totalsize;
+
+    assert(ep->pipeline);
+    assert(ep->pid == USB_TOKEN_IN);
+
+    QTAILQ_FOREACH_SAFE(p, &ep->queue, queue, next) {
+        /* Empty the queue on a halt */
+        if (ep->halted) {
+            p->status = USB_RET_REMOVE_FROM_QUEUE;
+            port->ops->complete(port, p);
+            continue;
+        }
+
+        /* Skip packets already submitted to the device */
+        if (p->state == USB_PACKET_ASYNC) {
+            prev = p;
+            continue;
+        }
+        usb_packet_check_state(p, USB_PACKET_QUEUED);
+
+        /*
+         * If the previous (combined) packet has the short_not_ok flag set
+         * stop, as we must not submit packets to the device after a transfer
+         * ending with short_not_ok packet.
+         */
+        if (prev && prev->short_not_ok) {
+            break;
+        }
+
+        if (first) {
+            if (first->combined == NULL) {
+                USBCombinedPacket *combined = calloc(1, sizeof(USBCombinedPacket));
+
+                combined->first = first;
+                QTAILQ_INIT(&combined->packets);
+                qemu_iovec_init(&combined->iov, 2);
+                usb_combined_packet_add(combined, first);
+            }
+            usb_combined_packet_add(first->combined, p);
+        } else {
+            first = p;
+        }
+
+        /* Is this packet the last one of a (combined) transfer? */
+        totalsize = (p->combined) ? p->combined->iov.size : p->iov.size;
+        if ((p->iov.size % ep->max_packet_size) != 0 || !p->short_not_ok ||
+                next == NULL ||
+                /* Work around for Linux usbfs bulk splitting + migration */
+                (totalsize == 16348 && p->int_req)) {
+            usb_device_handle_data(ep->dev, first);
+            assert(first->status == USB_RET_ASYNC);
+            if (first->combined) {
+                QTAILQ_FOREACH(u, &first->combined->packets, combined_entry) {
+                    usb_packet_set_state(u, USB_PACKET_ASYNC);
+                }
+            } else {
+                usb_packet_set_state(first, USB_PACKET_ASYNC);
+            }
+            first = NULL;
+            prev = p;
+        }
+    }
+}

Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c
==============================================================================
--- soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c	Mon Sep 23 17:35:23 2013	(r257656)
+++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c	Mon Sep 23 18:31:20 2013	(r257657)
@@ -31,8 +31,6 @@
 #include <pthread.h>
 #include <pthread_np.h>
 #include <string.h>
-#include <time.h>
-#include <signal.h>
 #include <assert.h>
 
 #include "pci_emul.h"
@@ -180,14 +178,6 @@
     uint16_t ctrl;
 } UHCIPort;
 
-typedef void(*timer_func_t)(void*);
-typedef struct Timer {
-	timer_t timerid;
-	struct sigevent se;
-	timer_func_t func;
-	void *arg;
-} Timer;
-
 struct UHCIState {
 //    PCIDevice dev;
 //    MemoryRegion io_bar;
@@ -249,8 +239,6 @@
 static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td);
 static void uhci_process_frame(UHCIState *s);
 
-#define SECINNS (1000000000L)
-
 static int pci_dma_read(struct pci_uhci_softc *sc, uintptr_t addr, void *buf, size_t len)
 {
 	void *haddr;
@@ -280,82 +268,6 @@
 	return 0;
 }
 
-
-static int64_t timespec_to_ns(struct timespec *ts)
-{
-	return ((int64_t)(ts->tv_sec * SECINNS) + ts->tv_nsec);
-}
-
-static struct timespec ns_to_timerspec(int64_t ns)
-{
-	struct timespec ts;
-	ts.tv_sec = ns / SECINNS;
-	ts.tv_nsec = ns % SECINNS;
-//	fprintf(usblog, "%s:%d tv_sec:%lu tv_nsec:%lu\n",
-//		__func__, __LINE__, ts.tv_sec, ts.tv_nsec);
-	return ts;
-}
-
-static int64_t get_clock_ns(void)
-{
-	struct timespec ts;
-	if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
-		perror("clock_gettime");
-		exit(1);
-	}
-	return timespec_to_ns(&ts);
-}
-
-static int64_t get_ticks_per_sec(void)
-{
-	return (1000000000L);
-}
-
-void timer_handler(union sigval sigv)
-{
-	Timer *timer = (Timer *)sigv.sigval_ptr;
-	timer->func(timer->arg);
-}
-
-static Timer *new_timer(timer_func_t func, void *arg)
-{
-	Timer *timer = (Timer *)calloc(1, sizeof(*timer));
-	if (!timer) {
-		perror("calloc");
-		exit(1);
-	}
-	timer->se.sigev_notify = SIGEV_THREAD;
-	timer->se.sigev_value.sigval_ptr = (Timer *)timer;
-	timer->se.sigev_notify_function = timer_handler;
-	timer->func = func;
-	timer->arg = arg;
-//	fprintf(usblog, "%s:%d timer:%p\n", __func__, __LINE__, timer);
-	if (timer_create(CLOCK_MONOTONIC, &timer->se, &timer->timerid)) {
-		perror("timer_create");
-		exit(1);
-	}
-	return timer;
-}
-
-static void mod_timer(Timer *timer, int64_t ns)
-{
-	struct itimerspec its;
-
-//	fprintf(usblog, "%s:%d timer:%p ns:%ld\n", __func__, __LINE__, timer, ns);
-	memset(&its, 0, sizeof(its));
-	its.it_value = ns_to_timerspec(ns);
-	timer_settime(timer->timerid, 0, &its, 0);
-}
-
-static void del_timer(Timer *timer)
-{
-	struct itimerspec its;
-
-	memset(&its, 0, sizeof(its));
-	timer_settime(timer->timerid, 0, &its, 0);
-//	fprintf(usblog, "%s:%d timer:%p\n", __func__, __LINE__, timer);
-}
-
 static inline int32_t uhci_queue_token(UHCI_TD *td)
 {
     if ((td->token & (0xf << 15)) == 0) {
@@ -1702,6 +1614,8 @@
 extern void usb_serial_class_initfn(USBDeviceClass *uc, void *data);
 extern USBDevice *usb_hub_init(USBBus *bus);
 void usb_hub_class_initfn(USBDeviceClass *uc, void *data);
+extern USBDevice *usb_host_init2(USBBus *bus);
+void usb_host_class_initfn(USBDeviceClass *uc, void *data);
 static int
 pci_uhci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
 {
@@ -1772,12 +1686,17 @@
 		usb_hub_class_initfn(&dev->klass, NULL);
 		usb_qdev_init(dev);
 	}
-#endif
 	{
 		USBDevice *dev = usb_serial_init(&sc->sc_st.bus);
 		usb_serial_class_initfn(&dev->klass, NULL);
 		usb_qdev_init(dev);
 	}
+#endif
+	{
+		USBDevice *dev = usb_host_init2(&sc->sc_st.bus);
+		usb_host_class_initfn(&dev->klass, NULL);
+		usb_qdev_init(dev);
+	}
 
 	return (0);
 }

Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/host-libusb.c
==============================================================================
--- soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/host-libusb.c	Mon Sep 23 17:35:23 2013	(r257656)
+++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/host-libusb.c	Mon Sep 23 18:31:20 2013	(r257657)
@@ -37,6 +37,7 @@
 #include <libusb.h>
 #include <stdlib.h>
 #include <string.h>
+#include <pthread.h>
 
 //#include "qemu-common.h"
 //#include "monitor/monitor.h"
@@ -48,10 +49,6 @@
 /* ------------------------------------------------------------------------ */
 
 #define TYPE_USB_HOST_DEVICE "usb-host"
-#if 0
-#define USB_HOST_DEVICE(obj) \
-     OBJECT_CHECK(USBHostDevice, (obj), TYPE_USB_HOST_DEVICE)
-#endif
 #define USB_HOST_DEVICE(obj) ((struct USBHostDevice *)obj)
 
 typedef struct USBHostDevice USBHostDevice;
@@ -100,14 +97,18 @@
         bool                         claimed;
     } ifs[USB_MAX_INTERFACES];
 
+#if 0
     /* callbacks & friends */
-//    QEMUBH                           *bh_nodev;
-//    QEMUBH                           *bh_postld;
-//    Notifier                         exit;
+    QEMUBH                           *bh_nodev;
+    QEMUBH                           *bh_postld;
+    Notifier                         exit;
+#endif
 
     /* request queues */
     QTAILQ_HEAD(, USBHostRequest)    requests;
     QTAILQ_HEAD(, USBHostIsoRing)    isorings;
+
+    pthread_t poll_tid;
 };
 
 struct USBHostRequest {
@@ -152,7 +153,6 @@
 #define BULK_TIMEOUT         0        /* unlimited */
 #define INTR_TIMEOUT         0        /* unlimited */
 
-#if 0
 static const char *speed_name[] = {
     [LIBUSB_SPEED_UNKNOWN] = "?",
     [LIBUSB_SPEED_LOW]     = "1.5",
@@ -160,7 +160,6 @@
     [LIBUSB_SPEED_HIGH]    = "480",
     [LIBUSB_SPEED_SUPER]   = "5000",
 };
-#endif
 
 static const unsigned int speed_map[] = {
     [LIBUSB_SPEED_LOW]     = USB_SPEED_LOW,
@@ -197,6 +196,8 @@
 
 static libusb_context *ctx;
 static uint32_t loglevel;
+static struct pollfd fds[1024];
+static int fds_idx = 0;
 
 static void usb_host_handle_fd(void *opaque)
 {
@@ -206,19 +207,36 @@
 
 static void usb_host_add_fd(int fd, short events, void *user_data)
 {
-/*
-    qemu_set_fd_handler(fd,
-                        (events & POLLIN)  ? usb_host_handle_fd : NULL,
-                        (events & POLLOUT) ? usb_host_handle_fd : NULL,
-                        ctx);
-*/
+    fds[fds_idx].fd = fd;
+    fds[fds_idx].events = events;
+    fds_idx++;
 }
 
 static void usb_host_del_fd(int fd, void *user_data)
 {
-/*
-    qemu_set_fd_handler(fd, NULL, NULL, NULL);
-*/
+    int i, j = 0;
+    struct pollfd temp[1024];
+
+    memset(temp, 0, sizeof(temp));
+    for (i = 0; i < fds_idx; i++) {
+        if (fds[i].fd == fd)
+            continue;
+        temp[j] = fds[i];
+        j++;
+    }
+    memcpy(fds, temp, sizeof(fds));
+    fds_idx--;
+}
+
+static void *
+usb_host_poll_thread(void *param)
+{
+    struct USBHostDevice *s = (USBHostDevice *)param;
+    while (s->dh) {
+        poll(fds, fds_idx - 1, -1);
+        usb_host_handle_fd(NULL);
+    }
+    return NULL;
 }
 
 static int usb_host_init(void)
@@ -439,8 +457,8 @@
 
     QTAILQ_REMOVE(&xfer->ring->inflight, xfer, next);
     if (QTAILQ_EMPTY(&xfer->ring->inflight)) {
-//        USBHostDevice *s = xfer->ring->host;
-//        trace_usb_host_iso_stop(s->bus_num, s->addr, xfer->ring->ep->nr);
+        USBHostDevice *s = xfer->ring->host;
+        trace_usb_host_iso_stop(s->bus_num, s->addr, xfer->ring->ep->nr);
     }
     if (xfer->ring->ep->pid == USB_TOKEN_IN) {
         QTAILQ_INSERT_TAIL(&xfer->ring->copy, xfer, next);
@@ -722,14 +740,12 @@
 
 static void usb_host_ep_update(USBHostDevice *s)
 {
-#if 0
     static const char *tname[] = {
         [USB_ENDPOINT_XFER_CONTROL] = "control",
         [USB_ENDPOINT_XFER_ISOC]    = "isoc",
         [USB_ENDPOINT_XFER_BULK]    = "bulk",
         [USB_ENDPOINT_XFER_INT]     = "int",
     };
-#endif
     USBDevice *udev = USB_DEVICE(s);
     struct libusb_config_descriptor *conf;
     const struct libusb_interface_descriptor *intf;
@@ -771,9 +787,9 @@
                 return;
             }
 
-//            trace_usb_host_parse_endpoint(s->bus_num, s->addr, ep,
-//                                          (devep & USB_DIR_IN) ? "in" : "out",
-//                                          tname[type], true);
+            trace_usb_host_parse_endpoint(s->bus_num, s->addr, ep,
+                                          (devep & USB_DIR_IN) ? "in" : "out",
+                                          tname[type], true);
             usb_ep_set_max_packet_size(udev, pid, ep,
                                        endp->wMaxPacketSize);
             usb_ep_set_type(udev, pid, ep, type);
@@ -831,6 +847,8 @@
         goto fail;
     }
 
+    pthread_create(&s->poll_tid, NULL, usb_host_poll_thread, (void *)s);
+
     trace_usb_host_open_success(bus_num, addr);
     return 0;
 
@@ -895,6 +913,7 @@
     }
     qemu_bh_schedule(s->bh_nodev);
 */
+    usb_host_nodev_bh(s);
 }
 
 /*
@@ -909,7 +928,7 @@
 }
 */
 
-static int usb_host_initfn(USBDevice *udev)
+int usb_host_initfn(USBDevice *udev)
 {
     USBHostDevice *s = USB_HOST_DEVICE(udev);
 
@@ -1321,14 +1340,15 @@
 
 static int usb_host_post_load(void *opaque, int version_id)
 {
-/*
     USBHostDevice *dev = opaque;
 
+/*
     if (!dev->bh_postld) {
         dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev);
     }
     qemu_bh_schedule(dev->bh_postld);
 */
+    usb_host_post_load_bh(dev);
     return 0;
 }
 
@@ -1359,12 +1379,10 @@
                     USB_HOST_OPT_PIPELINE, true),
     DEFINE_PROP_END_OF_LIST(),
 };
+#endif
 
-static void usb_host_class_initfn(ObjectClass *klass, void *data)
+void usb_host_class_initfn(USBDeviceClass *uc, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
-
     uc->init           = usb_host_initfn;
     uc->product_desc   = "USB Host Device";
     uc->cancel_packet  = usb_host_cancel_packet;
@@ -1373,10 +1391,13 @@
     uc->handle_reset   = usb_host_handle_reset;
     uc->handle_destroy = usb_host_handle_destroy;
     uc->flush_ep_queue = usb_host_flush_ep_queue;
+#if 0
     dc->vmsd = &vmstate_usb_host;
     dc->props = usb_host_dev_properties;
+#endif
 }
 
+#if 0
 static TypeInfo usb_host_dev_info = {
     .name          = TYPE_USB_HOST_DEVICE,
     .parent        = TYPE_USB_DEVICE,
@@ -1394,8 +1415,8 @@
 
 /* ------------------------------------------------------------------------ */
 
+static Timer *usb_auto_timer = NULL;
 #if 0
-static QEMUTimer *usb_auto_timer;
 static VMChangeStateEntry *usb_vmstate;
 
 static void usb_host_vm_state(void *unused, int running, RunState state)
@@ -1420,6 +1441,7 @@
     }
 
 //    if (runstate_is_running()) {
+    {
         n = libusb_get_device_list(ctx, &devs);
         for (i = 0; i < n; i++) {
             if (libusb_get_device_descriptor(devs[i], &ddesc) != 0) {
@@ -1468,7 +1490,7 @@
                 }
                 break;
             }
-//        }
+        }
         libusb_free_device_list(devs, 1);
 
         QTAILQ_FOREACH(s, &hostdevs, next) {
@@ -1484,35 +1506,32 @@
             s->seen = 0;
         }
 
-#if 0
         if (unconnected == 0) {
             /* nothing to watch */
             if (usb_auto_timer) {
-                qemu_del_timer(usb_auto_timer);
+                del_timer(usb_auto_timer);
                 trace_usb_host_auto_scan_disabled();
             }
             return;
         }
-#endif
     }
 
 #if 0
     if (!usb_vmstate) {
         usb_vmstate = qemu_add_vm_change_state_handler(usb_host_vm_state, NULL);
     }
+#endif
     if (!usb_auto_timer) {
-        usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
+        usb_auto_timer = new_timer(usb_host_auto_check, NULL);
         if (!usb_auto_timer) {
             return;
         }
         trace_usb_host_auto_scan_enabled();
     }
-    qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
-#endif
+    mod_timer(usb_auto_timer, 2000);
 }
 
-#if 0
-void usb_host_info(Monitor *mon, const QDict *qdict)
+void usb_host_info(void)
 {
     libusb_device **devs;
     struct libusb_device_descriptor ddesc;
@@ -1532,13 +1551,13 @@
             continue;
         }
         usb_host_get_port(devs[i], port, sizeof(port));
-        monitor_printf(mon, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
+        fprintf(usblog, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
                        libusb_get_bus_number(devs[i]),
                        libusb_get_device_address(devs[i]),
                        port,
                        speed_name[libusb_get_device_speed(devs[i])]);
-        monitor_printf(mon, "    Class %02x:", ddesc.bDeviceClass);
-        monitor_printf(mon, " USB device %04x:%04x",
+        fprintf(usblog, "    Class %02x:", ddesc.bDeviceClass);
+        fprintf(usblog, " USB device %04x:%04x",
                        ddesc.idVendor, ddesc.idProduct);
         if (ddesc.iProduct) {
             libusb_device_handle *handle;
@@ -1548,11 +1567,35 @@
                                                    ddesc.iProduct,
                                                    name, sizeof(name));
                 libusb_close(handle);
-                monitor_printf(mon, ", %s", name);
+                fprintf(usblog, ", %s", name);
             }
         }
-        monitor_printf(mon, "\n");
+        fprintf(usblog, "\n");
     }
     libusb_free_device_list(devs, 1);
 }
-#endif
+
+USBDevice *usb_host_init2(USBBus *bus)
+{
+    USBDevice *dev;
+    USBHostDevice *s;
+    char label[32];
+    static int index;
+
+    snprintf(label, sizeof(label), "usbhost%d", index++);
+
+    dev = usb_create(bus, "usb-host", sizeof(USBHostDevice));
+    if (!dev) {
+        return NULL;
+    }
+    s = (USBHostDevice *)dev;
+    s->iso_urb_count = 4;
+    s->iso_urb_frames = 32;
+    s->bootindex = -1;
+    s->match.vendor_id = 0x17ef;
+    s->match.product_id = 0x6009;
+    memset(fds, 0, sizeof(fds));
+    usb_host_info();
+
+    return dev;
+}

Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/include/hw/usb.h
==============================================================================
--- soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/include/hw/usb.h	Mon Sep 23 17:35:23 2013	(r257656)
+++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/include/hw/usb.h	Mon Sep 23 18:31:20 2013	(r257657)
@@ -31,6 +31,8 @@
 #include <stdbool.h>
 #include <assert.h>
 #include <stddef.h>
+#include <signal.h>
+#include <time.h>
 #include "qemu/queue.h"
 
 #define container_of(p, stype, field) ((stype *)(((uint8_t *)(p)) - offsetof(stype, field)))
@@ -619,6 +621,35 @@
 void qemu_iovec_init(IOVector *qiov, int alloc_hint);
 void qemu_iovec_reset(IOVector *qiov);
 void qemu_iovec_add(IOVector *qiov, void *base, size_t len);
+void qemu_iovec_concat(IOVector *dst,
+                       IOVector *src, size_t soffset, size_t sbytes);
 void qemu_iovec_destroy(IOVector *qiov);
 
+#define SECINNS (1000000000L)
+
+static inline int64_t timespec_to_ns(struct timespec *ts)
+{
+	return ((int64_t)(ts->tv_sec * SECINNS) + ts->tv_nsec);
+}
+
+static inline struct timespec ns_to_timerspec(int64_t ns)
+{
+	struct timespec ts;
+	ts.tv_sec = ns / SECINNS;
+	ts.tv_nsec = ns % SECINNS;
+	return ts;
+}
+
+typedef void(*timer_func_t)(void*);
+typedef struct Timer {
+	timer_t timerid;
+	struct sigevent se;
+	timer_func_t func;
+	void *arg;
+} Timer;
+Timer *new_timer(timer_func_t func, void *arg);
+void mod_timer(Timer *timer, int64_t ns);
+void del_timer(Timer *timer);
+int64_t get_clock_ns(void);
+int64_t get_ticks_per_sec(void);
 #endif


More information about the svn-soc-all mailing list