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

* kraxel/usb.44:
  Endian fix an assertion in usb-msd
  uhci: alloc can't fail, drop check.
  uhci: new uhci_handle_td return code for tds still in flight
  uhci: renumber uhci_handle_td return codes
  uhci: use enum for uhci_handle_td return codes
  uhci: tracing support
  uhci: cancel on schedule stop.
  uhci: fix uhci_async_cancel_all
  uhci: pass addr to uhci_async_alloc
  usb: improve packet state sanity checks
  usb-ohci: DMA writeback bug fixes
  usb-ehci: drop unused isoch_pause variable
  usb: zap hw/ush-{ohic,uhci}.h + init wrappers
  usb: the big rename
This commit is contained in:
Anthony Liguori 2012-03-13 13:55:02 -05:00
commit 684e1e0479
39 changed files with 226 additions and 218 deletions

View File

@ -119,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
@ -205,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
@ -228,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
@ -239,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

View File

@ -373,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

4
configure vendored
View File

@ -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

View File

@ -8,7 +8,6 @@
#include "ide.h"
#include "net.h"
#include "pc.h"
#include "usb-ohci.h"
#include "irq.h"

View File

@ -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);

View File

@ -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. */

View File

@ -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) {

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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;
}

View File

@ -1,5 +1,5 @@
#include "usb.h"
#include "usb-desc.h"
#include "hw/usb.h"
#include "hw/usb/desc.h"
#include "trace.h"
/* ------------------------------------------------------------------ */

View File

@ -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" */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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");
}

View File

@ -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

View File

@ -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)

View File

@ -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) {

View File

@ -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"