Commit 86c7dba0 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'kraxel/usb.80' into staging



# By Gerd Hoffmann (6) and Hans de Goede (1)
# Via Gerd Hoffmann
* kraxel/usb.80:
  use libusb for usb-host
  xhci: fix address device
  xhci: use slotid as device address
  xhci: fix portsc writes
  xhci: add xhci_cap_write
  xhci: remove leftover debug printf
  usb-serial: Remove double call to qemu_chr_add_handlers( NULL )

Message-id: 1366107190-30853-1-git-send-email-kraxel@redhat.com
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parents 6f8111a1 2b2325ff
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -226,6 +226,7 @@ trace_file="trace"
spice=""
rbd=""
smartcard_nss=""
libusb=""
usb_redir=""
glx=""
zlib="yes"
@@ -890,6 +891,10 @@ for opt do
  ;;
  --enable-smartcard-nss) smartcard_nss="yes"
  ;;
  --disable-libusb) libusb="no"
  ;;
  --enable-libusb) libusb="yes"
  ;;
  --disable-usb-redir) usb_redir="no"
  ;;
  --enable-usb-redir) usb_redir="yes"
@@ -1175,6 +1180,8 @@ echo " --disable-libiscsi disable iscsi support"
echo "  --enable-libiscsi        enable iscsi support"
echo "  --disable-smartcard-nss  disable smartcard nss support"
echo "  --enable-smartcard-nss   enable smartcard nss support"
echo "  --disable-libusb         disable libusb (for usb passthrough)"
echo "  --enable-libusb          enable libusb (for usb passthrough)"
echo "  --disable-usb-redir      disable usb network redirection support"
echo "  --enable-usb-redir       enable usb network redirection support"
echo "  --disable-guest-agent    disable building of the QEMU Guest Agent"
@@ -3005,6 +3012,23 @@ EOF
    fi
fi

# check for libusb
if test "$libusb" != "no" ; then
    if $pkg_config libusb-1.0 >/dev/null 2>&1 ; then
        libusb="yes"
	usb="libusb"
        libusb_cflags=$($pkg_config --cflags libusb-1.0 2>/dev/null)
        libusb_libs=$($pkg_config --libs libusb-1.0 2>/dev/null)
        QEMU_CFLAGS="$QEMU_CFLAGS $libusb_cflags"
        libs_softmmu="$libs_softmmu $libusb_libs"
    else
        if test "$libusb" = "yes"; then
            feature_not_found "libusb"
        fi
        libusb="no"
    fi
fi

# check for usbredirparser for usb network redirection support
if test "$usb_redir" != "no" ; then
    if $pkg_config --atleast-version=0.6 libusbredirparser-0.5 >/dev/null 2>&1 ; then
@@ -3516,6 +3540,7 @@ echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
echo "rbd support       $rbd"
echo "xfsctl support    $xfs"
echo "nss used          $smartcard_nss"
echo "libusb            $libusb"
echo "usb net redir     $usb_redir"
echo "GLX support       $glx"
echo "libiscsi support  $libiscsi"
@@ -3823,6 +3848,10 @@ if test "$smartcard_nss" = "yes" ; then
  echo "libcacard_cflags=$libcacard_cflags" >> $config_host_mak
fi

if test "$libusb" = "yes" ; then
  echo "CONFIG_USB_LIBUSB=y" >> $config_host_mak
fi

if test "$usb_redir" = "yes" ; then
  echo "CONFIG_USB_REDIR=y" >> $config_host_mak
fi
@@ -3907,6 +3936,13 @@ linux)
bsd)
  echo "HOST_USB=bsd" >> $config_host_mak
;;
libusb)
  if test "$linux" = "yes"; then
    echo "HOST_USB=libusb linux legacy" >> $config_host_mak
  else
    echo "HOST_USB=libusb legacy" >> $config_host_mak
  fi
;;
*)
  echo "HOST_USB=stub" >> $config_host_mak
;;
+0 −9
Original line number Diff line number Diff line
@@ -410,13 +410,6 @@ static void usb_serial_handle_data(USBDevice *dev, USBPacket *p)
    }
}

static void usb_serial_handle_destroy(USBDevice *dev)
{
    USBSerialState *s = (USBSerialState *)dev;

    qemu_chr_add_handlers(s->cs, NULL, NULL, NULL, NULL);
}

static int usb_serial_can_read(void *opaque)
{
    USBSerialState *s = opaque;
@@ -595,7 +588,6 @@ static void usb_serial_class_initfn(ObjectClass *klass, void *data)
    uc->handle_reset   = usb_serial_handle_reset;
    uc->handle_control = usb_serial_handle_control;
    uc->handle_data    = usb_serial_handle_data;
    uc->handle_destroy = usb_serial_handle_destroy;
    dc->vmsd = &vmstate_usb_serial;
    dc->props = serial_properties;
}
@@ -623,7 +615,6 @@ static void usb_braille_class_initfn(ObjectClass *klass, void *data)
    uc->handle_reset   = usb_serial_handle_reset;
    uc->handle_control = usb_serial_handle_control;
    uc->handle_data    = usb_serial_handle_data;
    uc->handle_destroy = usb_serial_handle_destroy;
    dc->vmsd = &vmstate_usb_serial;
    dc->props = braille_properties;
}
+49 −30
Original line number Diff line number Diff line
@@ -408,7 +408,6 @@ typedef struct XHCISlot {
    bool enabled;
    dma_addr_t ctx;
    USBPort *uport;
    unsigned int devaddr;
    XHCIEPContext * eps[31];
} XHCISlot;

@@ -452,7 +451,6 @@ struct XHCIState {
    MemoryRegion mem_oper;
    MemoryRegion mem_runtime;
    MemoryRegion mem_doorbell;
    unsigned int devaddr;

    /* properties */
    uint32_t numports_2;
@@ -2141,16 +2139,18 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
        slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;
    } else {
        USBPacket p;
        slot->devaddr = xhci->devaddr++;
        slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slot->devaddr;
        DPRINTF("xhci: device address is %d\n", slot->devaddr);
        uint8_t buf[1];

        slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slotid;
        usb_device_reset(dev);
        memset(&p, 0, sizeof(p));
        usb_packet_addbuf(&p, buf, sizeof(buf));
        usb_packet_setup(&p, USB_TOKEN_OUT,
                         usb_ep_get(dev, USB_TOKEN_OUT, 0), 0,
                         0, false, false);
        usb_device_handle_control(dev, &p,
                                  DeviceOutRequest | USB_REQ_SET_ADDRESS,
                                  slot->devaddr, 0, 0, NULL);
                                  slotid, 0, 0, NULL);
        assert(p.status != USB_RET_ASYNC);
    }

@@ -2526,7 +2526,6 @@ static void xhci_process_commands(XHCIState *xhci)
            }
            break;
        case CR_SET_TR_DEQUEUE:
            fprintf(stderr, "%s: CR_SET_TR_DEQUEUE\n", __func__);
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                unsigned int epid = (trb.control >> TRB_CR_EPID_SHIFT)
@@ -2593,6 +2592,7 @@ static void xhci_port_notify(XHCIPort *port, uint32_t bits)
    if ((port->portsc & bits) == bits) {
        return;
    }
    trace_usb_xhci_port_notify(port->portnr, bits);
    port->portsc |= bits;
    if (!xhci_running(port->xhci)) {
        return;
@@ -2674,7 +2674,6 @@ static void xhci_reset(DeviceState *dev)
    xhci->dcbaap_low = 0;
    xhci->dcbaap_high = 0;
    xhci->config = 0;
    xhci->devaddr = 2;

    for (i = 0; i < xhci->numslots; i++) {
        xhci_disable_slot(xhci, i+1);
@@ -2799,29 +2798,56 @@ static void xhci_port_write(void *ptr, hwaddr reg,
                            uint64_t val, unsigned size)
{
    XHCIPort *port = ptr;
    uint32_t portsc;
    uint32_t portsc, notify;

    trace_usb_xhci_port_write(port->portnr, reg, val);

    switch (reg) {
    case 0x00: /* PORTSC */
        /* write-1-to-start bits */
        if (val & PORTSC_PR) {
            xhci_port_reset(port);
            break;
        }

        portsc = port->portsc;
        notify = 0;
        /* write-1-to-clear bits*/
        portsc &= ~(val & (PORTSC_CSC|PORTSC_PEC|PORTSC_WRC|PORTSC_OCC|
                           PORTSC_PRC|PORTSC_PLC|PORTSC_CEC));
        if (val & PORTSC_LWS) {
            /* overwrite PLS only when LWS=1 */
            uint32_t pls = get_field(val, PORTSC_PLS);
            set_field(&portsc, pls, PORTSC_PLS);
            trace_usb_xhci_port_link(port->portnr, pls);
            uint32_t old_pls = get_field(port->portsc, PORTSC_PLS);
            uint32_t new_pls = get_field(val, PORTSC_PLS);
            switch (new_pls) {
            case PLS_U0:
                if (old_pls != PLS_U0) {
                    set_field(&portsc, new_pls, PORTSC_PLS);
                    trace_usb_xhci_port_link(port->portnr, new_pls);
                    notify = PORTSC_PLC;
                }
                break;
            case PLS_U3:
                if (old_pls < PLS_U3) {
                    set_field(&portsc, new_pls, PORTSC_PLS);
                    trace_usb_xhci_port_link(port->portnr, new_pls);
                }
                break;
            case PLS_RESUME:
                /* windows does this for some reason, don't spam stderr */
                break;
            default:
                fprintf(stderr, "%s: ignore pls write (old %d, new %d)\n",
                        __func__, old_pls, new_pls);
                break;
            }
        }
        /* read/write bits */
        portsc &= ~(PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE);
        portsc |= (val & (PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE));
        port->portsc = portsc;
        /* write-1-to-start bits */
        if (val & PORTSC_PR) {
            xhci_port_reset(port);
        if (notify) {
            xhci_port_notify(port, notify);
        }
        break;
    case 0x04: /* PORTPMSC */
@@ -3080,8 +3106,15 @@ static void xhci_doorbell_write(void *ptr, hwaddr reg,
    }
}

static void xhci_cap_write(void *opaque, hwaddr addr, uint64_t val,
                           unsigned width)
{
    /* nothing */
}

static const MemoryRegionOps xhci_cap_ops = {
    .read = xhci_cap_read,
    .write = xhci_cap_write,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .impl.min_access_size = 4,
@@ -3178,20 +3211,6 @@ static USBPortOps xhci_uport_ops = {
    .child_detach = xhci_child_detach,
};

static int xhci_find_slotid(XHCIState *xhci, USBDevice *dev)
{
    XHCISlot *slot;
    int slotid;

    for (slotid = 1; slotid <= xhci->numslots; slotid++) {
        slot = &xhci->slots[slotid-1];
        if (slot->devaddr == dev->addr) {
            return slotid;
        }
    }
    return 0;
}

static int xhci_find_epid(USBEndpoint *ep)
{
    if (ep->nr == 0) {
@@ -3211,7 +3230,7 @@ static void xhci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep,
    int slotid;

    DPRINTF("%s\n", __func__);
    slotid = xhci_find_slotid(xhci, ep->dev);
    slotid = ep->dev->addr;
    if (slotid == 0 || !xhci->slots[slotid-1].enabled) {
        DPRINTF("%s: oops, no slot for dev %d\n", __func__, ep->dev->addr);
        return;

hw/usb/host-libusb.c

0 → 100644
+1449 −0

File added.

Preview size limit exceeded, changes collapsed.

+12 −2
Original line number Diff line number Diff line
@@ -45,6 +45,12 @@
#include "hw/usb/desc.h"
#include "hw/usb/host.h"

#ifdef CONFIG_USB_LIBUSB
# define DEVNAME "usb-host-linux"
#else
# define DEVNAME "usb-host"
#endif

/* We redefine it to avoid version problems */
struct usb_ctrltransfer {
    uint8_t  bRequestType;
@@ -1487,7 +1493,7 @@ static int usb_host_initfn(USBDevice *dev)
}

static const VMStateDescription vmstate_usb_host = {
    .name = "usb-host",
    .name = DEVNAME,
    .version_id = 1,
    .minimum_version_id = 1,
    .post_load = usb_host_post_load,
@@ -1527,7 +1533,7 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
}

static const TypeInfo usb_host_dev_info = {
    .name          = "usb-host",
    .name          = DEVNAME,
    .parent        = TYPE_USB_DEVICE,
    .instance_size = sizeof(USBHostDevice),
    .class_init    = usb_host_class_initfn,
@@ -1767,6 +1773,8 @@ static void usb_host_auto_check(void *unused)
    qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
}

#ifndef CONFIG_USB_LIBUSB

/**********************/
/* USB host device info */

@@ -1898,3 +1906,5 @@ void usb_host_info(Monitor *mon, const QDict *qdict)
                       bus, addr, f->port ? f->port : "*", vid, pid);
    }
}

#endif
Loading