From owner-svn-soc-all@FreeBSD.ORG Mon Sep 23 18:31:20 2013 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id D0C3A2B1 for ; Mon, 23 Sep 2013 18:31:20 +0000 (UTC) (envelope-from syuu@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id BC83A2094 for ; Mon, 23 Sep 2013 18:31:20 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r8NIVKeX069079 for ; Mon, 23 Sep 2013 18:31:20 GMT (envelope-from syuu@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r8NIVK1D069073 for svn-soc-all@FreeBSD.org; Mon, 23 Sep 2013 18:31:20 GMT (envelope-from syuu@FreeBSD.org) Date: Mon, 23 Sep 2013 18:31:20 GMT Message-Id: <201309231831.r8NIVK1D069073@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to syuu@FreeBSD.org using -f From: syuu@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r257657 - in soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb: . gpl include/hw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Sep 2013 18:31:21 -0000 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 + * + * 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 . + */ +#include +#include +#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 #include #include -#include -#include #include #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 #include #include +#include //#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 #include #include +#include +#include #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