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: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori 2013-04-16 10:28:58 -05:00
commit 86c7dba0d0
6 changed files with 1551 additions and 41 deletions

36
configure vendored
View file

@ -226,6 +226,7 @@ trace_file="trace"
spice="" spice=""
rbd="" rbd=""
smartcard_nss="" smartcard_nss=""
libusb=""
usb_redir="" usb_redir=""
glx="" glx=""
zlib="yes" zlib="yes"
@ -890,6 +891,10 @@ for opt do
;; ;;
--enable-smartcard-nss) smartcard_nss="yes" --enable-smartcard-nss) smartcard_nss="yes"
;; ;;
--disable-libusb) libusb="no"
;;
--enable-libusb) libusb="yes"
;;
--disable-usb-redir) usb_redir="no" --disable-usb-redir) usb_redir="no"
;; ;;
--enable-usb-redir) usb_redir="yes" --enable-usb-redir) usb_redir="yes"
@ -1175,6 +1180,8 @@ echo " --disable-libiscsi disable iscsi support"
echo " --enable-libiscsi enable iscsi support" echo " --enable-libiscsi enable iscsi support"
echo " --disable-smartcard-nss disable smartcard nss support" echo " --disable-smartcard-nss disable smartcard nss support"
echo " --enable-smartcard-nss enable 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 " --disable-usb-redir disable usb network redirection support"
echo " --enable-usb-redir enable usb network redirection support" echo " --enable-usb-redir enable usb network redirection support"
echo " --disable-guest-agent disable building of the QEMU Guest Agent" echo " --disable-guest-agent disable building of the QEMU Guest Agent"
@ -3005,6 +3012,23 @@ EOF
fi fi
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 # check for usbredirparser for usb network redirection support
if test "$usb_redir" != "no" ; then if test "$usb_redir" != "no" ; then
if $pkg_config --atleast-version=0.6 libusbredirparser-0.5 >/dev/null 2>&1 ; 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 "rbd support $rbd"
echo "xfsctl support $xfs" echo "xfsctl support $xfs"
echo "nss used $smartcard_nss" echo "nss used $smartcard_nss"
echo "libusb $libusb"
echo "usb net redir $usb_redir" echo "usb net redir $usb_redir"
echo "GLX support $glx" echo "GLX support $glx"
echo "libiscsi support $libiscsi" echo "libiscsi support $libiscsi"
@ -3823,6 +3848,10 @@ if test "$smartcard_nss" = "yes" ; then
echo "libcacard_cflags=$libcacard_cflags" >> $config_host_mak echo "libcacard_cflags=$libcacard_cflags" >> $config_host_mak
fi fi
if test "$libusb" = "yes" ; then
echo "CONFIG_USB_LIBUSB=y" >> $config_host_mak
fi
if test "$usb_redir" = "yes" ; then if test "$usb_redir" = "yes" ; then
echo "CONFIG_USB_REDIR=y" >> $config_host_mak echo "CONFIG_USB_REDIR=y" >> $config_host_mak
fi fi
@ -3907,6 +3936,13 @@ linux)
bsd) bsd)
echo "HOST_USB=bsd" >> $config_host_mak 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 echo "HOST_USB=stub" >> $config_host_mak
;; ;;

View file

@ -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) static int usb_serial_can_read(void *opaque)
{ {
USBSerialState *s = 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_reset = usb_serial_handle_reset;
uc->handle_control = usb_serial_handle_control; uc->handle_control = usb_serial_handle_control;
uc->handle_data = usb_serial_handle_data; uc->handle_data = usb_serial_handle_data;
uc->handle_destroy = usb_serial_handle_destroy;
dc->vmsd = &vmstate_usb_serial; dc->vmsd = &vmstate_usb_serial;
dc->props = serial_properties; 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_reset = usb_serial_handle_reset;
uc->handle_control = usb_serial_handle_control; uc->handle_control = usb_serial_handle_control;
uc->handle_data = usb_serial_handle_data; uc->handle_data = usb_serial_handle_data;
uc->handle_destroy = usb_serial_handle_destroy;
dc->vmsd = &vmstate_usb_serial; dc->vmsd = &vmstate_usb_serial;
dc->props = braille_properties; dc->props = braille_properties;
} }

View file

@ -408,7 +408,6 @@ typedef struct XHCISlot {
bool enabled; bool enabled;
dma_addr_t ctx; dma_addr_t ctx;
USBPort *uport; USBPort *uport;
unsigned int devaddr;
XHCIEPContext * eps[31]; XHCIEPContext * eps[31];
} XHCISlot; } XHCISlot;
@ -452,7 +451,6 @@ struct XHCIState {
MemoryRegion mem_oper; MemoryRegion mem_oper;
MemoryRegion mem_runtime; MemoryRegion mem_runtime;
MemoryRegion mem_doorbell; MemoryRegion mem_doorbell;
unsigned int devaddr;
/* properties */ /* properties */
uint32_t numports_2; 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; slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;
} else { } else {
USBPacket p; USBPacket p;
slot->devaddr = xhci->devaddr++; uint8_t buf[1];
slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slot->devaddr;
DPRINTF("xhci: device address is %d\n", slot->devaddr); slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slotid;
usb_device_reset(dev); usb_device_reset(dev);
memset(&p, 0, sizeof(p));
usb_packet_addbuf(&p, buf, sizeof(buf));
usb_packet_setup(&p, USB_TOKEN_OUT, usb_packet_setup(&p, USB_TOKEN_OUT,
usb_ep_get(dev, USB_TOKEN_OUT, 0), 0, usb_ep_get(dev, USB_TOKEN_OUT, 0), 0,
0, false, false); 0, false, false);
usb_device_handle_control(dev, &p, usb_device_handle_control(dev, &p,
DeviceOutRequest | USB_REQ_SET_ADDRESS, DeviceOutRequest | USB_REQ_SET_ADDRESS,
slot->devaddr, 0, 0, NULL); slotid, 0, 0, NULL);
assert(p.status != USB_RET_ASYNC); assert(p.status != USB_RET_ASYNC);
} }
@ -2526,7 +2526,6 @@ static void xhci_process_commands(XHCIState *xhci)
} }
break; break;
case CR_SET_TR_DEQUEUE: case CR_SET_TR_DEQUEUE:
fprintf(stderr, "%s: CR_SET_TR_DEQUEUE\n", __func__);
slotid = xhci_get_slot(xhci, &event, &trb); slotid = xhci_get_slot(xhci, &event, &trb);
if (slotid) { if (slotid) {
unsigned int epid = (trb.control >> TRB_CR_EPID_SHIFT) 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) { if ((port->portsc & bits) == bits) {
return; return;
} }
trace_usb_xhci_port_notify(port->portnr, bits);
port->portsc |= bits; port->portsc |= bits;
if (!xhci_running(port->xhci)) { if (!xhci_running(port->xhci)) {
return; return;
@ -2674,7 +2674,6 @@ static void xhci_reset(DeviceState *dev)
xhci->dcbaap_low = 0; xhci->dcbaap_low = 0;
xhci->dcbaap_high = 0; xhci->dcbaap_high = 0;
xhci->config = 0; xhci->config = 0;
xhci->devaddr = 2;
for (i = 0; i < xhci->numslots; i++) { for (i = 0; i < xhci->numslots; i++) {
xhci_disable_slot(xhci, i+1); xhci_disable_slot(xhci, i+1);
@ -2799,29 +2798,56 @@ static void xhci_port_write(void *ptr, hwaddr reg,
uint64_t val, unsigned size) uint64_t val, unsigned size)
{ {
XHCIPort *port = ptr; XHCIPort *port = ptr;
uint32_t portsc; uint32_t portsc, notify;
trace_usb_xhci_port_write(port->portnr, reg, val); trace_usb_xhci_port_write(port->portnr, reg, val);
switch (reg) { switch (reg) {
case 0x00: /* PORTSC */ case 0x00: /* PORTSC */
/* write-1-to-start bits */
if (val & PORTSC_PR) {
xhci_port_reset(port);
break;
}
portsc = port->portsc; portsc = port->portsc;
notify = 0;
/* write-1-to-clear bits*/ /* write-1-to-clear bits*/
portsc &= ~(val & (PORTSC_CSC|PORTSC_PEC|PORTSC_WRC|PORTSC_OCC| portsc &= ~(val & (PORTSC_CSC|PORTSC_PEC|PORTSC_WRC|PORTSC_OCC|
PORTSC_PRC|PORTSC_PLC|PORTSC_CEC)); PORTSC_PRC|PORTSC_PLC|PORTSC_CEC));
if (val & PORTSC_LWS) { if (val & PORTSC_LWS) {
/* overwrite PLS only when LWS=1 */ /* overwrite PLS only when LWS=1 */
uint32_t pls = get_field(val, PORTSC_PLS); uint32_t old_pls = get_field(port->portsc, PORTSC_PLS);
set_field(&portsc, pls, PORTSC_PLS); uint32_t new_pls = get_field(val, PORTSC_PLS);
trace_usb_xhci_port_link(port->portnr, 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 */ /* read/write bits */
portsc &= ~(PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE); portsc &= ~(PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE);
portsc |= (val & (PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE)); portsc |= (val & (PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE));
port->portsc = portsc; port->portsc = portsc;
/* write-1-to-start bits */ if (notify) {
if (val & PORTSC_PR) { xhci_port_notify(port, notify);
xhci_port_reset(port);
} }
break; break;
case 0x04: /* PORTPMSC */ 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 = { static const MemoryRegionOps xhci_cap_ops = {
.read = xhci_cap_read, .read = xhci_cap_read,
.write = xhci_cap_write,
.valid.min_access_size = 1, .valid.min_access_size = 1,
.valid.max_access_size = 4, .valid.max_access_size = 4,
.impl.min_access_size = 4, .impl.min_access_size = 4,
@ -3178,20 +3211,6 @@ static USBPortOps xhci_uport_ops = {
.child_detach = xhci_child_detach, .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) static int xhci_find_epid(USBEndpoint *ep)
{ {
if (ep->nr == 0) { if (ep->nr == 0) {
@ -3211,7 +3230,7 @@ static void xhci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep,
int slotid; int slotid;
DPRINTF("%s\n", __func__); DPRINTF("%s\n", __func__);
slotid = xhci_find_slotid(xhci, ep->dev); slotid = ep->dev->addr;
if (slotid == 0 || !xhci->slots[slotid-1].enabled) { if (slotid == 0 || !xhci->slots[slotid-1].enabled) {
DPRINTF("%s: oops, no slot for dev %d\n", __func__, ep->dev->addr); DPRINTF("%s: oops, no slot for dev %d\n", __func__, ep->dev->addr);
return; return;

1449
hw/usb/host-libusb.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -45,6 +45,12 @@
#include "hw/usb/desc.h" #include "hw/usb/desc.h"
#include "hw/usb/host.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 */ /* We redefine it to avoid version problems */
struct usb_ctrltransfer { struct usb_ctrltransfer {
uint8_t bRequestType; uint8_t bRequestType;
@ -1487,7 +1493,7 @@ static int usb_host_initfn(USBDevice *dev)
} }
static const VMStateDescription vmstate_usb_host = { static const VMStateDescription vmstate_usb_host = {
.name = "usb-host", .name = DEVNAME,
.version_id = 1, .version_id = 1,
.minimum_version_id = 1, .minimum_version_id = 1,
.post_load = usb_host_post_load, .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 = { static const TypeInfo usb_host_dev_info = {
.name = "usb-host", .name = DEVNAME,
.parent = TYPE_USB_DEVICE, .parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHostDevice), .instance_size = sizeof(USBHostDevice),
.class_init = usb_host_class_initfn, .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); qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
} }
#ifndef CONFIG_USB_LIBUSB
/**********************/ /**********************/
/* USB host device info */ /* 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); bus, addr, f->port ? f->port : "*", vid, pid);
} }
} }
#endif

View file

@ -362,6 +362,7 @@ usb_xhci_queue_event(uint32_t vector, uint32_t idx, const char *trb, const char
usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x"
usb_xhci_port_reset(uint32_t port) "port %d" usb_xhci_port_reset(uint32_t port) "port %d"
usb_xhci_port_link(uint32_t port, uint32_t pls) "port %d, pls %d" usb_xhci_port_link(uint32_t port, uint32_t pls) "port %d, pls %d"
usb_xhci_port_notify(uint32_t port, uint32_t pls) "port %d, bits %x"
usb_xhci_slot_enable(uint32_t slotid) "slotid %d" usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
usb_xhci_slot_disable(uint32_t slotid) "slotid %d" usb_xhci_slot_disable(uint32_t slotid) "slotid %d"
usb_xhci_slot_address(uint32_t slotid) "slotid %d" usb_xhci_slot_address(uint32_t slotid) "slotid %d"
@ -424,11 +425,15 @@ usb_host_open_success(int bus, int addr) "dev %d:%d"
usb_host_open_failure(int bus, int addr) "dev %d:%d" usb_host_open_failure(int bus, int addr) "dev %d:%d"
usb_host_disconnect(int bus, int addr) "dev %d:%d" usb_host_disconnect(int bus, int addr) "dev %d:%d"
usb_host_close(int bus, int addr) "dev %d:%d" usb_host_close(int bus, int addr) "dev %d:%d"
usb_host_attach_kernel(int bus, int addr, int interface) "dev %d:%d, if %d"
usb_host_detach_kernel(int bus, int addr, int interface) "dev %d:%d, if %d"
usb_host_set_address(int bus, int addr, int config) "dev %d:%d, address %d" usb_host_set_address(int bus, int addr, int config) "dev %d:%d, address %d"
usb_host_set_config(int bus, int addr, int config) "dev %d:%d, config %d" usb_host_set_config(int bus, int addr, int config) "dev %d:%d, config %d"
usb_host_set_interface(int bus, int addr, int interface, int alt) "dev %d:%d, interface %d, alt %d" usb_host_set_interface(int bus, int addr, int interface, int alt) "dev %d:%d, interface %d, alt %d"
usb_host_claim_interfaces(int bus, int addr, int config, int nif) "dev %d:%d, config %d, nif %d" usb_host_claim_interfaces(int bus, int addr, int config, int nif) "dev %d:%d, config %d, nif %d"
usb_host_claim_interface(int bus, int addr, int config, int interface) "dev %d:%d, config %d, if %d"
usb_host_release_interfaces(int bus, int addr) "dev %d:%d" usb_host_release_interfaces(int bus, int addr) "dev %d:%d"
usb_host_release_interface(int bus, int addr, int interface) "dev %d:%d, if %d"
usb_host_req_control(int bus, int addr, void *p, int req, int value, int index) "dev %d:%d, packet %p, req 0x%x, value %d, index %d" usb_host_req_control(int bus, int addr, void *p, int req, int value, int index) "dev %d:%d, packet %p, req 0x%x, value %d, index %d"
usb_host_req_data(int bus, int addr, void *p, int in, int ep, int size) "dev %d:%d, packet %p, in %d, ep %d, size %d" usb_host_req_data(int bus, int addr, void *p, int in, int ep, int size) "dev %d:%d, packet %p, in %d, ep %d, size %d"
usb_host_req_complete(int bus, int addr, void *p, int status, int length) "dev %d:%d, packet %p, status %d, length %d" usb_host_req_complete(int bus, int addr, void *p, int status, int length) "dev %d:%d, packet %p, status %d, length %d"