summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--Makefile.objs47
-rw-r--r--Makefile.target6
-rw-r--r--Makefile.user1
-rw-r--r--bsd-user/main.c2
-rwxr-xr-xconfigure4
-rw-r--r--darwin-user/main.c3
-rw-r--r--hw/alpha_sys.h1
-rw-r--r--hw/kvm/clock.c2
-rw-r--r--hw/mips_fulong2e.c7
-rw-r--r--hw/mips_malta.c3
-rw-r--r--hw/pc_piix.c4
-rw-r--r--hw/ppc_newworld.c3
-rw-r--r--hw/ppc_oldworld.c3
-rw-r--r--hw/ppc_prep.c3
-rw-r--r--hw/realview.c3
-rw-r--r--hw/usb-ohci.h9
-rw-r--r--hw/usb-uhci.h10
-rw-r--r--hw/usb.h1
-rw-r--r--hw/usb/bus.c (renamed from hw/usb-bus.c)6
-rw-r--r--hw/usb/core.c (renamed from hw/usb.c)39
-rw-r--r--hw/usb/desc.c (renamed from hw/usb-desc.c)4
-rw-r--r--hw/usb/desc.h (renamed from hw/usb-desc.h)0
-rw-r--r--hw/usb/dev-audio.c (renamed from hw/usb-audio.c)8
-rw-r--r--hw/usb/dev-bluetooth.c (renamed from hw/usb-bt.c)6
-rw-r--r--hw/usb/dev-hid.c (renamed from hw/usb-hid.c)8
-rw-r--r--hw/usb/dev-hub.c (renamed from hw/usb-hub.c)4
-rw-r--r--hw/usb/dev-network.c (renamed from hw/usb-net.c)4
-rw-r--r--hw/usb/dev-serial.c (renamed from hw/usb-serial.c)4
-rw-r--r--hw/usb/dev-smartcard-reader.c (renamed from hw/usb-ccid.c)4
-rw-r--r--hw/usb/dev-storage.c (renamed from hw/usb-msd.c)12
-rw-r--r--hw/usb/dev-wacom.c (renamed from hw/usb-wacom.c)6
-rw-r--r--hw/usb/hcd-ehci.c (renamed from hw/usb-ehci.c)12
-rw-r--r--hw/usb/hcd-musb.c (renamed from hw/usb-musb.c)6
-rw-r--r--hw/usb/hcd-ohci.c (renamed from hw/usb-ohci.c)33
-rw-r--r--hw/usb/hcd-uhci.c (renamed from hw/usb-uhci.c)156
-rw-r--r--hw/usb/hcd-xhci.c (renamed from hw/usb-xhci.c)10
-rw-r--r--hw/usb/host-bsd.c (renamed from usb-bsd.c)0
-rw-r--r--hw/usb/host-linux.c (renamed from usb-linux.c)0
-rw-r--r--hw/usb/host-stub.c (renamed from usb-stub.c)0
-rw-r--r--hw/usb/libhw.c (renamed from hw/usb-libhw.c)2
-rw-r--r--hw/usb/redirect.c (renamed from usb-redir.c)0
-rw-r--r--hw/versatilepb.c3
-rw-r--r--linux-user/main.c2
-rw-r--r--qemu-user.c37
-rw-r--r--trace-events40
-rw-r--r--vl.c4
47 files changed, 298 insertions, 230 deletions
diff --git a/Makefile b/Makefile
index 408065e0b1..1bc3cb049a 100644
--- a/Makefile
+++ b/Makefile
@@ -98,12 +98,12 @@ ifneq ($(wildcard config-host.mak),)
 include $(SRC_PATH)/Makefile.objs
 endif
 
-$(common-obj-y): $(GENERATED_HEADERS)
+$(universal-obj-y) $(common-obj-y): $(GENERATED_HEADERS)
 subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o
 
-$(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(common-obj-y) subdir-libdis
+$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) subdir-libdis
 
-$(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(trace-obj-y) subdir-libdis-user subdir-libuser
+$(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(universal-obj-y) $(trace-obj-y) subdir-libdis-user subdir-libuser
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
 romsubdir-%:
diff --git a/Makefile.objs b/Makefile.objs
index 5f0b3f7136..f71ea17d07 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -1,9 +1,22 @@
 #######################################################################
+# Target-independent parts used in system and user emulation
+universal-obj-y =
+
+#######################################################################
 # QObject
 qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
 qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
 qobject-obj-y += qerror.o error.o qemu-error.o
 
+universal-obj-y += $(qobject-obj-y)
+
+#######################################################################
+# QOM
+include $(SRC_PATH)/qom/Makefile
+qom-obj-y = $(addprefix qom/, $(qom-y))
+
+universal-obj-y += $(qom-obj-y)
+
 #######################################################################
 # oslib-obj-y is code depending on the OS (win32 vs posix)
 oslib-obj-y = osdep.o
@@ -80,7 +93,6 @@ fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y))
 
 common-obj-y = $(block-obj-y) blockdev.o
 common-obj-y += $(net-obj-y)
-common-obj-y += $(qobject-obj-y)
 common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX))
 common-obj-y += readline.o console.o cursor.o
 common-obj-y += $(oslib-obj-y)
@@ -107,13 +119,15 @@ common-obj-y += eeprom93xx.o
 common-obj-y += scsi-disk.o cdrom.o
 common-obj-y += scsi-generic.o scsi-bus.o
 common-obj-y += hid.o
-common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
-common-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o usb-audio.o
+common-obj-y += usb/core.o usb/bus.o usb/desc.o usb/dev-hub.o
+common-obj-y += usb/host-$(HOST_USB).o
+common-obj-y += usb/dev-hid.o usb/dev-storage.o usb/dev-wacom.o
+common-obj-y += usb/dev-serial.o usb/dev-network.o usb/dev-audio.o
 common-obj-$(CONFIG_SSI) += ssi.o
 common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
 common-obj-$(CONFIG_SD) += sd.o
-common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
-common-obj-y += bt-hci-csr.o
+common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o
+common-obj-y += bt-hci-csr.o usb/dev-bluetooth.o
 common-obj-y += buffered_file.o migration.o migration-tcp.o
 common-obj-y += qemu-char.o #aio.o
 common-obj-y += msmouse.o ps2.o
@@ -128,9 +142,6 @@ common-obj-$(CONFIG_WIN32) += version.o
 
 common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o spice-qemu-char.o
 
-include $(SRC_PATH)/qom/Makefile
-common-obj-y += $(addprefix qom/, $(qom-y))
-
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
 audio-obj-$(CONFIG_OSS) += ossaudio.o
@@ -186,6 +197,8 @@ user-obj-y =
 user-obj-y += envlist.o path.o
 user-obj-y += tcg-runtime.o host-utils.o
 user-obj-y += cutils.o cache-utils.o
+user-obj-y += module.o
+user-obj-y += qemu-user.o
 user-obj-y += $(trace-obj-y)
 
 ######################################################################
@@ -194,7 +207,7 @@ user-obj-y += $(trace-obj-y)
 hw-obj-y =
 hw-obj-y += vl.o loader.o
 hw-obj-$(CONFIG_VIRTIO) += virtio-console.o
-hw-obj-y += usb-libhw.o
+hw-obj-y += usb/libhw.o
 hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 hw-obj-y += fw_cfg.o
 hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o
@@ -217,10 +230,10 @@ hw-obj-$(CONFIG_PARALLEL) += parallel.o
 hw-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
 hw-obj-$(CONFIG_PCSPK) += pcspk.o
 hw-obj-$(CONFIG_PCKBD) += pckbd.o
-hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o
-hw-obj-$(CONFIG_USB_OHCI) += usb-ohci.o
-hw-obj-$(CONFIG_USB_EHCI) += usb-ehci.o
-hw-obj-$(CONFIG_USB_XHCI) += usb-xhci.o
+hw-obj-$(CONFIG_USB_UHCI) += usb/hcd-uhci.o
+hw-obj-$(CONFIG_USB_OHCI) += usb/hcd-ohci.o
+hw-obj-$(CONFIG_USB_EHCI) += usb/hcd-ehci.o
+hw-obj-$(CONFIG_USB_XHCI) += usb/hcd-xhci.o
 hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
@@ -228,9 +241,9 @@ hw-obj-$(CONFIG_DMA) += dma.o
 hw-obj-$(CONFIG_I82374) += i82374.o
 hw-obj-$(CONFIG_HPET) += hpet.o
 hw-obj-$(CONFIG_APPLESMC) += applesmc.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+hw-obj-$(CONFIG_SMARTCARD) += usb/dev-smartcard-reader.o ccid-card-passthru.o
 hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
-hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o
+hw-obj-$(CONFIG_USB_REDIR) += usb/redirect.o
 hw-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
 
 # PPC devices
@@ -422,9 +435,11 @@ qapi-nested-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o
 qapi-nested-y += string-input-visitor.o string-output-visitor.o
 qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
 
-common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o $(qapi-obj-y)
+common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o
 common-obj-y += qmp.o hmp.o
 
+universal-obj-y += $(qapi-obj-y)
+
 ######################################################################
 # guest agent
 
diff --git a/Makefile.target b/Makefile.target
index 1bd25a89ad..eb2594188a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -136,6 +136,7 @@ obj-m68k-y += m68k-sim.o m68k-semi.o
 
 $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
 
+obj-y += $(addprefix ../, $(universal-obj-y))
 obj-y += $(addprefix ../libuser/, $(user-obj-y))
 obj-y += $(addprefix ../libdis-user/, $(libdis-y))
 obj-y += $(libobj-y)
@@ -163,6 +164,7 @@ obj-i386-y += ioport-user.o
 
 $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
 
+obj-y += $(addprefix ../, $(universal-obj-y))
 obj-y += $(addprefix ../libuser/, $(user-obj-y))
 obj-y += $(addprefix ../libdis-user/, $(libdis-y))
 obj-y += $(libobj-y)
@@ -185,6 +187,7 @@ obj-i386-y += ioport-user.o
 
 $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
 
+obj-y += $(addprefix ../, $(universal-obj-y))
 obj-y += $(addprefix ../libuser/, $(user-obj-y))
 obj-y += $(addprefix ../libdis-user/, $(libdis-y))
 obj-y += $(libobj-y)
@@ -370,7 +373,7 @@ obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \
 obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \
 		omap_gpmc.o omap_sdrc.o omap_spi.o omap_tap.o omap_l4.o
 obj-arm-y += omap_sx1.o palm.o tsc210x.o
-obj-arm-y += nseries.o blizzard.o onenand.o cbus.o tusb6010.o usb-musb.o
+obj-arm-y += nseries.o blizzard.o onenand.o cbus.o tusb6010.o usb/hcd-musb.o
 obj-arm-y += mst_fpga.o mainstone.o
 obj-arm-y += z2.o
 obj-arm-y += musicpal.o bitbang_i2c.o marvell_88w8618_audio.o
@@ -406,6 +409,7 @@ monitor.o: hmp-commands.h qmp-commands-old.h
 
 $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
 
+obj-y += $(addprefix ../, $(universal-obj-y))
 obj-y += $(addprefix ../, $(common-obj-y))
 obj-y += $(addprefix ../libdis/, $(libdis-y))
 obj-y += $(libobj-y)
diff --git a/Makefile.user b/Makefile.user
index 2b1e4d154e..b717820407 100644
--- a/Makefile.user
+++ b/Makefile.user
@@ -9,6 +9,7 @@ include $(SRC_PATH)/rules.mak
 $(call set-vpath, $(SRC_PATH))
 
 QEMU_CFLAGS+=-I..
+QEMU_CFLAGS += -I$(SRC_PATH)/include
 
 include $(SRC_PATH)/Makefile.objs
 
diff --git a/bsd-user/main.c b/bsd-user/main.c
index cc7d4a37ad..cdb0d0ac99 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -748,6 +748,8 @@ int main(int argc, char **argv)
     if (argc <= 1)
         usage();
 
+    module_call_init(MODULE_INIT_QOM);
+
     if ((envlist = envlist_create()) == NULL) {
         (void) fprintf(stderr, "Unable to allocate envlist\n");
         exit(1);
diff --git a/configure b/configure
index d7631ed247..fe4fc4fb96 100755
--- a/configure
+++ b/configure
@@ -3447,6 +3447,7 @@ mkdir -p $target_dir
 mkdir -p $target_dir/fpu
 mkdir -p $target_dir/tcg
 mkdir -p $target_dir/ide
+mkdir -p $target_dir/usb
 mkdir -p $target_dir/9pfs
 mkdir -p $target_dir/kvm
 if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" -o "$target" = "arm-bsd-user" -o "$target" = "armeb-bsd-user" ; then
@@ -3863,7 +3864,7 @@ done # for target in $targets
 DIRS="tests tests/tcg tests/tcg/cris slirp audio block net pc-bios/optionrom"
 DIRS="$DIRS pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
-DIRS="$DIRS fsdev ui"
+DIRS="$DIRS fsdev ui usb"
 DIRS="$DIRS qapi qapi-generated"
 DIRS="$DIRS qga trace qom"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
@@ -3904,6 +3905,7 @@ for hwlib in 32 64; do
   d=libhw$hwlib
   mkdir -p $d
   mkdir -p $d/ide
+  mkdir -p $d/usb
   symlink $source_path/Makefile.hw $d/Makefile
   mkdir -p $d/9pfs
   echo "QEMU_CFLAGS+=-DTARGET_PHYS_ADDR_BITS=$hwlib" > $d/config.mak
diff --git a/darwin-user/main.c b/darwin-user/main.c
index 9b57c20815..e1519c7d78 100644
--- a/darwin-user/main.c
+++ b/darwin-user/main.c
@@ -28,6 +28,7 @@
 #include <sys/mman.h>
 
 #include "qemu.h"
+#include "qemu-common.h"
 
 #define DEBUG_LOGFILE "/tmp/qemu.log"
 
@@ -749,6 +750,8 @@ int main(int argc, char **argv)
     if (argc <= 1)
         usage();
 
+    module_call_init(MODULE_INIT_QOM);
+
     optind = 1;
     for(;;) {
         if (optind >= argc)
diff --git a/hw/alpha_sys.h b/hw/alpha_sys.h
index d54b18f8ed..f9506c69a7 100644
--- a/hw/alpha_sys.h
+++ b/hw/alpha_sys.h
@@ -8,7 +8,6 @@
 #include "ide.h"
 #include "net.h"
 #include "pc.h"
-#include "usb-ohci.h"
 #include "irq.h"
 
 
diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c
index 2157340326..446bd62176 100644
--- a/hw/kvm/clock.c
+++ b/hw/kvm/clock.c
@@ -121,9 +121,7 @@ void kvmclock_create(void)
 
 static void kvmclock_register_types(void)
 {
-    if (kvm_enabled()) {
     type_register_static(&kvmclock_info);
-    }
 }
 
 type_init(kvmclock_register_types)
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index e3ba9dd42d..efdfdc29ff 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -29,7 +29,6 @@
 #include "mips.h"
 #include "mips_cpudevs.h"
 #include "pci.h"
-#include "usb-uhci.h"
 #include "qemu-char.h"
 #include "sysemu.h"
 #include "audio/audio.h"
@@ -355,8 +354,10 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
     isa_bus_irqs(isa_bus, i8259);
 
     vt82c686b_ide_init(pci_bus, hd, PCI_DEVFN(FULONG2E_VIA_SLOT, 1));
-    usb_uhci_vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 2));
-    usb_uhci_vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 3));
+    pci_create_simple(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 2),
+                      "vt82c686b-usb-uhci");
+    pci_create_simple(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 3),
+                      "vt82c686b-usb-uhci");
 
     smbus = vt82c686b_pm_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 4),
                               0xeee1, NULL);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index b1563ed2a7..866699dbf0 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -33,7 +33,6 @@
 #include "mips.h"
 #include "mips_cpudevs.h"
 #include "pci.h"
-#include "usb-uhci.h"
 #include "vmware_vga.h"
 #include "qemu-char.h"
 #include "sysemu.h"
@@ -965,7 +964,7 @@ void mips_malta_init (ram_addr_t ram_size,
 
     isa_bus_irqs(isa_bus, s->i8259);
     pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
-    usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
+    pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
     smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
                           isa_get_irq(NULL, 9), NULL, 0);
     /* TODO: Populate SPD eeprom data.  */
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 6c5c40f5df..3f99f9a7c2 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -28,8 +28,6 @@
 #include "pc.h"
 #include "apic.h"
 #include "pci.h"
-#include "usb-uhci.h"
-#include "usb-ohci.h"
 #include "net.h"
 #include "boards.h"
 #include "ide.h"
@@ -284,7 +282,7 @@ static void pc_init1(MemoryRegion *system_memory,
                  floppy, idebus[0], idebus[1], rtc_state);
 
     if (pci_enabled && usb_enabled) {
-        usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
+        pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
     }
 
     if (pci_enabled && acpi_enabled) {
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 506187b182..2fec5b4d67 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -54,7 +54,6 @@
 #include "nvram.h"
 #include "pc.h"
 #include "pci.h"
-#include "usb-ohci.h"
 #include "net.h"
 #include "sysemu.h"
 #include "boards.h"
@@ -352,7 +351,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
                dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
 
     if (usb_enabled) {
-        usb_ohci_init_pci(pci_bus, -1);
+        pci_create_simple(pci_bus, -1, "pci-ohci");
     }
 
     /* U3 needs to use USB for input because Linux doesn't support via-cuda
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 9295a34f59..49c2c9795e 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -34,7 +34,6 @@
 #include "net.h"
 #include "isa.h"
 #include "pci.h"
-#include "usb-ohci.h"
 #include "boards.h"
 #include "fw_cfg.h"
 #include "escc.h"
@@ -278,7 +277,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
                dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
 
     if (usb_enabled) {
-        usb_ohci_init_pci(pci_bus, -1);
+        pci_create_simple(pci_bus, -1, "pci-ohci");
     }
 
     if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index eb43fb5849..dc9edd7bf5 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -30,7 +30,6 @@
 #include "isa.h"
 #include "pci.h"
 #include "pci_host.h"
-#include "usb-ohci.h"
 #include "ppc.h"
 #include "boards.h"
 #include "qemu-log.h"
@@ -688,7 +687,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
 #endif
 
     if (usb_enabled) {
-        usb_ohci_init_pci(pci_bus, -1);
+        pci_create_simple(pci_bus, -1, "pci-ohci");
     }
 
     m48t59 = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59);
diff --git a/hw/realview.c b/hw/realview.c
index ae1bbcdac3..50ea67cb26 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -12,7 +12,6 @@
 #include "primecell.h"
 #include "devices.h"
 #include "pci.h"
-#include "usb-ohci.h"
 #include "net.h"
 #include "sysemu.h"
 #include "boards.h"
@@ -305,7 +304,7 @@ static void realview_init(ram_addr_t ram_size,
         sysbus_connect_irq(busdev, 3, pic[51]);
         pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
         if (usb_enabled) {
-            usb_ohci_init_pci(pci_bus, -1);
+            pci_create_simple(pci_bus, -1, "pci-ohci");
         }
         n = drive_get_max_bus(IF_SCSI);
         while (n >= 0) {
diff --git a/hw/usb-ohci.h b/hw/usb-ohci.h
deleted file mode 100644
index eefcef3602..0000000000
--- a/hw/usb-ohci.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef QEMU_USB_OHCI_H
-#define QEMU_USB_OHCI_H
-
-#include "qemu-common.h"
-
-void usb_ohci_init_pci(struct PCIBus *bus, int devfn);
-
-#endif
-
diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h
deleted file mode 100644
index 3e4d3777d4..0000000000
--- a/hw/usb-uhci.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef QEMU_USB_UHCI_H
-#define QEMU_USB_UHCI_H
-
-#include "qemu-common.h"
-
-void usb_uhci_piix3_init(PCIBus *bus, int devfn);
-void usb_uhci_piix4_init(PCIBus *bus, int devfn);
-void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn);
-
-#endif
diff --git a/hw/usb.h b/hw/usb.h
index d60d03df9c..e95085f0b3 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -336,6 +336,7 @@ struct USBPacket {
 
 void usb_packet_init(USBPacket *p);
 void usb_packet_set_state(USBPacket *p, USBPacketState state);
+void usb_packet_check_state(USBPacket *p, USBPacketState expected);
 void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep);
 void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
 int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
diff --git a/hw/usb-bus.c b/hw/usb/bus.c
index 70b7ebc086..d3f835895d 100644
--- a/hw/usb-bus.c
+++ b/hw/usb/bus.c
@@ -1,6 +1,6 @@
-#include "hw.h"
-#include "usb.h"
-#include "qdev.h"
+#include "hw/hw.h"
+#include "hw/usb.h"
+#include "hw/qdev.h"
 #include "sysemu.h"
 #include "monitor.h"
 #include "trace.h"
diff --git a/hw/usb.c b/hw/usb/core.c
index 1ec2e90ef7..a4048fe3e0 100644
--- a/hw/usb.c
+++ b/hw/usb/core.c
@@ -24,7 +24,7 @@
  * THE SOFTWARE.
  */
 #include "qemu-common.h"
-#include "usb.h"
+#include "hw/usb.h"
 #include "iov.h"
 #include "trace.h"
 
@@ -378,7 +378,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
     }
     assert(dev == p->ep->dev);
     assert(dev->state == USB_STATE_DEFAULT);
-    assert(p->state == USB_PACKET_SETUP);
+    usb_packet_check_state(p, USB_PACKET_SETUP);
     assert(p->ep != NULL);
 
     if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
@@ -406,7 +406,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
     USBEndpoint *ep = p->ep;
     int ret;
 
-    assert(p->state == USB_PACKET_ASYNC);
+    usb_packet_check_state(p, USB_PACKET_ASYNC);
     assert(QTAILQ_FIRST(&ep->queue) == p);
     usb_packet_set_state(p, USB_PACKET_COMPLETE);
     QTAILQ_REMOVE(&ep->queue, p, queue);
@@ -417,7 +417,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
         if (p->state == USB_PACKET_ASYNC) {
             break;
         }
-        assert(p->state == USB_PACKET_QUEUED);
+        usb_packet_check_state(p, USB_PACKET_QUEUED);
         ret = usb_process_one(p);
         if (ret == USB_RET_ASYNC) {
             usb_packet_set_state(p, USB_PACKET_ASYNC);
@@ -450,7 +450,7 @@ void usb_packet_init(USBPacket *p)
     qemu_iovec_init(&p->iov, 1);
 }
 
-void usb_packet_set_state(USBPacket *p, USBPacketState state)
+static const char *usb_packet_state_name(USBPacketState state)
 {
     static const char *name[] = {
         [USB_PACKET_UNDEFINED] = "undef",
@@ -460,11 +460,36 @@ void usb_packet_set_state(USBPacket *p, USBPacketState state)
         [USB_PACKET_COMPLETE]  = "complete",
         [USB_PACKET_CANCELED]  = "canceled",
     };
+    if (state < ARRAY_SIZE(name)) {
+        return name[state];
+    }
+    return "INVALID";
+}
+
+void usb_packet_check_state(USBPacket *p, USBPacketState expected)
+{
+    USBDevice *dev;
+    USBBus *bus;
+
+    if (p->state == expected) {
+        return;
+    }
+    dev = p->ep->dev;
+    bus = usb_bus_from_device(dev);
+    trace_usb_packet_state_fault(bus->busnr, dev->port->path, p->ep->nr, p,
+                                 usb_packet_state_name(p->state),
+                                 usb_packet_state_name(expected));
+    assert(!"usb packet state check failed");
+}
+
+void usb_packet_set_state(USBPacket *p, USBPacketState state)
+{
     USBDevice *dev = p->ep->dev;
     USBBus *bus = usb_bus_from_device(dev);
 
-    trace_usb_packet_state_change(bus->busnr, dev->port->path, p->ep->nr,
-                                  p, name[p->state], name[state]);
+    trace_usb_packet_state_change(bus->busnr, dev->port->path, p->ep->nr, p,
+                                  usb_packet_state_name(p->state),
+                                  usb_packet_state_name(state));
     p->state = state;
 }
 
diff --git a/hw/usb-desc.c b/hw/usb/desc.c
index ccf85ade9e..9847a75b83 100644
--- a/hw/usb-desc.c
+++ b/hw/usb/desc.c
@@ -1,5 +1,5 @@
-#include "usb.h"
-#include "usb-desc.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
 #include "trace.h"
 
 /* ------------------------------------------------------------------ */
diff --git a/hw/usb-desc.h b/hw/usb/desc.h
index d6e07ea5d2..d6e07ea5d2 100644
--- a/hw/usb-desc.h
+++ b/hw/usb/desc.h
diff --git a/hw/usb-audio.c b/hw/usb/dev-audio.c
index fed136117b..426b95c82b 100644
--- a/hw/usb-audio.c
+++ b/hw/usb/dev-audio.c
@@ -30,10 +30,10 @@
  */
 
 #include "qemu-common.h"
-#include "usb.h"
-#include "usb-desc.h"
-#include "hw.h"
-#include "audiodev.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
+#include "hw/hw.h"
+#include "hw/audiodev.h"
 #include "audio/audio.h"
 
 #define USBAUDIO_VENDOR_NUM     0x46f4 /* CRC16() of "QEMU" */
diff --git a/hw/usb-bt.c b/hw/usb/dev-bluetooth.c
index 23c39ecc23..195370c24a 100644
--- a/hw/usb-bt.c
+++ b/hw/usb/dev-bluetooth.c
@@ -19,10 +19,10 @@
  */
 
 #include "qemu-common.h"
-#include "usb.h"
-#include "usb-desc.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
 #include "net.h"
-#include "bt.h"
+#include "hw/bt.h"
 
 struct USBBtState {
     USBDevice dev;
diff --git a/hw/usb-hid.c b/hw/usb/dev-hid.c
index 37bca78eca..f29544d954 100644
--- a/hw/usb-hid.c
+++ b/hw/usb/dev-hid.c
@@ -22,12 +22,12 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "hw.h"
+#include "hw/hw.h"
 #include "console.h"
-#include "usb.h"
-#include "usb-desc.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
 #include "qemu-timer.h"
-#include "hid.h"
+#include "hw/hid.h"
 
 /* HID interface requests */
 #define GET_REPORT   0xa101
diff --git a/hw/usb-hub.c b/hw/usb/dev-hub.c
index a12856e2e9..eb4e711207 100644
--- a/hw/usb-hub.c
+++ b/hw/usb/dev-hub.c
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 #include "qemu-common.h"
-#include "usb.h"
-#include "usb-desc.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
 
 //#define DEBUG
 
diff --git a/hw/usb-net.c b/hw/usb/dev-network.c
index 22b82017e3..cff55f223e 100644
--- a/hw/usb-net.c
+++ b/hw/usb/dev-network.c
@@ -24,8 +24,8 @@
  */
 
 #include "qemu-common.h"
-#include "usb.h"
-#include "usb-desc.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
 #include "net.h"
 #include "qemu-queue.h"
 #include "sysemu.h"
diff --git a/hw/usb-serial.c b/hw/usb/dev-serial.c
index 0aae379b20..8dcac8bc88 100644
--- a/hw/usb-serial.c
+++ b/hw/usb/dev-serial.c
@@ -10,8 +10,8 @@
 
 #include "qemu-common.h"
 #include "qemu-error.h"
-#include "usb.h"
-#include "usb-desc.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
 #include "qemu-char.h"
 
 //#define DEBUG_Serial
diff --git a/hw/usb-ccid.c b/hw/usb/dev-smartcard-reader.c
index ced687f288..8e66675d86 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -36,8 +36,8 @@
 
 #include "qemu-common.h"
 #include "qemu-error.h"
-#include "usb.h"
-#include "usb-desc.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
 #include "monitor.h"
 
 #include "hw/ccid.h"
diff --git a/hw/usb-msd.c b/hw/usb/dev-storage.c
index c6f08a0313..bdbe7bdd11 100644
--- a/hw/usb-msd.c
+++ b/hw/usb/dev-storage.c
@@ -10,9 +10,9 @@
 #include "qemu-common.h"
 #include "qemu-option.h"
 #include "qemu-config.h"
-#include "usb.h"
-#include "usb-desc.h"
-#include "scsi.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
+#include "hw/scsi.h"
 #include "console.h"
 #include "monitor.h"
 #include "sysemu.h"
@@ -193,9 +193,9 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p)
     int len;
 
     DPRINTF("Command status %d tag 0x%x, len %zd\n",
-            s->csw.status, s->csw.tag, p->iov.size);
+            s->csw.status, le32_to_cpu(s->csw.tag), p->iov.size);
 
-    assert(s->csw.sig == 0x53425355);
+    assert(s->csw.sig == cpu_to_le32(0x53425355));
     len = MIN(sizeof(s->csw), p->iov.size);
     usb_packet_copy(p, &s->csw, len);
     memset(&s->csw, 0, sizeof(s->csw));
@@ -233,7 +233,7 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t r
 
     s->csw.sig = cpu_to_le32(0x53425355);
     s->csw.tag = cpu_to_le32(req->tag);
-    s->csw.residue = s->residue;
+    s->csw.residue = cpu_to_le32(s->residue);
     s->csw.status = status != 0;
 
     if (s->packet) {
diff --git a/hw/usb-wacom.c b/hw/usb/dev-wacom.c
index 197e2dced5..c1cfd74403 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -25,10 +25,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "hw.h"
+#include "hw/hw.h"
 #include "console.h"
-#include "usb.h"
-#include "usb-desc.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
 
 /* Interface requests */
 #define WACOM_GET_REPORT	0x2101
diff --git a/hw/usb-ehci.c b/hw/usb/hcd-ehci.c
index df742f7f02..60f9f5bdb5 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -22,10 +22,10 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "hw.h"
+#include "hw/hw.h"
 #include "qemu-timer.h"
-#include "usb.h"
-#include "pci.h"
+#include "hw/usb.h"
+#include "hw/pci.h"
 #include "monitor.h"
 #include "trace.h"
 #include "dma.h"
@@ -419,7 +419,6 @@ struct EHCIState {
 
     USBPacket ipacket;
     QEMUSGList isgl;
-    int isoch_pause;
 
     uint64_t last_run_ns;
 };
@@ -907,7 +906,6 @@ static void ehci_reset(void *opaque)
 
     s->astate = EST_INACTIVE;
     s->pstate = EST_INACTIVE;
-    s->isoch_pause = -1;
     s->attach_poll_counter = 0;
 
     for(i = 0; i < NB_PORTS; i++) {
@@ -2150,9 +2148,7 @@ static void ehci_frame_timer(void *opaque)
 
     for (i = 0; i < frames; i++) {
         if ( !(ehci->usbsts & USBSTS_HALT)) {
-            if (ehci->isoch_pause <= 0) {
-                ehci->frindex += 8;
-            }
+            ehci->frindex += 8;
 
             if (ehci->frindex > 0x00001fff) {
                 ehci->frindex = 0;
diff --git a/hw/usb-musb.c b/hw/usb/hcd-musb.c
index 820907a9a9..fa9385ee49 100644
--- a/hw/usb-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -22,9 +22,9 @@
  */
 #include "qemu-common.h"
 #include "qemu-timer.h"
-#include "usb.h"
-#include "irq.h"
-#include "hw.h"
+#include "hw/usb.h"
+#include "hw/irq.h"
+#include "hw/hw.h"
 
 /* Common USB registers */
 #define MUSB_HDRC_FADDR		0x00	/* 8-bit */
diff --git a/hw/usb-ohci.c b/hw/usb/hcd-ohci.c
index 20aaa74250..1a1cc88b1f 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -26,13 +26,12 @@
  *  o BIOS work to boot from USB storage
 */
 
-#include "hw.h"
+#include "hw/hw.h"
 #include "qemu-timer.h"
-#include "usb.h"
-#include "pci.h"
-#include "usb-ohci.h"
-#include "sysbus.h"
-#include "qdev-addr.h"
+#include "hw/usb.h"
+#include "hw/pci.h"
+#include "hw/sysbus.h"
+#include "hw/qdev-addr.h"
 
 //#define DEBUG_OHCI
 /* Dump packet contents.  */
@@ -122,6 +121,11 @@ struct ohci_hcca {
     uint16_t frame, pad;
     uint32_t done;
 };
+#define HCCA_WRITEBACK_OFFSET   offsetof(struct ohci_hcca, frame)
+#define HCCA_WRITEBACK_SIZE     8 /* frame, pad, done */
+
+#define ED_WBACK_OFFSET offsetof(struct ohci_ed, head)
+#define ED_WBACK_SIZE   4
 
 static void ohci_bus_stop(OHCIState *ohci);
 static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev);
@@ -569,7 +573,13 @@ static inline int ohci_read_hcca(OHCIState *ohci,
 static inline int ohci_put_ed(OHCIState *ohci,
                               uint32_t addr, struct ohci_ed *ed)
 {
-    return put_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2);
+    /* ed->tail is under control of the HCD.
+     * Since just ed->head is changed by HC, just write back this
+     */
+
+    return put_dwords(ohci, addr + ED_WBACK_OFFSET,
+                      (uint32_t *)((char *)ed + ED_WBACK_OFFSET),
+                      ED_WBACK_SIZE >> 2);
 }
 
 static inline int ohci_put_td(OHCIState *ohci,
@@ -588,7 +598,9 @@ static inline int ohci_put_iso_td(OHCIState *ohci,
 static inline int ohci_put_hcca(OHCIState *ohci,
                                 uint32_t addr, struct ohci_hcca *hcca)
 {
-    cpu_physical_memory_write(addr + ohci->localmem_base, hcca, sizeof(*hcca));
+    cpu_physical_memory_write(addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET,
+                              (char *)hcca + HCCA_WRITEBACK_OFFSET,
+                              HCCA_WRITEBACK_SIZE);
     return 1;
 }
 
@@ -1815,11 +1827,6 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
     return 0;
 }
 
-void usb_ohci_init_pci(struct PCIBus *bus, int devfn)
-{
-    pci_create_simple(bus, devfn, "pci-ohci");
-}
-
 typedef struct {
     SysBusDevice busdev;
     OHCIState ohci;
diff --git a/hw/usb-uhci.c b/hw/usb/hcd-uhci.c
index 304b84b831..e55dad914c 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -25,13 +25,13 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "hw.h"
-#include "usb.h"
-#include "pci.h"
+#include "hw/hw.h"
+#include "hw/usb.h"
+#include "hw/pci.h"
 #include "qemu-timer.h"
-#include "usb-uhci.h"
 #include "iov.h"
 #include "dma.h"
+#include "trace.h"
 
 //#define DEBUG
 //#define DEBUG_DUMP_DATA
@@ -77,22 +77,13 @@
 
 #define NB_PORTS 2
 
-#ifdef DEBUG
-#define DPRINTF printf
-
-static const char *pid2str(int pid)
-{
-    switch (pid) {
-    case USB_TOKEN_SETUP: return "SETUP";
-    case USB_TOKEN_IN:    return "IN";
-    case USB_TOKEN_OUT:   return "OUT";
-    }
-    return "?";
-}
-
-#else
-#define DPRINTF(...)
-#endif
+enum {
+    TD_RESULT_STOP_FRAME = 10,
+    TD_RESULT_COMPLETE,
+    TD_RESULT_NEXT_QH,
+    TD_RESULT_ASYNC_START,
+    TD_RESULT_ASYNC_CONT,
+};
 
 typedef struct UHCIState UHCIState;
 typedef struct UHCIAsync UHCIAsync;
@@ -188,6 +179,7 @@ static UHCIQueue *uhci_queue_get(UHCIState *s, UHCI_TD *td)
     queue->token = token;
     QTAILQ_INIT(&queue->asyncs);
     QTAILQ_INSERT_HEAD(&s->queues, queue, next);
+    trace_usb_uhci_queue_add(queue->token);
     return queue;
 }
 
@@ -195,23 +187,27 @@ static void uhci_queue_free(UHCIQueue *queue)
 {
     UHCIState *s = queue->uhci;
 
+    trace_usb_uhci_queue_del(queue->token);
     QTAILQ_REMOVE(&s->queues, queue, next);
     g_free(queue);
 }
 
-static UHCIAsync *uhci_async_alloc(UHCIQueue *queue)
+static UHCIAsync *uhci_async_alloc(UHCIQueue *queue, uint32_t addr)
 {
     UHCIAsync *async = g_new0(UHCIAsync, 1);
 
     async->queue = queue;
+    async->td = addr;
     usb_packet_init(&async->packet);
     pci_dma_sglist_init(&async->sgl, &queue->uhci->dev, 1);
+    trace_usb_uhci_packet_add(async->queue->token, async->td);
 
     return async;
 }
 
 static void uhci_async_free(UHCIAsync *async)
 {
+    trace_usb_uhci_packet_del(async->queue->token, async->td);
     usb_packet_cleanup(&async->packet);
     qemu_sglist_destroy(&async->sgl);
     g_free(async);
@@ -221,19 +217,19 @@ static void uhci_async_link(UHCIAsync *async)
 {
     UHCIQueue *queue = async->queue;
     QTAILQ_INSERT_TAIL(&queue->asyncs, async, next);
+    trace_usb_uhci_packet_link_async(async->queue->token, async->td);
 }
 
 static void uhci_async_unlink(UHCIAsync *async)
 {
     UHCIQueue *queue = async->queue;
     QTAILQ_REMOVE(&queue->asyncs, async, next);
+    trace_usb_uhci_packet_unlink_async(async->queue->token, async->td);
 }
 
 static void uhci_async_cancel(UHCIAsync *async)
 {
-    DPRINTF("uhci: cancel td 0x%x token 0x%x done %u\n",
-           async->td, async->token, async->done);
-
+    trace_usb_uhci_packet_cancel(async->queue->token, async->td, async->done);
     if (!async->done)
         usb_cancel_packet(&async->packet);
     uhci_async_free(async);
@@ -300,6 +296,7 @@ static void uhci_async_cancel_all(UHCIState *s)
             uhci_async_unlink(curr);
             uhci_async_cancel(curr);
         }
+        uhci_queue_free(queue);
     }
 }
 
@@ -350,7 +347,7 @@ static void uhci_reset(void *opaque)
     int i;
     UHCIPort *port;
 
-    DPRINTF("uhci: full reset\n");
+    trace_usb_uhci_reset();
 
     pci_conf = s->dev.config;
 
@@ -450,12 +447,13 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
     UHCIState *s = opaque;
 
     addr &= 0x1f;
-    DPRINTF("uhci: writew port=0x%04x val=0x%04x\n", addr, val);
+    trace_usb_uhci_mmio_writew(addr, val);
 
     switch(addr) {
     case 0x00:
         if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
             /* start frame processing */
+            trace_usb_uhci_schedule_start();
             s->expire_time = qemu_get_clock_ns(vm_clock) +
                 (get_ticks_per_sec() / FRAME_TIMER_FREQ);
             qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock));
@@ -560,7 +558,7 @@ static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
         break;
     }
 
-    DPRINTF("uhci: readw port=0x%04x val=0x%04x\n", addr, val);
+    trace_usb_uhci_mmio_readw(addr, val);
 
     return val;
 }
@@ -570,7 +568,7 @@ static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
     UHCIState *s = opaque;
 
     addr &= 0x1f;
-    DPRINTF("uhci: writel port=0x%04x val=0x%08x\n", addr, val);
+    trace_usb_uhci_mmio_writel(addr, val);
 
     switch(addr) {
     case 0x08:
@@ -593,6 +591,7 @@ static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
         val = 0xffffffff;
         break;
     }
+    trace_usb_uhci_mmio_readl(addr, val);
     return val;
 }
 
@@ -728,13 +727,15 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
         if ((td->ctrl & TD_CTRL_SPD) && len < max_len) {
             *int_mask |= 0x02;
             /* short packet: do not update QH */
-            DPRINTF("uhci: short packet. td 0x%x token 0x%x\n", async->td, async->token);
-            return 1;
+            trace_usb_uhci_packet_complete_shortxfer(async->queue->token,
+                                                    async->td);
+            return TD_RESULT_NEXT_QH;
         }
     }
 
     /* success */
-    return 0;
+    trace_usb_uhci_packet_complete_success(async->queue->token, async->td);
+    return TD_RESULT_COMPLETE;
 
 out:
     switch(ret) {
@@ -746,7 +747,8 @@ out:
             *int_mask |= 0x01;
         }
         uhci_update_irq(s);
-        return 1;
+        trace_usb_uhci_packet_complete_stall(async->queue->token, async->td);
+        return TD_RESULT_NEXT_QH;
 
     case USB_RET_BABBLE:
         td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
@@ -757,13 +759,14 @@ out:
         }
         uhci_update_irq(s);
         /* frame interrupted */
-        return -1;
+        trace_usb_uhci_packet_complete_babble(async->queue->token, async->td);
+        return TD_RESULT_STOP_FRAME;
 
     case USB_RET_NAK:
         td->ctrl |= TD_CTRL_NAK;
         if (pid == USB_TOKEN_SETUP)
             break;
-	return 1;
+        return TD_RESULT_NEXT_QH;
 
     case USB_RET_IOERROR:
     case USB_RET_NODEV:
@@ -783,11 +786,13 @@ out:
             if (td->ctrl & TD_CTRL_IOC)
                 *int_mask |= 0x01;
             uhci_update_irq(s);
+            trace_usb_uhci_packet_complete_error(async->queue->token,
+                                                 async->td);
         }
     }
     td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
         (err << TD_CTRL_ERROR_SHIFT);
-    return 1;
+    return TD_RESULT_NEXT_QH;
 }
 
 static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)
@@ -800,7 +805,7 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
 
     /* Is active ? */
     if (!(td->ctrl & TD_CTRL_ACTIVE))
-        return 1;
+        return TD_RESULT_NEXT_QH;
 
     async = uhci_async_find_td(s, addr, td);
     if (async) {
@@ -808,22 +813,19 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
         async->queue->valid = 32;
 
         if (!async->done)
-            return 1;
+            return TD_RESULT_ASYNC_CONT;
 
         uhci_async_unlink(async);
         goto done;
     }
 
     /* Allocate new packet */
-    async = uhci_async_alloc(uhci_queue_get(s, td));
-    if (!async)
-        return 1;
+    async = uhci_async_alloc(uhci_queue_get(s, td), addr);
 
     /* valid needs to be large enough to handle 10 frame delay
      * for initial isochronous requests
      */
     async->queue->valid = 32;
-    async->td    = addr;
     async->isoc  = td->ctrl & TD_CTRL_IOS;
 
     max_len = ((td->token >> 21) + 1) & 0x7ff;
@@ -852,12 +854,12 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
         uhci_async_free(async);
         s->status |= UHCI_STS_HCPERR;
         uhci_update_irq(s);
-        return -1;
+        return TD_RESULT_STOP_FRAME;
     }
  
     if (len == USB_RET_ASYNC) {
         uhci_async_link(async);
-        return 2;
+        return TD_RESULT_ASYNC_START;
     }
 
     async->packet.result = len;
@@ -874,8 +876,6 @@ static void uhci_async_complete(USBPort *port, USBPacket *packet)
     UHCIAsync *async = container_of(packet, UHCIAsync, packet);
     UHCIState *s = async->queue->uhci;
 
-    DPRINTF("uhci: async complete. td 0x%x token 0x%x\n", async->td, async->token);
-
     if (async->isoc) {
         UHCI_TD td;
         uint32_t link = async->td;
@@ -963,8 +963,9 @@ static void uhci_fill_queue(UHCIState *s, UHCI_TD *td)
         if (uhci_queue_token(&ptd) != token) {
             break;
         }
+        trace_usb_uhci_td_queue(plink & ~0xf, ptd.ctrl, ptd.token);
         ret = uhci_handle_td(s, plink, &ptd, &int_mask);
-        assert(ret == 2); /* got USB_RET_ASYNC */
+        assert(ret == TD_RESULT_ASYNC_START);
         assert(int_mask == 0);
         plink = ptd.link;
     }
@@ -981,8 +982,6 @@ static void uhci_process_frame(UHCIState *s)
 
     frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
 
-    DPRINTF("uhci: processing frame %d addr 0x%x\n" , s->frnum, frame_addr);
-
     pci_dma_read(&s->dev, frame_addr, &link, 4);
     le32_to_cpus(&link);
 
@@ -994,6 +993,7 @@ static void uhci_process_frame(UHCIState *s)
     for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
         if (is_qh(link)) {
             /* QH */
+            trace_usb_uhci_qh_load(link & ~0xf);
 
             if (qhdb_insert(&qhdb, link)) {
                 /*
@@ -1006,14 +1006,14 @@ static void uhci_process_frame(UHCIState *s)
                  *  (b) we've reached the usb 1.1 bandwidth, which is
                  *      1280 bytes/frame.
                  */
-                DPRINTF("uhci: detected loop. qh 0x%x\n", link);
                 if (td_count == 0) {
-                    DPRINTF("uhci: no transaction last round, stop\n");
+                    trace_usb_uhci_frame_loop_stop_idle();
                     break;
                 } else if (bytes_count >= 1280) {
-                    DPRINTF("uhci: bandwidth limit reached, stop\n");
+                    trace_usb_uhci_frame_loop_stop_bandwidth();
                     break;
                 } else {
+                    trace_usb_uhci_frame_loop_continue();
                     td_count = 0;
                     qhdb_reset(&qhdb);
                     qhdb_insert(&qhdb, link);
@@ -1024,9 +1024,6 @@ static void uhci_process_frame(UHCIState *s)
             le32_to_cpus(&qh.link);
             le32_to_cpus(&qh.el_link);
 
-            DPRINTF("uhci: QH 0x%x load. link 0x%x elink 0x%x\n",
-                    link, qh.link, qh.el_link);
-
             if (!is_valid(qh.el_link)) {
                 /* QH w/o elements */
                 curr_qh = 0;
@@ -1045,9 +1042,7 @@ static void uhci_process_frame(UHCIState *s)
         le32_to_cpus(&td.ctrl);
         le32_to_cpus(&td.token);
         le32_to_cpus(&td.buffer);
-
-        DPRINTF("uhci: TD 0x%x load. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n", 
-                link, td.link, td.ctrl, td.token, curr_qh);
+        trace_usb_uhci_td_load(curr_qh & ~0xf, link & ~0xf, td.ctrl, td.token);
 
         old_td_ctrl = td.ctrl;
         ret = uhci_handle_td(s, link, &td, &int_mask);
@@ -1058,31 +1053,25 @@ static void uhci_process_frame(UHCIState *s)
         }
 
         switch (ret) {
-        case -1: /* interrupted frame */
+        case TD_RESULT_STOP_FRAME: /* interrupted frame */
             goto out;
 
-        case 1: /* goto next queue */
-            DPRINTF("uhci: TD 0x%x skip. "
-                    "link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n",
-                    link, td.link, td.ctrl, td.token, curr_qh);
+        case TD_RESULT_NEXT_QH:
+        case TD_RESULT_ASYNC_CONT:
+            trace_usb_uhci_td_nextqh(curr_qh & ~0xf, link & ~0xf);
             link = curr_qh ? qh.link : td.link;
             continue;
 
-        case 2: /* got USB_RET_ASYNC */
-            DPRINTF("uhci: TD 0x%x async. "
-                    "link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n",
-                    link, td.link, td.ctrl, td.token, curr_qh);
+        case TD_RESULT_ASYNC_START:
+            trace_usb_uhci_td_async(curr_qh & ~0xf, link & ~0xf);
             if (is_valid(td.link)) {
                 uhci_fill_queue(s, &td);
             }
             link = curr_qh ? qh.link : td.link;
             continue;
 
-        case 0: /* completed TD */
-            DPRINTF("uhci: TD 0x%x done. "
-                    "link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n",
-                    link, td.link, td.ctrl, td.token, curr_qh);
-
+        case TD_RESULT_COMPLETE:
+            trace_usb_uhci_td_complete(curr_qh & ~0xf, link & ~0xf);
             link = td.link;
             td_count++;
             bytes_count += (td.ctrl & 0x7ff) + 1;
@@ -1095,10 +1084,6 @@ static void uhci_process_frame(UHCIState *s)
 
                 if (!depth_first(link)) {
                     /* done with this QH */
-
-                    DPRINTF("uhci: QH 0x%x done. link 0x%x elink 0x%x\n",
-                            curr_qh, qh.link, qh.el_link);
-
                     curr_qh = 0;
                     link    = qh.link;
                 }
@@ -1125,11 +1110,11 @@ static void uhci_frame_timer(void *opaque)
 
     if (!(s->cmd & UHCI_CMD_RS)) {
         /* Full stop */
+        trace_usb_uhci_schedule_stop();
         qemu_del_timer(s->frame_timer);
+        uhci_async_cancel_all(s);
         /* set hchalted bit in status - UHCI11D 2.1.2 */
         s->status |= UHCI_STS_HCHALTED;
-
-        DPRINTF("uhci: halted\n");
         return;
     }
 
@@ -1144,7 +1129,7 @@ static void uhci_frame_timer(void *opaque)
     /* Start new frame */
     s->frnum = (s->frnum + 1) & 0x7ff;
 
-    DPRINTF("uhci: new frame #%u\n" , s->frnum);
+    trace_usb_uhci_frame_start(s->frnum);
 
     uhci_async_validate_begin(s);
 
@@ -1391,18 +1376,3 @@ static void uhci_register_types(void)
 }
 
 type_init(uhci_register_types)
-
-void usb_uhci_piix3_init(PCIBus *bus, int devfn)
-{
-    pci_create_simple(bus, devfn, "piix3-usb-uhci");
-}
-
-void usb_uhci_piix4_init(PCIBus *bus, int devfn)
-{
-    pci_create_simple(bus, devfn, "piix4-usb-uhci");
-}
-
-void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn)
-{
-    pci_create_simple(bus, devfn, "vt82c686b-usb-uhci");
-}
diff --git a/hw/usb-xhci.c b/hw/usb/hcd-xhci.c
index e8f1b6e3a5..73b0c7f5e5 100644
--- a/hw/usb-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -18,12 +18,12 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#include "hw.h"
+#include "hw/hw.h"
 #include "qemu-timer.h"
-#include "usb.h"
-#include "pci.h"
-#include "qdev-addr.h"
-#include "msi.h"
+#include "hw/usb.h"
+#include "hw/pci.h"
+#include "hw/qdev-addr.h"
+#include "hw/msi.h"
 
 //#define DEBUG_XHCI
 //#define DEBUG_DATA
diff --git a/usb-bsd.c b/hw/usb/host-bsd.c
index ec26266620..ec26266620 100644
--- a/usb-bsd.c
+++ b/hw/usb/host-bsd.c
diff --git a/usb-linux.c b/hw/usb/host-linux.c
index 90919c242a..90919c242a 100644
--- a/usb-linux.c
+++ b/hw/usb/host-linux.c
diff --git a/usb-stub.c b/hw/usb/host-stub.c
index b4e10c12ca..b4e10c12ca 100644
--- a/usb-stub.c
+++ b/hw/usb/host-stub.c
diff --git a/hw/usb-libhw.c b/hw/usb/libhw.c
index 162b42bd5b..2462351389 100644
--- a/hw/usb-libhw.c
+++ b/hw/usb/libhw.c
@@ -21,7 +21,7 @@
  */
 #include "qemu-common.h"
 #include "cpu-common.h"
-#include "usb.h"
+#include "hw/usb.h"
 #include "dma.h"
 
 int usb_packet_map(USBPacket *p, QEMUSGList *sgl)
diff --git a/usb-redir.c b/hw/usb/redirect.c
index 8e9f175dbb..8e9f175dbb 100644
--- a/usb-redir.c
+++ b/hw/usb/redirect.c
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index b9102f4a54..c1687a5b89 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -13,7 +13,6 @@
 #include "net.h"
 #include "sysemu.h"
 #include "pci.h"
-#include "usb-ohci.h"
 #include "boards.h"
 #include "blockdev.h"
 #include "exec-memory.h"
@@ -240,7 +239,7 @@ static void versatile_init(ram_addr_t ram_size,
         }
     }
     if (usb_enabled) {
-        usb_ohci_init_pci(pci_bus, -1);
+        pci_create_simple(pci_bus, -1, "pci-ohci");
     }
     n = drive_get_max_bus(IF_SCSI);
     while (n >= 0) {
diff --git a/linux-user/main.c b/linux-user/main.c
index 14bf5f0bc7..bd4748941a 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3285,6 +3285,8 @@ int main(int argc, char **argv, char **envp)
     int i;
     int ret;
 
+    module_call_init(MODULE_INIT_QOM);
+
     qemu_cache_utils_init(envp);
 
     if ((envlist = envlist_create()) == NULL) {
diff --git a/qemu-user.c b/qemu-user.c
new file mode 100644
index 0000000000..08ccb0fe8e
--- /dev/null
+++ b/qemu-user.c
@@ -0,0 +1,37 @@
+/*
+ * Stubs for QEMU user emulation
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 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/gpl-2.0.html>
+ */
+
+#include "qemu-common.h"
+#include "monitor.h"
+
+Monitor *cur_mon;
+
+int monitor_cur_is_qmp(void)
+{
+    return 0;
+}
+
+void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+{
+}
+
+void monitor_set_error(Monitor *mon, QError *qerror)
+{
+}
diff --git a/trace-events b/trace-events
index 74bb92af4f..c8317a0fa5 100644
--- a/trace-events
+++ b/trace-events
@@ -227,16 +227,17 @@ sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags
 sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
 sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64
 
-# hw/usb.c
+# hw/usb/core.c
 usb_packet_state_change(int bus, const char *port, int ep, void *p, const char *o, const char *n) "bus %d, port %s, ep %d, packet %p, state %s -> %s"
+usb_packet_state_fault(int bus, const char *port, int ep, void *p, const char *o, const char *n) "bus %d, port %s, ep %d, packet %p, state %s, expected %s"
 
-# hw/usb-bus.c
+# hw/usb/bus.c
 usb_port_claim(int bus, const char *port) "bus %d, port %s"
 usb_port_attach(int bus, const char *port) "bus %d, port %s"
 usb_port_detach(int bus, const char *port) "bus %d, port %s"
 usb_port_release(int bus, const char *port) "bus %d, port %s"
 
-# hw/usb-ehci.c
+# hw/usb/hcd-ehci.c
 usb_ehci_reset(void) "=== RESET ==="
 usb_ehci_mmio_readl(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
 usb_ehci_mmio_writel(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
@@ -257,6 +258,37 @@ usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
 usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t len, uint32_t bufpos) "write %d, cpage %d, offset 0x%03x, addr 0x%08x, len %d, bufpos %d"
 usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
 
+# hw/usb/hcd-uhci.c
+usb_uhci_reset(void) "=== RESET ==="
+usb_uhci_schedule_start(void) ""
+usb_uhci_schedule_stop(void) ""
+usb_uhci_frame_start(uint32_t num) "nr %d"
+usb_uhci_frame_loop_stop_idle(void) ""
+usb_uhci_frame_loop_stop_bandwidth(void) ""
+usb_uhci_frame_loop_continue(void) ""
+usb_uhci_mmio_readw(uint32_t addr, uint32_t val) "addr %04x, ret 0x04%x"
+usb_uhci_mmio_writew(uint32_t addr, uint32_t val) "addr %04x, val 0x04%x"
+usb_uhci_mmio_readl(uint32_t addr, uint32_t val) "addr %04x, ret 0x08%x"
+usb_uhci_mmio_writel(uint32_t addr, uint32_t val) "addr %04x, val 0x08%x"
+usb_uhci_queue_add(uint32_t token) "token 0x%x"
+usb_uhci_queue_del(uint32_t token) "token 0x%x"
+usb_uhci_packet_add(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_link_async(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_unlink_async(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_cancel(uint32_t token, uint32_t addr, int done) "token 0x%x, td 0x%x, done %d"
+usb_uhci_packet_complete_success(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_complete_shortxfer(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_complete_stall(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_complete_babble(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_complete_error(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_del(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_qh_load(uint32_t qh) "qh 0x%x"
+usb_uhci_td_load(uint32_t qh, uint32_t td, uint32_t ctrl, uint32_t token) "qh 0x%x, td 0x%x, ctrl 0x%x, token 0x%x"
+usb_uhci_td_queue(uint32_t td, uint32_t ctrl, uint32_t token) "td 0x%x, ctrl 0x%x, token 0x%x"
+usb_uhci_td_nextqh(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
+usb_uhci_td_async(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
+usb_uhci_td_complete(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
+
 # hw/usb-desc.c
 usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
 usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
@@ -269,7 +301,7 @@ usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d,
 usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
 usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
 
-# usb-linux.c
+# hw/usb/host-linux.c
 usb_host_open_started(int bus, int addr) "dev %d:%d"
 usb_host_open_success(int bus, int addr) "dev %d:%d"
 usb_host_open_failure(int bus, int addr) "dev %d:%d"
diff --git a/vl.c b/vl.c
index 65f11f200d..bd95539ff7 100644
--- a/vl.c
+++ b/vl.c
@@ -2299,6 +2299,8 @@ int main(int argc, char **argv, char **envp)
 #endif
     }
 
+    module_call_init(MODULE_INIT_QOM);
+
     runstate_init();
 
     init_clocks();
@@ -3466,8 +3468,6 @@ int main(int argc, char **argv, char **envp)
     if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
         exit(1);
 
-    module_call_init(MODULE_INIT_QOM);
-
     /* must be after qdev registration but before machine init */
     if (vga_model) {
         select_vgahw(vga_model);