mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 13:30:52 +00:00
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:
commit
86c7dba0d0
36
configure
vendored
36
configure
vendored
@ -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
|
||||
;;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
1449
hw/usb/host-libusb.c
Normal file
1449
hw/usb/host-libusb.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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_port_reset(uint32_t port) "port %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_disable(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_disconnect(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_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_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_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_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"
|
||||
|
Loading…
Reference in New Issue
Block a user