summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/virtio-9p-device.c2
-rw-r--r--hw/Makefile.objs11
-rw-r--r--hw/a15mpcore.c2
-rw-r--r--hw/a9mpcore.c2
-rw-r--r--hw/ac97.c2
-rw-r--r--hw/acpi_piix4.c2
-rw-r--r--hw/ads7846.c2
-rw-r--r--hw/apb_pci.c6
-rw-r--r--hw/apic.c2
-rw-r--r--hw/apic_common.c2
-rw-r--r--hw/applesmc.c2
-rw-r--r--hw/arm11mpcore.c4
-rw-r--r--hw/arm_gic.c2
-rw-r--r--hw/arm_gic_common.c2
-rw-r--r--hw/arm_l2x0.c2
-rw-r--r--hw/arm_mptimer.c2
-rw-r--r--hw/arm_sysctl.c2
-rw-r--r--hw/arm_timer.c4
-rw-r--r--hw/armv7m.c2
-rw-r--r--hw/armv7m_nvic.c2
-rw-r--r--hw/bitbang_i2c.c2
-rw-r--r--hw/cadence_gem.c2
-rw-r--r--hw/cadence_ttc.c2
-rw-r--r--hw/cadence_uart.c2
-rw-r--r--hw/ccid-card-emulated.c2
-rw-r--r--hw/ccid-card-passthru.c2
-rw-r--r--hw/cirrus_vga.c4
-rw-r--r--hw/cs4231.c2
-rw-r--r--hw/cs4231a.c2
-rw-r--r--hw/debugcon.c2
-rw-r--r--hw/debugexit.c2
-rw-r--r--hw/ds1225y.c2
-rw-r--r--hw/ds1338.c2
-rw-r--r--hw/e1000.c14
-rw-r--r--hw/eccmemctl.c2
-rw-r--r--hw/empty_slot.c2
-rw-r--r--hw/es1370.c2
-rw-r--r--hw/escc.c2
-rw-r--r--hw/etraxfs_eth.c2
-rw-r--r--hw/etraxfs_pic.c2
-rw-r--r--hw/etraxfs_ser.c2
-rw-r--r--hw/etraxfs_timer.c2
-rw-r--r--hw/exynos4210.c7
-rw-r--r--hw/exynos4210_combiner.c2
-rw-r--r--hw/exynos4210_fimd.c2
-rw-r--r--hw/exynos4210_gic.c6
-rw-r--r--hw/exynos4210_mct.c2
-rw-r--r--hw/exynos4210_pmu.c2
-rw-r--r--hw/exynos4210_pwm.c2
-rw-r--r--hw/exynos4210_uart.c2
-rw-r--r--hw/fdc.c6
-rw-r--r--hw/fw_cfg.c2
-rw-r--r--hw/g364fb.c2
-rw-r--r--hw/grlib_apbuart.c2
-rw-r--r--hw/grlib_gptimer.c2
-rw-r--r--hw/grlib_irqmp.c2
-rw-r--r--hw/gus.c2
-rw-r--r--hw/hda-audio.c6
-rw-r--r--hw/hid.c43
-rw-r--r--hw/hid.h5
-rw-r--r--hw/highbank.c2
-rw-r--r--hw/hpet.c2
-rw-r--r--hw/i2c.c2
-rw-r--r--hw/i82374.c2
-rw-r--r--hw/i82378.c2
-rw-r--r--hw/i8254.c2
-rw-r--r--hw/i8254_common.c2
-rw-r--r--hw/i8259.c2
-rw-r--r--hw/i8259_common.c2
-rw-r--r--hw/ide/ahci.c2
-rw-r--r--hw/ide/cmd646.c2
-rw-r--r--hw/ide/ich.c2
-rw-r--r--hw/ide/isa.c2
-rw-r--r--hw/ide/piix.c6
-rw-r--r--hw/ide/qdev.c8
-rw-r--r--hw/ide/via.c2
-rw-r--r--hw/imx_ccm.c2
-rw-r--r--hw/imx_serial.c2
-rw-r--r--hw/integratorcp.c4
-rw-r--r--hw/intel-hda.c43
-rw-r--r--hw/ioapic.c2
-rw-r--r--hw/ioapic_common.c2
-rw-r--r--hw/ioh3420.c2
-rw-r--r--hw/isa-bus.c4
-rw-r--r--hw/ivshmem.c2
-rw-r--r--hw/jazz_led.c2
-rw-r--r--hw/kvm/apic.c2
-rw-r--r--hw/kvm/clock.c2
-rw-r--r--hw/kvm/i8254.c2
-rw-r--r--hw/kvm/i8259.c2
-rw-r--r--hw/kvm/ioapic.c2
-rw-r--r--hw/kvmvapic.c2
-rw-r--r--hw/lan9118.c2
-rw-r--r--hw/lance.c2
-rw-r--r--hw/lm32_juart.c2
-rw-r--r--hw/lm32_pic.c2
-rw-r--r--hw/lm32_sys.c2
-rw-r--r--hw/lm32_timer.c2
-rw-r--r--hw/lm32_uart.c2
-rw-r--r--hw/lm832x.c2
-rw-r--r--hw/lsi53c895a.c2
-rw-r--r--hw/m48t59.c4
-rw-r--r--hw/macio.c2
-rw-r--r--hw/marvell_88w8618_audio.c2
-rw-r--r--hw/max111x.c4
-rw-r--r--hw/max7310.c2
-rw-r--r--hw/mc146818rtc.c2
-rw-r--r--hw/milkymist-ac97.c2
-rw-r--r--hw/milkymist-hpdmc.c2
-rw-r--r--hw/milkymist-memcard.c2
-rw-r--r--hw/milkymist-minimac2.c2
-rw-r--r--hw/milkymist-pfpu.c2
-rw-r--r--hw/milkymist-softusb.c2
-rw-r--r--hw/milkymist-sysctl.c2
-rw-r--r--hw/milkymist-tmu2.c2
-rw-r--r--hw/milkymist-uart.c2
-rw-r--r--hw/milkymist-vgafb.c2
-rw-r--r--hw/mips_malta.c2
-rw-r--r--hw/mipsnet.c2
-rw-r--r--hw/mpc8544_guts.c2
-rw-r--r--hw/mst_fpga.c2
-rw-r--r--hw/musicpal.c16
-rw-r--r--hw/nand.c2
-rw-r--r--hw/ne2000-isa.c2
-rw-r--r--hw/ne2000.c2
-rw-r--r--hw/omap1.c2
-rw-r--r--hw/omap_gpio.c4
-rw-r--r--hw/omap_i2c.c2
-rw-r--r--hw/omap_intc.c4
-rw-r--r--hw/onenand.c2
-rw-r--r--hw/opencores_eth.c2
-rw-r--r--hw/openpic.c1034
-rw-r--r--hw/parallel.c2
-rw-r--r--hw/pc-testdev.c2
-rw-r--r--hw/pc.c14
-rw-r--r--hw/pc87312.c387
-rw-r--r--hw/pc87312.h66
-rw-r--r--hw/pc_piix.c8
-rw-r--r--hw/pc_q35.c4
-rw-r--r--hw/pc_sysfw.c2
-rw-r--r--hw/pci/pci.c2
-rw-r--r--hw/pci_bridge_dev.c2
-rw-r--r--hw/pckbd.c2
-rw-r--r--hw/pcnet-pci.c2
-rw-r--r--hw/pcspk.c2
-rw-r--r--hw/piix4.c2
-rw-r--r--hw/pl011.c4
-rw-r--r--hw/pl022.c2
-rw-r--r--hw/pl031.c2
-rw-r--r--hw/pl041.c2
-rw-r--r--hw/pl050.c4
-rw-r--r--hw/pl061.c4
-rw-r--r--hw/pl080.c4
-rw-r--r--hw/pl110.c6
-rw-r--r--hw/pl181.c2
-rw-r--r--hw/pl190.c2
-rw-r--r--hw/ppc/e500.c8
-rw-r--r--hw/ppc_booke.c13
-rw-r--r--hw/ppc_prep.c39
-rw-r--r--hw/ppce500_spin.c2
-rw-r--r--hw/pxa2xx.c8
-rw-r--r--hw/pxa2xx_dma.c2
-rw-r--r--hw/pxa2xx_gpio.c2
-rw-r--r--hw/pxa2xx_pic.c2
-rw-r--r--hw/pxa2xx_timer.c4
-rw-r--r--hw/qdev-core.h12
-rw-r--r--hw/qdev-monitor.c51
-rw-r--r--hw/qdev.c17
-rw-r--r--hw/qxl.c4
-rw-r--r--hw/realview_gic.c2
-rw-r--r--hw/rtl8139.c5
-rw-r--r--hw/s390-virtio-bus.c14
-rw-r--r--hw/s390x/event-facility.c4
-rw-r--r--hw/s390x/sclp.c2
-rw-r--r--hw/s390x/sclpconsole.c2
-rw-r--r--hw/s390x/sclpquiesce.c2
-rw-r--r--hw/sb16.c2
-rw-r--r--hw/sbi.c2
-rw-r--r--hw/scsi-bus.c2
-rw-r--r--hw/scsi-disk.c8
-rw-r--r--hw/scsi-generic.c2
-rw-r--r--hw/serial-isa.c2
-rw-r--r--hw/serial-pci.c6
-rw-r--r--hw/sga.c2
-rw-r--r--hw/sh_pci.c4
-rw-r--r--hw/slavio_intctl.c2
-rw-r--r--hw/slavio_misc.c4
-rw-r--r--hw/slavio_timer.c2
-rw-r--r--hw/smbus.c2
-rw-r--r--hw/smbus_eeprom.c2
-rw-r--r--hw/smc91c111.c2
-rw-r--r--hw/spapr_llan.c2
-rw-r--r--hw/spapr_vio.c4
-rw-r--r--hw/spapr_vscsi.c2
-rw-r--r--hw/spapr_vty.c2
-rw-r--r--hw/sparc32_dma.c2
-rw-r--r--hw/spitz.c8
-rw-r--r--hw/ssd0303.c2
-rw-r--r--hw/ssd0323.c2
-rw-r--r--hw/ssi-sd.c2
-rw-r--r--hw/ssi.c2
-rw-r--r--hw/stellaris.c6
-rw-r--r--hw/stellaris_enet.c2
-rw-r--r--hw/stream.c2
-rw-r--r--hw/strongarm.c12
-rw-r--r--hw/sun4c_intctl.c2
-rw-r--r--hw/sun4m.c8
-rw-r--r--hw/sun4m_iommu.c2
-rw-r--r--hw/sun4u.c6
-rw-r--r--hw/sysbus.c2
-rw-r--r--hw/tcx.c2
-rw-r--r--hw/tmp105.c2
-rw-r--r--hw/tosa.c4
-rw-r--r--hw/tusb6010.c2
-rw-r--r--hw/twl92230.c2
-rw-r--r--hw/usb.h20
-rw-r--r--hw/usb/Makefile.objs4
-rw-r--r--hw/usb/bus.c10
-rw-r--r--hw/usb/core.c2
-rw-r--r--hw/usb/dev-audio.c2
-rw-r--r--hw/usb/dev-bluetooth.c2
-rw-r--r--hw/usb/dev-hid.c14
-rw-r--r--hw/usb/dev-hub.c2
-rw-r--r--hw/usb/dev-network.c2
-rw-r--r--hw/usb/dev-serial.c4
-rw-r--r--hw/usb/dev-smartcard-reader.c4
-rw-r--r--hw/usb/dev-storage.c2
-rw-r--r--hw/usb/dev-uas.c2
-rw-r--r--hw/usb/dev-wacom.c2
-rw-r--r--hw/usb/hcd-ehci-pci.c39
-rw-r--r--hw/usb/hcd-ehci-sysbus.c49
-rw-r--r--hw/usb/hcd-ehci.c347
-rw-r--r--hw/usb/hcd-ehci.h42
-rw-r--r--hw/usb/hcd-ohci.c34
-rw-r--r--hw/usb/hcd-uhci.c174
-rw-r--r--hw/usb/hcd-xhci.c16
-rw-r--r--hw/usb/host-bsd.c2
-rw-r--r--hw/usb/host-linux.c2
-rw-r--r--hw/usb/quirks-ftdi-ids.h1255
-rw-r--r--hw/usb/quirks-pl2303-ids.h150
-rw-r--r--hw/usb/quirks.c53
-rw-r--r--hw/usb/quirks.h910
-rw-r--r--hw/usb/redirect.c451
-rw-r--r--hw/versatile_pci.c6
-rw-r--r--hw/versatilepb.c2
-rw-r--r--hw/vfio_pci.c34
-rw-r--r--hw/vga-isa.c2
-rw-r--r--hw/vga-pci.c2
-rw-r--r--hw/virtio-console.c4
-rw-r--r--hw/virtio-pci.c12
-rw-r--r--hw/virtio-scsi.c4
-rw-r--r--hw/virtio-serial-bus.c2
-rw-r--r--hw/vmmouse.c2
-rw-r--r--hw/vmport.c2
-rw-r--r--hw/vmware_vga.c2
-rw-r--r--hw/vt82c686.c8
-rw-r--r--hw/wdt_i6300esb.c2
-rw-r--r--hw/wdt_ib700.c2
-rw-r--r--hw/wm8750.c2
-rw-r--r--hw/xen_apic.c2
-rw-r--r--hw/xen_platform.c2
-rw-r--r--hw/xen_pt.c2
-rw-r--r--hw/xgmac.c2
-rw-r--r--hw/xilinx_axidma.c2
-rw-r--r--hw/xilinx_axienet.c2
-rw-r--r--hw/xilinx_ethlite.c2
-rw-r--r--hw/xilinx_intc.c2
-rw-r--r--hw/xilinx_spi.c2
-rw-r--r--hw/xilinx_timer.c2
-rw-r--r--hw/xilinx_uartlite.c2
-rw-r--r--hw/xio3130_downstream.c2
-rw-r--r--hw/xio3130_upstream.c2
-rw-r--r--hw/z2.c4
-rw-r--r--hw/zaurus.c2
-rw-r--r--hw/zynq_slcr.c2
275 files changed, 4912 insertions, 1121 deletions
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index f16ccfbed1..6f427dfc5d 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -177,7 +177,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
dc->reset = virtio_pci_reset;
}
-static TypeInfo virtio_9p_info = {
+static const TypeInfo virtio_9p_info = {
.name = "virtio-9p-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VirtIOPCIProxy),
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index b8bbed39c1..aa55ce9873 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -1,3 +1,8 @@
+# core qdev-related obj files, also used by *-user:
+universal-obj-y += qdev.o qdev-properties.o
+# irq.o needed for qdev GPIO handling:
+universal-obj-y += irq.o
+
common-obj-y = usb/ ide/ pci/
common-obj-y += loader.o
common-obj-$(CONFIG_VIRTIO) += virtio-console.o
@@ -31,7 +36,7 @@ common-obj-$(CONFIG_DMA) += dma.o
common-obj-$(CONFIG_I82374) += i82374.o
common-obj-$(CONFIG_HPET) += hpet.o
common-obj-$(CONFIG_APPLESMC) += applesmc.o
-common-obj-$(CONFIG_SMARTCARD) += ccid-card-passthru.o
+common-obj-y += ccid-card-passthru.o
common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
common-obj-y += fifo.o
@@ -42,6 +47,7 @@ extra-obj-y += pci/
# PPC devices
common-obj-$(CONFIG_PREP_PCI) += prep_pci.o
common-obj-$(CONFIG_I82378) += i82378.o
+common-obj-$(CONFIG_PC87312) += pc87312.o
# Mac shared devices
common-obj-$(CONFIG_MACIO) += macio.o
common-obj-$(CONFIG_CUDA) += cuda.o
@@ -154,7 +160,6 @@ common-obj-$(CONFIG_SOUND) += $(sound-obj-y)
common-obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/
common-obj-y += usb/
-common-obj-y += irq.o
common-obj-$(CONFIG_PTIMER) += ptimer.o
common-obj-$(CONFIG_MAX7310) += max7310.o
common-obj-$(CONFIG_WM8750) += wm8750.o
@@ -180,7 +185,7 @@ common-obj-$(CONFIG_SD) += sd.o
common-obj-y += bt.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o
common-obj-y += bt-hci-csr.o
common-obj-y += msmouse.o ps2.o
-common-obj-y += qdev.o qdev-properties.o qdev-monitor.o
+common-obj-y += qdev-monitor.o
common-obj-y += qdev-properties-system.o
common-obj-$(CONFIG_BRLAPI) += baum.o
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index fc0a02ae86..30983efc03 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -93,7 +93,7 @@ static void a15mp_priv_class_init(ObjectClass *klass, void *data)
/* We currently have no savable state */
}
-static TypeInfo a15mp_priv_info = {
+static const TypeInfo a15mp_priv_info = {
.name = "a15mpcore_priv",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(A15MPPrivState),
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index f802de0824..184734f9b1 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -226,7 +226,7 @@ static void a9mp_priv_class_init(ObjectClass *klass, void *data)
dc->reset = a9mp_priv_reset;
}
-static TypeInfo a9mp_priv_info = {
+static const TypeInfo a9mp_priv_info = {
.name = "a9mpcore_priv",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(a9mp_priv_state),
diff --git a/hw/ac97.c b/hw/ac97.c
index 5cd19c1d02..6c565e755c 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1423,7 +1423,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
dc->props = ac97_properties;
}
-static TypeInfo ac97_info = {
+static const TypeInfo ac97_info = {
.name = "AC97",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof (AC97LinkState),
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 06a8aca9cb..2f84b4ed4c 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -487,7 +487,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
dc->props = piix4_pm_properties;
}
-static TypeInfo piix4_pm_info = {
+static const TypeInfo piix4_pm_info = {
.name = "PIIX4_PM",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PIIX4PMState),
diff --git a/hw/ads7846.c b/hw/ads7846.c
index fa137e628e..29e5585d91 100644
--- a/hw/ads7846.c
+++ b/hw/ads7846.c
@@ -162,7 +162,7 @@ static void ads7846_class_init(ObjectClass *klass, void *data)
k->transfer = ads7846_transfer;
}
-static TypeInfo ads7846_info = {
+static const TypeInfo ads7846_info = {
.name = "ads7846",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ADS7846State),
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index c22e2b0fc3..b9a7ee6a31 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -486,7 +486,7 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
-static TypeInfo pbm_pci_host_info = {
+static const TypeInfo pbm_pci_host_info = {
.name = "pbm-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -502,7 +502,7 @@ static void pbm_host_class_init(ObjectClass *klass, void *data)
dc->reset = pci_pbm_reset;
}
-static TypeInfo pbm_host_info = {
+static const TypeInfo pbm_host_info = {
.name = "pbm",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(APBState),
@@ -525,7 +525,7 @@ static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pci_device;
}
-static TypeInfo pbm_pci_bridge_info = {
+static const TypeInfo pbm_pci_bridge_info = {
.name = "pbm-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIBridge),
diff --git a/hw/apic.c b/hw/apic.c
index 81b82f694c..fd14b73023 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -895,7 +895,7 @@ static void apic_class_init(ObjectClass *klass, void *data)
k->post_load = apic_post_load;
}
-static TypeInfo apic_info = {
+static const TypeInfo apic_info = {
.name = "apic",
.instance_size = sizeof(APICCommonState),
.parent = TYPE_APIC_COMMON,
diff --git a/hw/apic_common.c b/hw/apic_common.c
index 0658be93c1..6e1b1e0320 100644
--- a/hw/apic_common.c
+++ b/hw/apic_common.c
@@ -385,7 +385,7 @@ static void apic_common_class_init(ObjectClass *klass, void *data)
sc->init = apic_init_common;
}
-static TypeInfo apic_common_type = {
+static const TypeInfo apic_common_type = {
.name = TYPE_APIC_COMMON,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(APICCommonState),
diff --git a/hw/applesmc.c b/hw/applesmc.c
index c564b60c0a..5a8c4ff2d2 100644
--- a/hw/applesmc.c
+++ b/hw/applesmc.c
@@ -236,7 +236,7 @@ static void qdev_applesmc_class_init(ObjectClass *klass, void *data)
dc->props = applesmc_isa_properties;
}
-static TypeInfo applesmc_isa_info = {
+static const TypeInfo applesmc_isa_info = {
.name = "isa-applesmc",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(struct AppleSMCStatus),
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index 093331124a..469f6bfdee 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -222,7 +222,7 @@ static void mpcore_rirq_class_init(ObjectClass *klass, void *data)
dc->props = mpcore_rirq_properties;
}
-static TypeInfo mpcore_rirq_info = {
+static const TypeInfo mpcore_rirq_info = {
.name = "realview_mpcore",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mpcore_rirq_state),
@@ -252,7 +252,7 @@ static void mpcore_priv_class_init(ObjectClass *klass, void *data)
dc->props = mpcore_priv_properties;
}
-static TypeInfo mpcore_priv_info = {
+static const TypeInfo mpcore_priv_info = {
.name = "arm11mpcore_priv",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mpcore_priv_state),
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index b6062c4241..466dbf7398 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -703,7 +703,7 @@ static void arm_gic_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo arm_gic_info = {
+static const TypeInfo arm_gic_info = {
.name = TYPE_ARM_GIC,
.parent = TYPE_ARM_GIC_COMMON,
.instance_size = sizeof(GICState),
diff --git a/hw/arm_gic_common.c b/hw/arm_gic_common.c
index 73ae331807..41799ad765 100644
--- a/hw/arm_gic_common.c
+++ b/hw/arm_gic_common.c
@@ -171,7 +171,7 @@ static void arm_gic_common_class_init(ObjectClass *klass, void *data)
sc->init = arm_gic_common_init;
}
-static TypeInfo arm_gic_common_type = {
+static const TypeInfo arm_gic_common_type = {
.name = TYPE_ARM_GIC_COMMON,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(GICState),
diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
index 6abf0ee160..ae1e51d009 100644
--- a/hw/arm_l2x0.c
+++ b/hw/arm_l2x0.c
@@ -179,7 +179,7 @@ static void l2x0_class_init(ObjectClass *klass, void *data)
dc->reset = l2x0_priv_reset;
}
-static TypeInfo l2x0_info = {
+static const TypeInfo l2x0_info = {
.name = "l2x0",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(l2x0_state),
diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c
index 1febaeb7b1..0cd3853a36 100644
--- a/hw/arm_mptimer.c
+++ b/hw/arm_mptimer.c
@@ -329,7 +329,7 @@ static void arm_mptimer_class_init(ObjectClass *klass, void *data)
dc->props = arm_mptimer_properties;
}
-static TypeInfo arm_mptimer_info = {
+static const TypeInfo arm_mptimer_info = {
.name = "arm_mptimer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(arm_mptimer_state),
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index b733617aa0..a196fcc4aa 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -410,7 +410,7 @@ static void arm_sysctl_class_init(ObjectClass *klass, void *data)
dc->props = arm_sysctl_properties;
}
-static TypeInfo arm_sysctl_info = {
+static const TypeInfo arm_sysctl_info = {
.name = "realview_sysctl",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(arm_sysctl_state),
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 37e28e993c..c1e56be74e 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -361,7 +361,7 @@ static void icp_pit_class_init(ObjectClass *klass, void *data)
sdc->init = icp_pit_init;
}
-static TypeInfo icp_pit_info = {
+static const TypeInfo icp_pit_info = {
.name = "integrator_pit",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(icp_pit_state),
@@ -383,7 +383,7 @@ static void sp804_class_init(ObjectClass *klass, void *data)
k->props = sp804_properties;
}
-static TypeInfo sp804_info = {
+static const TypeInfo sp804_info = {
.name = "sp804",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(sp804_state),
diff --git a/hw/armv7m.c b/hw/armv7m.c
index ce2ec9b4dc..98fe483c25 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -269,7 +269,7 @@ static void bitband_class_init(ObjectClass *klass, void *data)
dc->props = bitband_properties;
}
-static TypeInfo bitband_info = {
+static const TypeInfo bitband_info = {
.name = "ARM,bitband-memory",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BitBandState),
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 0907e42c0c..d5798d0309 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -535,7 +535,7 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
dc->reset = armv7m_nvic_reset;
}
-static TypeInfo armv7m_nvic_info = {
+static const TypeInfo armv7m_nvic_info = {
.name = TYPE_NVIC,
.parent = TYPE_ARM_GIC_COMMON,
.instance_init = armv7m_nvic_instance_init,
diff --git a/hw/bitbang_i2c.c b/hw/bitbang_i2c.c
index 44ed7f4d61..114508fade 100644
--- a/hw/bitbang_i2c.c
+++ b/hw/bitbang_i2c.c
@@ -230,7 +230,7 @@ static void gpio_i2c_class_init(ObjectClass *klass, void *data)
dc->desc = "Virtual GPIO to I2C bridge";
}
-static TypeInfo gpio_i2c_info = {
+static const TypeInfo gpio_i2c_info = {
.name = "gpio_i2c",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(GPIOI2CState),
diff --git a/hw/cadence_gem.c b/hw/cadence_gem.c
index 40a239973c..2beee6268e 100644
--- a/hw/cadence_gem.c
+++ b/hw/cadence_gem.c
@@ -1218,7 +1218,7 @@ static void gem_class_init(ObjectClass *klass, void *data)
dc->reset = gem_reset;
}
-static TypeInfo gem_info = {
+static const TypeInfo gem_info = {
.class_init = gem_class_init,
.name = "cadence_gem",
.parent = TYPE_SYS_BUS_DEVICE,
diff --git a/hw/cadence_ttc.c b/hw/cadence_ttc.c
index 9e1cb1f152..2a8fadd810 100644
--- a/hw/cadence_ttc.c
+++ b/hw/cadence_ttc.c
@@ -474,7 +474,7 @@ static void cadence_ttc_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_cadence_ttc;
}
-static TypeInfo cadence_ttc_info = {
+static const TypeInfo cadence_ttc_info = {
.name = "cadence_ttc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CadenceTTCState),
diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c
index 7dd2fe54ed..cf2f53c81c 100644
--- a/hw/cadence_uart.c
+++ b/hw/cadence_uart.c
@@ -501,7 +501,7 @@ static void cadence_uart_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_cadence_uart;
}
-static TypeInfo cadence_uart_info = {
+static const TypeInfo cadence_uart_info = {
.name = "cadence_uart",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(UartState),
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
index 6fd44695ae..c8f8ba3792 100644
--- a/hw/ccid-card-emulated.c
+++ b/hw/ccid-card-emulated.c
@@ -587,7 +587,7 @@ static void emulated_class_initfn(ObjectClass *klass, void *data)
dc->props = emulated_card_properties;
}
-static TypeInfo emulated_card_info = {
+static const TypeInfo emulated_card_info = {
.name = EMULATED_DEV_NAME,
.parent = TYPE_CCID_CARD,
.instance_size = sizeof(EmulatedState),
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index 4be05471a9..984bd0bf4c 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -336,7 +336,7 @@ static void passthru_class_initfn(ObjectClass *klass, void *data)
dc->props = passthru_card_properties;
}
-static TypeInfo passthru_card_info = {
+static const TypeInfo passthru_card_info = {
.name = PASSTHRU_DEV_NAME,
.parent = TYPE_CCID_CARD,
.instance_size = sizeof(PassthruState),
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 80510bc9af..2a2c8dad62 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2933,7 +2933,7 @@ static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data)
dc->props = isa_vga_cirrus_properties;
}
-static TypeInfo isa_cirrus_vga_info = {
+static const TypeInfo isa_cirrus_vga_info = {
.name = "isa-cirrus-vga",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISACirrusVGAState),
@@ -3003,7 +3003,7 @@ static void cirrus_vga_class_init(ObjectClass *klass, void *data)
dc->props = pci_vga_cirrus_properties;
}
-static TypeInfo cirrus_vga_info = {
+static const TypeInfo cirrus_vga_info = {
.name = "cirrus-vga",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCICirrusVGAState),
diff --git a/hw/cs4231.c b/hw/cs4231.c
index 23570d5b41..ae384b90fd 100644
--- a/hw/cs4231.c
+++ b/hw/cs4231.c
@@ -166,7 +166,7 @@ static void cs4231_class_init(ObjectClass *klass, void *data)
dc->props = cs4231_properties;
}
-static TypeInfo cs4231_info = {
+static const TypeInfo cs4231_info = {
.name = "SUNW,CS4231",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CSState),
diff --git a/hw/cs4231a.c b/hw/cs4231a.c
index 9d528c43b0..73f08594bf 100644
--- a/hw/cs4231a.c
+++ b/hw/cs4231a.c
@@ -682,7 +682,7 @@ static void cs4231a_class_initfn (ObjectClass *klass, void *data)
dc->props = cs4231a_properties;
}
-static TypeInfo cs4231a_info = {
+static const TypeInfo cs4231a_info = {
.name = "cs4231a",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof (CSState),
diff --git a/hw/debugcon.c b/hw/debugcon.c
index e8a855e33a..81b2bb00fd 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -119,7 +119,7 @@ static void debugcon_isa_class_initfn(ObjectClass *klass, void *data)
dc->props = debugcon_isa_properties;
}
-static TypeInfo debugcon_isa_info = {
+static const TypeInfo debugcon_isa_info = {
.name = TYPE_ISA_DEBUGCON_DEVICE,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISADebugconState),
diff --git a/hw/debugexit.c b/hw/debugexit.c
index 90642eb37f..c1b489ddcb 100644
--- a/hw/debugexit.c
+++ b/hw/debugexit.c
@@ -60,7 +60,7 @@ static void debug_exit_class_initfn(ObjectClass *klass, void *data)
dc->props = debug_exit_properties;
}
-static TypeInfo debug_exit_info = {
+static const TypeInfo debug_exit_info = {
.name = TYPE_ISA_DEBUG_EXIT_DEVICE,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISADebugExitState),
diff --git a/hw/ds1225y.c b/hw/ds1225y.c
index 4b3f69bc67..a6219a7908 100644
--- a/hw/ds1225y.c
+++ b/hw/ds1225y.c
@@ -150,7 +150,7 @@ static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
dc->props = nvram_sysbus_properties;
}
-static TypeInfo nvram_sysbus_info = {
+static const TypeInfo nvram_sysbus_info = {
.name = "ds1225y",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusNvRamState),
diff --git a/hw/ds1338.c b/hw/ds1338.c
index 1aefa3ba04..379220638e 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -221,7 +221,7 @@ static void ds1338_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ds1338;
}
-static TypeInfo ds1338_info = {
+static const TypeInfo ds1338_info = {
.name = "ds1338",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(DS1338State),
diff --git a/hw/e1000.c b/hw/e1000.c
index 92fb00a89f..ef06ca1894 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -61,6 +61,8 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
/* this is the size past which hardware will drop packets when setting LPE=0 */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
+/* this is the size past which hardware will drop packets when setting LPE=1 */
+#define MAXIMUM_ETHERNET_LPE_SIZE 16384
/*
* HW models:
@@ -164,6 +166,11 @@ static void
set_phy_ctrl(E1000State *s, int index, uint16_t val)
{
if ((val & MII_CR_AUTO_NEG_EN) && (val & MII_CR_RESTART_AUTO_NEG)) {
+ /* no need auto-negotiation if link was down */
+ if (s->nic->nc.link_down) {
+ s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
+ return;
+ }
s->nic->nc.link_down = true;
e1000_link_down(s);
s->phy_reg[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
@@ -809,8 +816,9 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)
}
/* Discard oversized packets if !LPE and !SBP. */
- if (size > MAXIMUM_ETHERNET_VLAN_SIZE
- && !(s->mac_reg[RCTL] & E1000_RCTL_LPE)
+ if ((size > MAXIMUM_ETHERNET_LPE_SIZE ||
+ (size > MAXIMUM_ETHERNET_VLAN_SIZE
+ && !(s->mac_reg[RCTL] & E1000_RCTL_LPE)))
&& !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) {
return size;
}
@@ -1319,7 +1327,7 @@ static void e1000_class_init(ObjectClass *klass, void *data)
dc->props = e1000_properties;
}
-static TypeInfo e1000_info = {
+static const TypeInfo e1000_info = {
.name = "e1000",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(E1000State),
diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
index 000bd08dee..dbac2c2bbc 100644
--- a/hw/eccmemctl.c
+++ b/hw/eccmemctl.c
@@ -324,7 +324,7 @@ static void ecc_class_init(ObjectClass *klass, void *data)
dc->props = ecc_properties;
}
-static TypeInfo ecc_info = {
+static const TypeInfo ecc_info = {
.name = "eccmemctl",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(ECCState),
diff --git a/hw/empty_slot.c b/hw/empty_slot.c
index 23978eb149..3cb6ccb27d 100644
--- a/hw/empty_slot.c
+++ b/hw/empty_slot.c
@@ -83,7 +83,7 @@ static void empty_slot_class_init(ObjectClass *klass, void *data)
k->init = empty_slot_init1;
}
-static TypeInfo empty_slot_info = {
+static const TypeInfo empty_slot_info = {
.name = "empty_slot",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(EmptySlot),
diff --git a/hw/es1370.c b/hw/es1370.c
index 59c3f2329e..977d2e3767 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1073,7 +1073,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)
dc->vmsd = &vmstate_es1370;
}
-static TypeInfo es1370_info = {
+static const TypeInfo es1370_info = {
.name = "ES1370",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof (ES1370State),
diff --git a/hw/escc.c b/hw/escc.c
index f09904aae4..c81088b22f 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -923,7 +923,7 @@ static void escc_class_init(ObjectClass *klass, void *data)
dc->props = escc_properties;
}
-static TypeInfo escc_info = {
+static const TypeInfo escc_info = {
.name = "escc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SerialState),
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 289a810edc..ec23fa6edf 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -630,7 +630,7 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
dc->props = etraxfs_eth_properties;
}
-static TypeInfo etraxfs_eth_info = {
+static const TypeInfo etraxfs_eth_info = {
.name = "etraxfs-eth",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct fs_eth),
diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index 62a62a36af..64af31c46e 100644
--- a/hw/etraxfs_pic.c
+++ b/hw/etraxfs_pic.c
@@ -165,7 +165,7 @@ static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
dc->props = etraxfs_pic_properties;
}
-static TypeInfo etraxfs_pic_info = {
+static const TypeInfo etraxfs_pic_info = {
.name = "etraxfs,pic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct etrax_pic),
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index 7bde8004d0..72c8868639 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -233,7 +233,7 @@ static void etraxfs_ser_class_init(ObjectClass *klass, void *data)
dc->reset = etraxfs_ser_reset;
}
-static TypeInfo etraxfs_ser_info = {
+static const TypeInfo etraxfs_ser_info = {
.name = "etraxfs,serial",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct etrax_serial),
diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c
index e9273cd95d..d3dac52315 100644
--- a/hw/etraxfs_timer.c
+++ b/hw/etraxfs_timer.c
@@ -336,7 +336,7 @@ static void etraxfs_timer_class_init(ObjectClass *klass, void *data)
sdc->init = etraxfs_timer_init;
}
-static TypeInfo etraxfs_timer_info = {
+static const TypeInfo etraxfs_timer_info = {
.name = "etraxfs,timer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof (struct etrax_timer),
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index a7b84d61a0..246a0fc1c3 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -27,6 +27,7 @@
#include "arm-misc.h"
#include "loader.h"
#include "exynos4210.h"
+#include "usb/hcd-ehci.h"
#define EXYNOS4210_CHIPID_ADDR 0x10000000
@@ -72,6 +73,9 @@
/* Display controllers (FIMD) */
#define EXYNOS4210_FIMD0_BASE_ADDR 0x11C00000
+/* EHCI */
+#define EXYNOS4210_EHCI_BASE_ADDR 0x12580000
+
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
0x09, 0x00, 0x00, 0x00 };
@@ -338,5 +342,8 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
s->irq_table[exynos4210_get_irq(11, 2)],
NULL);
+ sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
+ s->irq_table[exynos4210_get_irq(28, 3)]);
+
return s;
}
diff --git a/hw/exynos4210_combiner.c b/hw/exynos4210_combiner.c
index 84d36ed11f..ba644b43c2 100644
--- a/hw/exynos4210_combiner.c
+++ b/hw/exynos4210_combiner.c
@@ -440,7 +440,7 @@ static void exynos4210_combiner_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_exynos4210_combiner;
}
-static TypeInfo exynos4210_combiner_info = {
+static const TypeInfo exynos4210_combiner_info = {
.name = "exynos4210.combiner",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Exynos4210CombinerState),
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index 5c29b5d01d..3d498b77f8 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1913,7 +1913,7 @@ static void exynos4210_fimd_class_init(ObjectClass *klass, void *data)
k->init = exynos4210_fimd_init;
}
-static TypeInfo exynos4210_fimd_info = {
+static const TypeInfo exynos4210_fimd_info = {
.name = "exynos4210.fimd",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Exynos4210fimdState),
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index 4fea09873a..f67906e42f 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -140,7 +140,7 @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
EXT_GIC_ID_I2C7 },
/* int combiner group 28 */
- { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 },
+ { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
/* int combiner group 29 */
{ EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
@@ -346,7 +346,7 @@ static void exynos4210_gic_class_init(ObjectClass *klass, void *data)
dc->props = exynos4210_gic_properties;
}
-static TypeInfo exynos4210_gic_info = {
+static const TypeInfo exynos4210_gic_info = {
.name = "exynos4210.gic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Exynos4210GicState),
@@ -447,7 +447,7 @@ static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
dc->props = exynos4210_irq_gate_properties;
}
-static TypeInfo exynos4210_irq_gate_info = {
+static const TypeInfo exynos4210_irq_gate_info = {
.name = "exynos4210.irq_gate",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Exynos4210IRQGateState),
diff --git a/hw/exynos4210_mct.c b/hw/exynos4210_mct.c
index 41cd142227..d7d5904cc0 100644
--- a/hw/exynos4210_mct.c
+++ b/hw/exynos4210_mct.c
@@ -1467,7 +1467,7 @@ static void exynos4210_mct_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_exynos4210_mct_state;
}
-static TypeInfo exynos4210_mct_info = {
+static const TypeInfo exynos4210_mct_info = {
.name = "exynos4210.mct",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Exynos4210MCTState),
diff --git a/hw/exynos4210_pmu.c b/hw/exynos4210_pmu.c
index a22b8f181a..7c81a1b628 100644
--- a/hw/exynos4210_pmu.c
+++ b/hw/exynos4210_pmu.c
@@ -484,7 +484,7 @@ static void exynos4210_pmu_class_init(ObjectClass *klass, void *data)
dc->vmsd = &exynos4210_pmu_vmstate;
}
-static TypeInfo exynos4210_pmu_info = {
+static const TypeInfo exynos4210_pmu_info = {
.name = "exynos4210.pmu",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Exynos4210PmuState),
diff --git a/hw/exynos4210_pwm.c b/hw/exynos4210_pwm.c
index 3a3eb8c27a..c8656248a8 100644
--- a/hw/exynos4210_pwm.c
+++ b/hw/exynos4210_pwm.c
@@ -407,7 +407,7 @@ static void exynos4210_pwm_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_exynos4210_pwm_state;
}
-static TypeInfo exynos4210_pwm_info = {
+static const TypeInfo exynos4210_pwm_info = {
.name = "exynos4210.pwm",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Exynos4210PWMState),
diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c
index 4f23079095..adaab242fe 100644
--- a/hw/exynos4210_uart.c
+++ b/hw/exynos4210_uart.c
@@ -661,7 +661,7 @@ static void exynos4210_uart_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_exynos4210_uart;
}
-static TypeInfo exynos4210_uart_info = {
+static const TypeInfo exynos4210_uart_info = {
.name = "exynos4210.uart",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Exynos4210UartState),
diff --git a/hw/fdc.c b/hw/fdc.c
index ddc0cc3819..976a587c42 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -2210,7 +2210,7 @@ static void isabus_fdc_class_init1(ObjectClass *klass, void *data)
dc->props = isa_fdc_properties;
}
-static TypeInfo isa_fdc_info = {
+static const TypeInfo isa_fdc_info = {
.name = "isa-fdc",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(FDCtrlISABus),
@@ -2244,7 +2244,7 @@ static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
dc->props = sysbus_fdc_properties;
}
-static TypeInfo sysbus_fdc_info = {
+static const TypeInfo sysbus_fdc_info = {
.name = "sysbus-fdc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(FDCtrlSysBus),
@@ -2267,7 +2267,7 @@ static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
dc->props = sun4m_fdc_properties;
}
-static TypeInfo sun4m_fdc_info = {
+static const TypeInfo sun4m_fdc_info = {
.name = "SUNW,fdtwo",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(FDCtrlSysBus),
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 26f7125fe2..7c9480c4d7 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -575,7 +575,7 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data)
dc->props = fw_cfg_properties;
}
-static TypeInfo fw_cfg_info = {
+static const TypeInfo fw_cfg_info = {
.name = "fw_cfg",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(FWCfgState),
diff --git a/hw/g364fb.c b/hw/g364fb.c
index b46a044607..0c0c8ba302 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -597,7 +597,7 @@ static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
dc->props = g364fb_sysbus_properties;
}
-static TypeInfo g364fb_sysbus_info = {
+static const TypeInfo g364fb_sysbus_info = {
.name = "sysbus-g364",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(G364SysBusState),
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 88c46780d1..760bed0b72 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -256,7 +256,7 @@ static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
dc->props = grlib_gptimer_properties;
}
-static TypeInfo grlib_gptimer_info = {
+static const TypeInfo grlib_gptimer_info = {
.name = "grlib,apbuart",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(UART),
diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c
index 252ba893e3..7962b74f2c 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -389,7 +389,7 @@ static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
dc->props = grlib_gptimer_properties;
}
-static TypeInfo grlib_gptimer_info = {
+static const TypeInfo grlib_gptimer_info = {
.name = "grlib,gptimer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(GPTimerUnit),
diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c
index 23a6a02bc5..b5427c8039 100644
--- a/hw/grlib_irqmp.c
+++ b/hw/grlib_irqmp.c
@@ -370,7 +370,7 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
dc->props = grlib_irqmp_properties;
}
-static TypeInfo grlib_irqmp_info = {
+static const TypeInfo grlib_irqmp_info = {
.name = "grlib,irqmp",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(IRQMP),
diff --git a/hw/gus.c b/hw/gus.c
index 840d098d6a..aa13fccf0d 100644
--- a/hw/gus.c
+++ b/hw/gus.c
@@ -317,7 +317,7 @@ static void gus_class_initfn (ObjectClass *klass, void *data)
dc->props = gus_properties;
}
-static TypeInfo gus_info = {
+static const TypeInfo gus_info = {
.name = "gus",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof (GUSState),
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 92a91b5ab1..3190bd1cf8 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -1039,7 +1039,7 @@ static void hda_audio_output_class_init(ObjectClass *klass, void *data)
dc->props = hda_audio_properties;
}
-static TypeInfo hda_audio_output_info = {
+static const TypeInfo hda_audio_output_info = {
.name = "hda-output",
.parent = TYPE_HDA_CODEC_DEVICE,
.instance_size = sizeof(HDAAudioState),
@@ -1060,7 +1060,7 @@ static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
dc->props = hda_audio_properties;
}
-static TypeInfo hda_audio_duplex_info = {
+static const TypeInfo hda_audio_duplex_info = {
.name = "hda-duplex",
.parent = TYPE_HDA_CODEC_DEVICE,
.instance_size = sizeof(HDAAudioState),
@@ -1081,7 +1081,7 @@ static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
dc->props = hda_audio_properties;
}
-static TypeInfo hda_audio_micro_info = {
+static const TypeInfo hda_audio_micro_info = {
.name = "hda-micro",
.parent = TYPE_HDA_CODEC_DEVICE,
.instance_size = sizeof(HDAAudioState),
diff --git a/hw/hid.c b/hw/hid.c
index 0fee3b6ddd..89b5415c0f 100644
--- a/hw/hid.c
+++ b/hw/hid.c
@@ -71,12 +71,38 @@ static const uint8_t hid_usage_keys[0x100] = {
bool hid_has_events(HIDState *hs)
{
- return hs->n > 0;
+ return hs->n > 0 || hs->idle_pending;
}
-void hid_set_next_idle(HIDState *hs, int64_t curtime)
+static void hid_idle_timer(void *opaque)
{
- hs->next_idle_clock = curtime + (get_ticks_per_sec() * hs->idle * 4) / 1000;
+ HIDState *hs = opaque;
+
+ hs->idle_pending = true;
+ hs->event(hs);
+}
+
+static void hid_del_idle_timer(HIDState *hs)
+{
+ if (hs->idle_timer) {
+ qemu_del_timer(hs->idle_timer);
+ qemu_free_timer(hs->idle_timer);
+ hs->idle_timer = NULL;
+ }
+}
+
+void hid_set_next_idle(HIDState *hs)
+{
+ if (hs->idle) {
+ uint64_t expire_time = qemu_get_clock_ns(vm_clock) +
+ get_ticks_per_sec() * hs->idle * 4 / 1000;
+ if (!hs->idle_timer) {
+ hs->idle_timer = qemu_new_timer_ns(vm_clock, hid_idle_timer, hs);
+ }
+ qemu_mod_timer_ns(hs->idle_timer, expire_time);
+ } else {
+ hid_del_idle_timer(hs);
+ }
}
static void hid_pointer_event_clear(HIDPointerEvent *e, int buttons)
@@ -232,6 +258,8 @@ int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
int index;
HIDPointerEvent *e;
+ hs->idle_pending = false;
+
hid_pointer_activate(hs);
/* When the buffer is empty, return the last event. Relative
@@ -319,6 +347,8 @@ int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
{
+ hs->idle_pending = false;
+
if (len < 2) {
return 0;
}
@@ -377,6 +407,8 @@ void hid_reset(HIDState *hs)
hs->n = 0;
hs->protocol = 1;
hs->idle = 0;
+ hs->idle_pending = false;
+ hid_del_idle_timer(hs);
}
void hid_free(HIDState *hs)
@@ -390,6 +422,7 @@ void hid_free(HIDState *hs)
qemu_remove_mouse_event_handler(hs->ptr.eh_entry);
break;
}
+ hid_del_idle_timer(hs);
}
void hid_init(HIDState *hs, int kind, HIDEventFunc event)
@@ -412,9 +445,7 @@ static int hid_post_load(void *opaque, int version_id)
{
HIDState *s = opaque;
- if (s->idle) {
- hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
- }
+ hid_set_next_idle(s);
return 0;
}
diff --git a/hw/hid.h b/hw/hid.h
index 100b121663..56c71ed5ae 100644
--- a/hw/hid.h
+++ b/hw/hid.h
@@ -43,7 +43,8 @@ struct HIDState {
int kind;
int32_t protocol;
uint8_t idle;
- int64_t next_idle_clock;
+ bool idle_pending;
+ QEMUTimer *idle_timer;
HIDEventFunc event;
};
@@ -52,7 +53,7 @@ void hid_reset(HIDState *hs);
void hid_free(HIDState *hs);
bool hid_has_events(HIDState *hs);
-void hid_set_next_idle(HIDState *hs, int64_t curtime);
+void hid_set_next_idle(HIDState *hs);
void hid_pointer_activate(HIDState *hs);
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len);
int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len);
diff --git a/hw/highbank.c b/hw/highbank.c
index 6005622f3a..98deca8bce 100644
--- a/hw/highbank.c
+++ b/hw/highbank.c
@@ -168,7 +168,7 @@ static void highbank_regs_class_init(ObjectClass *klass, void *data)
dc->reset = highbank_regs_reset;
}
-static TypeInfo highbank_regs_info = {
+static const TypeInfo highbank_regs_info = {
.name = "highbank-regs",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(HighbankRegsState),
diff --git a/hw/hpet.c b/hw/hpet.c
index 78c0662dfc..6efae55eee 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -745,7 +745,7 @@ static void hpet_device_class_init(ObjectClass *klass, void *data)
dc->props = hpet_device_properties;
}
-static TypeInfo hpet_device_info = {
+static const TypeInfo hpet_device_info = {
.name = "hpet",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(HPETState),
diff --git a/hw/i2c.c b/hw/i2c.c
index 296bece119..119e96bc0e 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -228,7 +228,7 @@ static void i2c_slave_class_init(ObjectClass *klass, void *data)
k->props = i2c_props;
}
-static TypeInfo i2c_slave_type_info = {
+static const TypeInfo i2c_slave_type_info = {
.name = TYPE_I2C_SLAVE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(I2CSlave),
diff --git a/hw/i82374.c b/hw/i82374.c
index 4a922c3f4e..6a62ba2ab8 100644
--- a/hw/i82374.c
+++ b/hw/i82374.c
@@ -153,7 +153,7 @@ static void i82374_class_init(ObjectClass *klass, void *data)
dc->props = i82374_properties;
}
-static TypeInfo i82374_isa_info = {
+static const TypeInfo i82374_isa_info = {
.name = "i82374",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISAi82374State),
diff --git a/hw/i82378.c b/hw/i82378.c
index c6b0b5ec55..0914d7bbfb 100644
--- a/hw/i82378.c
+++ b/hw/i82378.c
@@ -262,7 +262,7 @@ static void pci_i82378_class_init(ObjectClass *klass, void *data)
dc->props = i82378_properties;
}
-static TypeInfo pci_i82378_info = {
+static const TypeInfo pci_i82378_info = {
.name = "i82378",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIi82378State),
diff --git a/hw/i8254.c b/hw/i8254.c
index 7c2aa6238d..394b2e81d7 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -347,7 +347,7 @@ static void pit_class_initfn(ObjectClass *klass, void *data)
dc->props = pit_properties;
}
-static TypeInfo pit_info = {
+static const TypeInfo pit_info = {
.name = "isa-pit",
.parent = TYPE_PIT_COMMON,
.instance_size = sizeof(PITCommonState),
diff --git a/hw/i8254_common.c b/hw/i8254_common.c
index 08ab8d14bd..8c2e45a92e 100644
--- a/hw/i8254_common.c
+++ b/hw/i8254_common.c
@@ -294,7 +294,7 @@ static void pit_common_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo pit_common_type = {
+static const TypeInfo pit_common_type = {
.name = TYPE_PIT_COMMON,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(PITCommonState),
diff --git a/hw/i8259.c b/hw/i8259.c
index 8fc6339250..264879e097 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -481,7 +481,7 @@ static void i8259_class_init(ObjectClass *klass, void *data)
dc->reset = pic_reset;
}
-static TypeInfo i8259_info = {
+static const TypeInfo i8259_info = {
.name = "isa-i8259",
.instance_size = sizeof(PICCommonState),
.parent = TYPE_PIC_COMMON,
diff --git a/hw/i8259_common.c b/hw/i8259_common.c
index ab3d98b2a1..fc91056afb 100644
--- a/hw/i8259_common.c
+++ b/hw/i8259_common.c
@@ -144,7 +144,7 @@ static void pic_common_class_init(ObjectClass *klass, void *data)
ic->init = pic_init_common;
}
-static TypeInfo pic_common_type = {
+static const TypeInfo pic_common_type = {
.name = TYPE_PIC_COMMON,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(PICCommonState),
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index d0724499c7..21f50ea5be 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1247,7 +1247,7 @@ static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
dc->reset = sysbus_ahci_reset;
}
-static TypeInfo sysbus_ahci_info = {
+static const TypeInfo sysbus_ahci_info = {
.name = "sysbus-ahci",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysbusAHCIState),
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index ee855b670f..745ef94deb 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -342,7 +342,7 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
dc->props = cmd646_ide_properties;
}
-static TypeInfo cmd646_ide_info = {
+static const TypeInfo cmd646_ide_info = {
.name = "cmd646-ide",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIIDEState),
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index de39b3067a..1fb803d340 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -156,7 +156,7 @@ static void ich_ahci_class_init(ObjectClass *klass, void *data)
dc->reset = pci_ich9_reset;
}
-static TypeInfo ich_ahci_info = {
+static const TypeInfo ich_ahci_info = {
.name = "ich9-ahci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(AHCIPCIState),
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index aa0e7fa22d..fb7bb8201d 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -111,7 +111,7 @@ static void isa_ide_class_initfn(ObjectClass *klass, void *data)
dc->props = isa_ide_properties;
}
-static TypeInfo isa_ide_info = {
+static const TypeInfo isa_ide_info = {
.name = "isa-ide",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISAIDEState),
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index df95aec195..4d3e82266c 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -251,7 +251,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo piix3_ide_info = {
+static const TypeInfo piix3_ide_info = {
.name = "piix3-ide",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIIDEState),
@@ -271,7 +271,7 @@ static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
dc->unplug = pci_piix3_xen_ide_unplug;
}
-static TypeInfo piix3_ide_xen_info = {
+static const TypeInfo piix3_ide_xen_info = {
.name = "piix3-ide-xen",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIIDEState),
@@ -292,7 +292,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo piix4_ide_info = {
+static const TypeInfo piix4_ide_info = {
.name = "piix4-ide",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIIDEState),
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index d2fe77398f..c436b38bcb 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -216,7 +216,7 @@ static void ide_hd_class_init(ObjectClass *klass, void *data)
dc->props = ide_hd_properties;
}
-static TypeInfo ide_hd_info = {
+static const TypeInfo ide_hd_info = {
.name = "ide-hd",
.parent = TYPE_IDE_DEVICE,
.instance_size = sizeof(IDEDrive),
@@ -238,7 +238,7 @@ static void ide_cd_class_init(ObjectClass *klass, void *data)
dc->props = ide_cd_properties;
}
-static TypeInfo ide_cd_info = {
+static const TypeInfo ide_cd_info = {
.name = "ide-cd",
.parent = TYPE_IDE_DEVICE,
.instance_size = sizeof(IDEDrive),
@@ -260,7 +260,7 @@ static void ide_drive_class_init(ObjectClass *klass, void *data)
dc->props = ide_drive_properties;
}
-static TypeInfo ide_drive_info = {
+static const TypeInfo ide_drive_info = {
.name = "ide-drive",
.parent = TYPE_IDE_DEVICE,
.instance_size = sizeof(IDEDrive),
@@ -275,7 +275,7 @@ static void ide_device_class_init(ObjectClass *klass, void *data)
k->props = ide_props;
}
-static TypeInfo ide_device_type_info = {
+static const TypeInfo ide_device_type_info = {
.name = TYPE_IDE_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(IDEDevice),
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 14acb3ac04..f40c1adc8c 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -226,7 +226,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo via_ide_info = {
+static const TypeInfo via_ide_info = {
.name = "via-ide",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIIDEState),
diff --git a/hw/imx_ccm.c b/hw/imx_ccm.c
index 46962e4df9..477903a546 100644
--- a/hw/imx_ccm.c
+++ b/hw/imx_ccm.c
@@ -306,7 +306,7 @@ static void imx_ccm_class_init(ObjectClass *klass, void *data)
dc->desc = "i.MX Clock Control Module";
}
-static TypeInfo imx_ccm_info = {
+static const TypeInfo imx_ccm_info = {
.name = "imx_ccm",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(IMXCCMState),
diff --git a/hw/imx_serial.c b/hw/imx_serial.c
index 124dbb2860..77ed693a0c 100644
--- a/hw/imx_serial.c
+++ b/hw/imx_serial.c
@@ -452,7 +452,7 @@ static void imx_serial_class_init(ObjectClass *klass, void *data)
dc->props = imx32_serial_properties;
}
-static TypeInfo imx_serial_info = {
+static const TypeInfo imx_serial_info = {
.name = "imx-serial",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(IMXSerialState),
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 47fc9cb944..6c824dc36e 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -535,7 +535,7 @@ static void core_class_init(ObjectClass *klass, void *data)
dc->props = core_properties;
}
-static TypeInfo core_info = {
+static const TypeInfo core_info = {
.name = "integrator_core",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(integratorcm_state),
@@ -549,7 +549,7 @@ static void icp_pic_class_init(ObjectClass *klass, void *data)
sdc->init = icp_pic_init;
}
-static TypeInfo icp_pic_info = {
+static const TypeInfo icp_pic_info = {
.name = "integrator_pic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(icp_pic_state),
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 98ff93679d..784c229d8f 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1232,7 +1232,7 @@ static Property intel_hda_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
-static void intel_hda_class_init(ObjectClass *klass, void *data)
+static void intel_hda_class_init_common(ObjectClass *klass)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -1240,20 +1240,46 @@ static void intel_hda_class_init(ObjectClass *klass, void *data)
k->init = intel_hda_init;
k->exit = intel_hda_exit;
k->vendor_id = PCI_VENDOR_ID_INTEL;
- k->device_id = 0x2668;
- k->revision = 1;
k->class_id = PCI_CLASS_MULTIMEDIA_HD_AUDIO;
- dc->desc = "Intel HD Audio Controller";
dc->reset = intel_hda_reset;
dc->vmsd = &vmstate_intel_hda;
dc->props = intel_hda_properties;
}
-static TypeInfo intel_hda_info = {
+static void intel_hda_class_init_ich6(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ intel_hda_class_init_common(klass);
+ k->device_id = 0x2668;
+ k->revision = 1;
+ dc->desc = "Intel HD Audio Controller (ich6)";
+}
+
+static void intel_hda_class_init_ich9(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ intel_hda_class_init_common(klass);
+ k->device_id = 0x293e;
+ k->revision = 3;
+ dc->desc = "Intel HD Audio Controller (ich9)";
+}
+
+static const TypeInfo intel_hda_info_ich6 = {
.name = "intel-hda",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(IntelHDAState),
- .class_init = intel_hda_class_init,
+ .class_init = intel_hda_class_init_ich6,
+};
+
+static const TypeInfo intel_hda_info_ich9 = {
+ .name = "ich9-intel-hda",
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(IntelHDAState),
+ .class_init = intel_hda_class_init_ich9,
};
static void hda_codec_device_class_init(ObjectClass *klass, void *data)
@@ -1265,7 +1291,7 @@ static void hda_codec_device_class_init(ObjectClass *klass, void *data)
k->props = hda_props;
}
-static TypeInfo hda_codec_device_type_info = {
+static const TypeInfo hda_codec_device_type_info = {
.name = TYPE_HDA_CODEC_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(HDACodecDevice),
@@ -1277,7 +1303,8 @@ static TypeInfo hda_codec_device_type_info = {
static void intel_hda_register_types(void)
{
type_register_static(&hda_codec_bus_info);
- type_register_static(&intel_hda_info);
+ type_register_static(&intel_hda_info_ich6);
+ type_register_static(&intel_hda_info_ich9);
type_register_static(&hda_codec_device_type_info);
}
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 72730951a6..f06c2dcf2e 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -244,7 +244,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data)
dc->reset = ioapic_reset_common;
}
-static TypeInfo ioapic_info = {
+static const TypeInfo ioapic_info = {
.name = "ioapic",
.parent = TYPE_IOAPIC_COMMON,
.instance_size = sizeof(IOAPICCommonState),
diff --git a/hw/ioapic_common.c b/hw/ioapic_common.c
index 653eef2ce1..7dc552f033 100644
--- a/hw/ioapic_common.c
+++ b/hw/ioapic_common.c
@@ -103,7 +103,7 @@ static void ioapic_common_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo ioapic_common_type = {
+static const TypeInfo ioapic_common_type = {
.name = TYPE_IOAPIC_COMMON,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(IOAPICCommonState),
diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index d706e195df..95bceb5347 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -226,7 +226,7 @@ static void ioh3420_class_init(ObjectClass *klass, void *data)
dc->props = ioh3420_properties;
}
-static TypeInfo ioh3420_info = {
+static const TypeInfo ioh3420_info = {
.name = "ioh3420",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIESlot),
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 86b0bbd3d1..fce311bc2a 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -215,7 +215,7 @@ static void isabus_bridge_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo isabus_bridge_info = {
+static const TypeInfo isabus_bridge_info = {
.name = "isabus-bridge",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusDevice),
@@ -229,7 +229,7 @@ static void isa_device_class_init(ObjectClass *klass, void *data)
k->bus_type = TYPE_ISA_BUS;
}
-static TypeInfo isa_device_type_info = {
+static const TypeInfo isa_device_type_info = {
.name = TYPE_ISA_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(ISADevice),
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index c86fddd0b3..afaf9b3bbf 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -810,7 +810,7 @@ static void ivshmem_class_init(ObjectClass *klass, void *data)
dc->props = ivshmem_properties;
}
-static TypeInfo ivshmem_info = {
+static const TypeInfo ivshmem_info = {
.name = "ivshmem",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(IVShmemState),
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index f4a040631e..4822c485f2 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -277,7 +277,7 @@ static void jazz_led_class_init(ObjectClass *klass, void *data)
dc->reset = jazz_led_reset;
}
-static TypeInfo jazz_led_info = {
+static const TypeInfo jazz_led_info = {
.name = "jazz-led",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LedState),
diff --git a/hw/kvm/apic.c b/hw/kvm/apic.c
index a4e834744b..d994ea7c97 100644
--- a/hw/kvm/apic.c
+++ b/hw/kvm/apic.c
@@ -194,7 +194,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data)
k->external_nmi = kvm_apic_external_nmi;
}
-static TypeInfo kvm_apic_info = {
+static const TypeInfo kvm_apic_info = {
.name = "kvm-apic",
.parent = TYPE_APIC_COMMON,
.instance_size = sizeof(APICCommonState),
diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c
index be24973df9..fa40e283f7 100644
--- a/hw/kvm/clock.c
+++ b/hw/kvm/clock.c
@@ -118,7 +118,7 @@ static void kvmclock_class_init(ObjectClass *klass, void *data)
dc->vmsd = &kvmclock_vmsd;
}
-static TypeInfo kvmclock_info = {
+static const TypeInfo kvmclock_info = {
.name = "kvmclock",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(KVMClockState),
diff --git a/hw/kvm/i8254.c b/hw/kvm/i8254.c
index 57faf64ab2..04ad649b0e 100644
--- a/hw/kvm/i8254.c
+++ b/hw/kvm/i8254.c
@@ -302,7 +302,7 @@ static void kvm_pit_class_init(ObjectClass *klass, void *data)
dc->props = kvm_pit_properties;
}
-static TypeInfo kvm_pit_info = {
+static const TypeInfo kvm_pit_info = {
.name = "kvm-pit",
.parent = TYPE_PIT_COMMON,
.instance_size = sizeof(KVMPITState),
diff --git a/hw/kvm/i8259.c b/hw/kvm/i8259.c
index 70e1d185de..5ae8b6819b 100644
--- a/hw/kvm/i8259.c
+++ b/hw/kvm/i8259.c
@@ -123,7 +123,7 @@ static void kvm_i8259_class_init(ObjectClass *klass, void *data)
k->post_load = kvm_pic_put;
}
-static TypeInfo kvm_i8259_info = {
+static const TypeInfo kvm_i8259_info = {
.name = "kvm-i8259",
.parent = TYPE_PIC_COMMON,
.instance_size = sizeof(PICCommonState),
diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c
index 30db6230b4..23877d4259 100644
--- a/hw/kvm/ioapic.c
+++ b/hw/kvm/ioapic.c
@@ -150,7 +150,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
dc->props = kvm_ioapic_properties;
}
-static TypeInfo kvm_ioapic_info = {
+static const TypeInfo kvm_ioapic_info = {
.name = "kvm-ioapic",
.parent = TYPE_IOAPIC_COMMON,
.instance_size = sizeof(KVMIOAPICState),
diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c
index 81f4bcfdf6..1b5f416a78 100644
--- a/hw/kvmvapic.c
+++ b/hw/kvmvapic.c
@@ -804,7 +804,7 @@ static void vapic_class_init(ObjectClass *klass, void *data)
sc->init = vapic_init;
}
-static TypeInfo vapic_type = {
+static const TypeInfo vapic_type = {
.name = "kvmvapic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(VAPICROMState),
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 5adf91199b..969b634d47 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -1368,7 +1368,7 @@ static void lan9118_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lan9118;
}
-static TypeInfo lan9118_info = {
+static const TypeInfo lan9118_info = {
.name = "lan9118",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(lan9118_state),
diff --git a/hw/lance.c b/hw/lance.c
index b7265c0fed..a5997fd64e 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -155,7 +155,7 @@ static void lance_class_init(ObjectClass *klass, void *data)
dc->props = lance_properties;
}
-static TypeInfo lance_info = {
+static const TypeInfo lance_info = {
.name = "lance",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusPCNetState),
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index 7c2d202d6a..8c82c85f6d 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -144,7 +144,7 @@ static void lm32_juart_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lm32_juart;
}
-static TypeInfo lm32_juart_info = {
+static const TypeInfo lm32_juart_info = {
.name = "lm32-juart",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LM32JuartState),
diff --git a/hw/lm32_pic.c b/hw/lm32_pic.c
index 42d5602cf0..8f13355821 100644
--- a/hw/lm32_pic.c
+++ b/hw/lm32_pic.c
@@ -184,7 +184,7 @@ static void lm32_pic_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lm32_pic;
}
-static TypeInfo lm32_pic_info = {
+static const TypeInfo lm32_pic_info = {
.name = "lm32-pic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LM32PicState),
diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c
index e3a9db9748..187ef6d0d6 100644
--- a/hw/lm32_sys.c
+++ b/hw/lm32_sys.c
@@ -157,7 +157,7 @@ static void lm32_sys_class_init(ObjectClass *klass, void *data)
dc->props = lm32_sys_properties;
}
-static TypeInfo lm32_sys_info = {
+static const TypeInfo lm32_sys_info = {
.name = "lm32-sys",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LM32SysState),
diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c
index bd4c346386..db527e9dc6 100644
--- a/hw/lm32_timer.c
+++ b/hw/lm32_timer.c
@@ -215,7 +215,7 @@ static void lm32_timer_class_init(ObjectClass *klass, void *data)
dc->props = lm32_timer_properties;
}
-static TypeInfo lm32_timer_info = {
+static const TypeInfo lm32_timer_info = {
.name = "lm32-timer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LM32TimerState),
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index 89605b8e77..9c89cca49b 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -281,7 +281,7 @@ static void lm32_uart_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lm32_uart;
}
-static TypeInfo lm32_uart_info = {
+static const TypeInfo lm32_uart_info = {
.name = "lm32-uart",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LM32UartState),
diff --git a/hw/lm832x.c b/hw/lm832x.c
index 3649e3d249..af49dd68bf 100644
--- a/hw/lm832x.c
+++ b/hw/lm832x.c
@@ -506,7 +506,7 @@ static void lm8323_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lm_kbd;
}
-static TypeInfo lm8323_info = {
+static const TypeInfo lm8323_info = {
.name = "lm8323",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(LM823KbdState),
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 0aafb00b58..89c657fb00 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2126,7 +2126,7 @@ static void lsi_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lsi_scsi;
}
-static TypeInfo lsi_info = {
+static const TypeInfo lsi_info = {
.name = "lsi53c895a",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(LSIState),
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 393c5c049a..8f1ca3cccd 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -738,7 +738,7 @@ static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
dc->props = m48t59_isa_properties;
}
-static TypeInfo m48t59_isa_info = {
+static const TypeInfo m48t59_isa_info = {
.name = "m48t59_isa",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(M48t59ISAState),
@@ -762,7 +762,7 @@ static void m48t59_class_init(ObjectClass *klass, void *data)
dc->props = m48t59_properties;
}
-static TypeInfo m48t59_info = {
+static const TypeInfo m48t59_info = {
.name = "m48t59",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(M48t59SysBusState),
diff --git a/hw/macio.c b/hw/macio.c
index 362afdc7ec..675a71c051 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -90,7 +90,7 @@ static void macio_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_OTHERS << 8;
}
-static TypeInfo macio_info = {
+static const TypeInfo macio_info = {
.name = "macio",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(MacIOState),
diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c
index de16cfa090..511004b94e 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -288,7 +288,7 @@ static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
dc->props = mv88w8618_audio_properties;
}
-static TypeInfo mv88w8618_audio_info = {
+static const TypeInfo mv88w8618_audio_info = {
.name = "mv88w8618_audio",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_audio_state),
diff --git a/hw/max111x.c b/hw/max111x.c
index 67640f109a..de1be4ddd6 100644
--- a/hw/max111x.c
+++ b/hw/max111x.c
@@ -162,7 +162,7 @@ static void max1110_class_init(ObjectClass *klass, void *data)
k->transfer = max111x_transfer;
}
-static TypeInfo max1110_info = {
+static const TypeInfo max1110_info = {
.name = "max1110",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(MAX111xState),
@@ -177,7 +177,7 @@ static void max1111_class_init(ObjectClass *klass, void *data)
k->transfer = max111x_transfer;
}
-static TypeInfo max1111_info = {
+static const TypeInfo max1111_info = {
.name = "max1111",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(MAX111xState),
diff --git a/hw/max7310.c b/hw/max7310.c
index 1ed18ba876..de2221ba01 100644
--- a/hw/max7310.c
+++ b/hw/max7310.c
@@ -198,7 +198,7 @@ static void max7310_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_max7310;
}
-static TypeInfo max7310_info = {
+static const TypeInfo max7310_info = {
.name = "max7310",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(MAX7310State),
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 2ddd7de09e..2fb11f69a3 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -898,7 +898,7 @@ static void rtc_class_initfn(ObjectClass *klass, void *data)
dc->props = mc146818rtc_properties;
}
-static TypeInfo mc146818rtc_info = {
+static const TypeInfo mc146818rtc_info = {
.name = "mc146818rtc",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(RTCState),
diff --git a/hw/milkymist-ac97.c b/hw/milkymist-ac97.c
index f46af1c509..d51d1ac993 100644
--- a/hw/milkymist-ac97.c
+++ b/hw/milkymist-ac97.c
@@ -329,7 +329,7 @@ static void milkymist_ac97_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_milkymist_ac97;
}
-static TypeInfo milkymist_ac97_info = {
+static const TypeInfo milkymist_ac97_info = {
.name = "milkymist-ac97",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistAC97State),
diff --git a/hw/milkymist-hpdmc.c b/hw/milkymist-hpdmc.c
index fd54d3129a..ea4d210685 100644
--- a/hw/milkymist-hpdmc.c
+++ b/hw/milkymist-hpdmc.c
@@ -155,7 +155,7 @@ static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_milkymist_hpdmc;
}
-static TypeInfo milkymist_hpdmc_info = {
+static const TypeInfo milkymist_hpdmc_info = {
.name = "milkymist-hpdmc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistHpdmcState),
diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c
index f80befc53a..9d15309ab7 100644
--- a/hw/milkymist-memcard.c
+++ b/hw/milkymist-memcard.c
@@ -288,7 +288,7 @@ static void milkymist_memcard_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_milkymist_memcard;
}
-static TypeInfo milkymist_memcard_info = {
+static const TypeInfo milkymist_memcard_info = {
.name = "milkymist-memcard",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistMemcardState),
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index 4e92ac3dcb..43d6c195eb 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -535,7 +535,7 @@ static void milkymist_minimac2_class_init(ObjectClass *klass, void *data)
dc->props = milkymist_minimac2_properties;
}
-static TypeInfo milkymist_minimac2_info = {
+static const TypeInfo milkymist_minimac2_info = {
.name = "milkymist-minimac2",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistMinimac2State),
diff --git a/hw/milkymist-pfpu.c b/hw/milkymist-pfpu.c
index 0521829202..c347680ad7 100644
--- a/hw/milkymist-pfpu.c
+++ b/hw/milkymist-pfpu.c
@@ -529,7 +529,7 @@ static void milkymist_pfpu_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_milkymist_pfpu;
}
-static TypeInfo milkymist_pfpu_info = {
+static const TypeInfo milkymist_pfpu_info = {
.name = "milkymist-pfpu",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistPFPUState),
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index b7beb4bedb..01660bebf0 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -316,7 +316,7 @@ static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
dc->props = milkymist_softusb_properties;
}
-static TypeInfo milkymist_softusb_info = {
+static const TypeInfo milkymist_softusb_info = {
.name = "milkymist-softusb",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistSoftUsbState),
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index 796e795f04..e69ac6f047 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -323,7 +323,7 @@ static void milkymist_sysctl_class_init(ObjectClass *klass, void *data)
dc->props = milkymist_sysctl_properties;
}
-static TypeInfo milkymist_sysctl_info = {
+static const TypeInfo milkymist_sysctl_info = {
.name = "milkymist-sysctl",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistSysctlState),
diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c
index a11772aebe..42de10aafd 100644
--- a/hw/milkymist-tmu2.c
+++ b/hw/milkymist-tmu2.c
@@ -475,7 +475,7 @@ static void milkymist_tmu2_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_milkymist_tmu2;
}
-static TypeInfo milkymist_tmu2_info = {
+static const TypeInfo milkymist_tmu2_info = {
.name = "milkymist-tmu2",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistTMU2State),
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
index 19e9dbdc75..e73eb8476c 100644
--- a/hw/milkymist-uart.c
+++ b/hw/milkymist-uart.c
@@ -228,7 +228,7 @@ static void milkymist_uart_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_milkymist_uart;
}
-static TypeInfo milkymist_uart_info = {
+static const TypeInfo milkymist_uart_info = {
.name = "milkymist-uart",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistUartState),
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 561285154f..4d0a5dfb78 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -319,7 +319,7 @@ static void milkymist_vgafb_class_init(ObjectClass *klass, void *data)
dc->props = milkymist_vgafb_properties;
}
-static TypeInfo milkymist_vgafb_info = {
+static const TypeInfo milkymist_vgafb_info = {
.name = "milkymist-vgafb",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MilkymistVgafbState),
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 635143d20c..2250e675a5 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -1004,7 +1004,7 @@ static void mips_malta_class_init(ObjectClass *klass, void *data)
k->init = mips_malta_sysbus_device_init;
}
-static TypeInfo mips_malta_device = {
+static const TypeInfo mips_malta_device = {
.name = "mips-malta",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MaltaState),
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index bb752d3950..feac8159ee 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -269,7 +269,7 @@ static void mipsnet_class_init(ObjectClass *klass, void *data)
dc->props = mipsnet_properties;
}
-static TypeInfo mipsnet_info = {
+static const TypeInfo mipsnet_info = {
.name = "mipsnet",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MIPSnetState),
diff --git a/hw/mpc8544_guts.c b/hw/mpc8544_guts.c
index 84522e9722..9c57d7665f 100644
--- a/hw/mpc8544_guts.c
+++ b/hw/mpc8544_guts.c
@@ -128,7 +128,7 @@ static void mpc8544_guts_class_init(ObjectClass *klass, void *data)
k->init = mpc8544_guts_initfn;
}
-static TypeInfo mpc8544_guts_info = {
+static const TypeInfo mpc8544_guts_info = {
.name = "mpc8544-guts",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(GutsState),
diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c
index fb4b739c7c..7ae05e389f 100644
--- a/hw/mst_fpga.c
+++ b/hw/mst_fpga.c
@@ -248,7 +248,7 @@ static void mst_fpga_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_mst_fpga_regs;
}
-static TypeInfo mst_fpga_info = {
+static const TypeInfo mst_fpga_info = {
.name = "mainstone-fpga",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mst_irq_state),
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 77a585eee6..24a1722703 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -428,7 +428,7 @@ static void mv88w8618_eth_class_init(ObjectClass *klass, void *data)
dc->props = mv88w8618_eth_properties;
}
-static TypeInfo mv88w8618_eth_info = {
+static const TypeInfo mv88w8618_eth_info = {
.name = "mv88w8618_eth",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_eth_state),
@@ -643,7 +643,7 @@ static void musicpal_lcd_class_init(ObjectClass *klass, void *data)
dc->vmsd = &musicpal_lcd_vmsd;
}
-static TypeInfo musicpal_lcd_info = {
+static const TypeInfo musicpal_lcd_info = {
.name = "musicpal_lcd",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(musicpal_lcd_state),
@@ -762,7 +762,7 @@ static void mv88w8618_pic_class_init(ObjectClass *klass, void *data)
dc->vmsd = &mv88w8618_pic_vmsd;
}
-static TypeInfo mv88w8618_pic_info = {
+static const TypeInfo mv88w8618_pic_info = {
.name = "mv88w8618_pic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_pic_state),
@@ -939,7 +939,7 @@ static void mv88w8618_pit_class_init(ObjectClass *klass, void *data)
dc->vmsd = &mv88w8618_pit_vmsd;
}
-static TypeInfo mv88w8618_pit_info = {
+static const TypeInfo mv88w8618_pit_info = {
.name = "mv88w8618_pit",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_pit_state),
@@ -1019,7 +1019,7 @@ static void mv88w8618_flashcfg_class_init(ObjectClass *klass, void *data)
dc->vmsd = &mv88w8618_flashcfg_vmsd;
}
-static TypeInfo mv88w8618_flashcfg_info = {
+static const TypeInfo mv88w8618_flashcfg_info = {
.name = "mv88w8618_flashcfg",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_flashcfg_state),
@@ -1341,7 +1341,7 @@ static void musicpal_gpio_class_init(ObjectClass *klass, void *data)
dc->vmsd = &musicpal_gpio_vmsd;
}
-static TypeInfo musicpal_gpio_info = {
+static const TypeInfo musicpal_gpio_info = {
.name = "musicpal_gpio",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(musicpal_gpio_state),
@@ -1495,7 +1495,7 @@ static void musicpal_key_class_init(ObjectClass *klass, void *data)
dc->vmsd = &musicpal_key_vmsd;
}
-static TypeInfo musicpal_key_info = {
+static const TypeInfo musicpal_key_info = {
.name = "musicpal_key",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(musicpal_key_state),
@@ -1674,7 +1674,7 @@ static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data)
sdc->init = mv88w8618_wlan_init;
}
-static TypeInfo mv88w8618_wlan_info = {
+static const TypeInfo mv88w8618_wlan_info = {
.name = "mv88w8618_wlan",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusDevice),
diff --git a/hw/nand.c b/hw/nand.c
index 16950c5ec4..6054f46581 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -435,7 +435,7 @@ static void nand_class_init(ObjectClass *klass, void *data)
dc->props = nand_properties;
}
-static TypeInfo nand_info = {
+static const TypeInfo nand_info = {
.name = "nand",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NANDFlashState),
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index c2c00c215f..7c11229f1a 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -97,7 +97,7 @@ static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
dc->props = ne2000_isa_properties;
}
-static TypeInfo ne2000_isa_info = {
+static const TypeInfo ne2000_isa_info = {
.name = "ne2k_isa",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISANE2000State),
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 00efa74a0f..872115c454 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -773,7 +773,7 @@ static void ne2000_class_init(ObjectClass *klass, void *data)
dc->props = ne2000_properties;
}
-static TypeInfo ne2000_info = {
+static const TypeInfo ne2000_info = {
.name = "ne2k_pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCINE2000State),
diff --git a/hw/omap1.c b/hw/omap1.c
index 8536e96687..e85f2e2423 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -2830,7 +2830,7 @@ static void omap_rtc_tick(void *opaque)
s->round = 0;
}
- memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
+ localtime_r(&s->ti, &s->current_tm);
if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
s->status |= 0x40;
diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
index 25655325d0..15bdd629bf 100644
--- a/hw/omap_gpio.c
+++ b/hw/omap_gpio.c
@@ -747,7 +747,7 @@ static void omap_gpio_class_init(ObjectClass *klass, void *data)
dc->props = omap_gpio_properties;
}
-static TypeInfo omap_gpio_info = {
+static const TypeInfo omap_gpio_info = {
.name = "omap-gpio",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct omap_gpif_s),
@@ -776,7 +776,7 @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data)
dc->props = omap2_gpio_properties;
}
-static TypeInfo omap2_gpio_info = {
+static const TypeInfo omap2_gpio_info = {
.name = "omap2-gpio",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct omap2_gpif_s),
diff --git a/hw/omap_i2c.c b/hw/omap_i2c.c
index ba08e6400c..e0a5087f37 100644
--- a/hw/omap_i2c.c
+++ b/hw/omap_i2c.c
@@ -471,7 +471,7 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data)
dc->reset = omap_i2c_reset;
}
-static TypeInfo omap_i2c_info = {
+static const TypeInfo omap_i2c_info = {
.name = "omap_i2c",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(OMAPI2CState),
diff --git a/hw/omap_intc.c b/hw/omap_intc.c
index 61e0dafbdd..113725ef98 100644
--- a/hw/omap_intc.c
+++ b/hw/omap_intc.c
@@ -389,7 +389,7 @@ static void omap_intc_class_init(ObjectClass *klass, void *data)
dc->props = omap_intc_properties;
}
-static TypeInfo omap_intc_info = {
+static const TypeInfo omap_intc_info = {
.name = "omap-intc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct omap_intr_handler_s),
@@ -633,7 +633,7 @@ static void omap2_intc_class_init(ObjectClass *klass, void *data)
dc->props = omap2_intc_properties;
}
-static TypeInfo omap2_intc_info = {
+static const TypeInfo omap2_intc_info = {
.name = "omap2-intc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct omap_intr_handler_s),
diff --git a/hw/onenand.c b/hw/onenand.c
index 26bf991d6d..b82bf7d333 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -821,7 +821,7 @@ static void onenand_class_init(ObjectClass *klass, void *data)
dc->props = onenand_properties;
}
-static TypeInfo onenand_info = {
+static const TypeInfo onenand_info = {
.name = "onenand",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(OneNANDState),
diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c
index a0dfdce1f9..746a959f6b 100644
--- a/hw/opencores_eth.c
+++ b/hw/opencores_eth.c
@@ -718,7 +718,7 @@ static void open_eth_class_init(ObjectClass *klass, void *data)
dc->props = open_eth_properties;
}
-static TypeInfo open_eth_info = {
+static const TypeInfo open_eth_info = {
.name = "open_eth",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(OpenEthState),
diff --git a/hw/openpic.c b/hw/openpic.c
index 9c956b9dcc..23fa8f9635 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -39,26 +39,32 @@
#include "openpic.h"
#include "sysbus.h"
#include "pci/msi.h"
+#include "qemu/bitops.h"
//#define DEBUG_OPENPIC
#ifdef DEBUG_OPENPIC
-#define DPRINTF(fmt, ...) do { printf(fmt , ## __VA_ARGS__); } while (0)
+static const int debug_openpic = 1;
#else
-#define DPRINTF(fmt, ...) do { } while (0)
+static const int debug_openpic = 0;
#endif
+#define DPRINTF(fmt, ...) do { \
+ if (debug_openpic) { \
+ printf(fmt , ## __VA_ARGS__); \
+ } \
+ } while (0)
+
#define MAX_CPU 15
#define MAX_SRC 256
#define MAX_TMR 4
-#define VECTOR_BITS 8
#define MAX_IPI 4
#define MAX_MSI 8
#define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR)
#define VID 0x03 /* MPIC version ID */
/* OpenPIC capability flags */
-#define OPENPIC_FLAG_IDE_CRIT (1 << 0)
+#define OPENPIC_FLAG_IDR_CRIT (1 << 0)
/* OpenPIC address map */
#define OPENPIC_GLB_REG_START 0x0
@@ -115,14 +121,22 @@
#define FSL_BRR1_IPMJ (0x00 << 8) /* 8 bit IP major number */
#define FSL_BRR1_IPMN 0x00 /* 8 bit IP minor number */
-#define FREP_NIRQ_SHIFT 16
-#define FREP_NCPU_SHIFT 8
-#define FREP_VID_SHIFT 0
+#define FRR_NIRQ_SHIFT 16
+#define FRR_NCPU_SHIFT 8
+#define FRR_VID_SHIFT 0
#define VID_REVISION_1_2 2
#define VID_REVISION_1_3 3
-#define VENI_GENERIC 0x00000000 /* Generic Vendor ID */
+#define VIR_GENERIC 0x00000000 /* Generic Vendor ID */
+
+#define GCR_RESET 0x80000000
+#define GCR_MODE_PASS 0x00000000
+#define GCR_MODE_MIXED 0x20000000
+#define GCR_MODE_PROXY 0x60000000
+
+#define TBCR_CI 0x80000000 /* count inhibit */
+#define TCCR_TOG 0x80000000 /* toggles when decrement to zero */
#define IDR_EP_SHIFT 31
#define IDR_EP_MASK (1 << IDR_EP_SHIFT)
@@ -137,27 +151,13 @@
#define MSIIR_IBS_SHIFT 24
#define MSIIR_IBS_MASK (0x1f << MSIIR_IBS_SHIFT)
-#define BF_WIDTH(_bits_) \
-(((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
-
-static inline void set_bit(uint32_t *field, int bit)
-{
- field[bit >> 5] |= 1 << (bit & 0x1F);
-}
-
-static inline void reset_bit(uint32_t *field, int bit)
-{
- field[bit >> 5] &= ~(1 << (bit & 0x1F));
-}
-
-static inline int test_bit(uint32_t *field, int bit)
-{
- return (field[bit >> 5] & 1 << (bit & 0x1F)) != 0;
-}
-
static int get_current_cpu(void)
{
- return cpu_single_env->cpu_index;
+ if (!cpu_single_env) {
+ return -1;
+ }
+
+ return cpu_single_env->cpu_index;
}
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
@@ -165,43 +165,61 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
uint32_t val, int idx);
-typedef struct IRQ_queue_t {
- uint32_t queue[BF_WIDTH(MAX_IRQ)];
+typedef enum IRQType {
+ IRQ_TYPE_NORMAL = 0,
+ IRQ_TYPE_FSLINT, /* FSL internal interrupt -- level only */
+ IRQ_TYPE_FSLSPECIAL, /* FSL timer/IPI interrupt, edge, no polarity */
+} IRQType;
+
+typedef struct IRQQueue {
+ /* Round up to the nearest 64 IRQs so that the queue length
+ * won't change when moving between 32 and 64 bit hosts.
+ */
+ unsigned long queue[BITS_TO_LONGS((MAX_IRQ + 63) & ~63)];
int next;
int priority;
- int pending; /* nr of pending bits in queue */
-} IRQ_queue_t;
+} IRQQueue;
-typedef struct IRQ_src_t {
- uint32_t ipvp; /* IRQ vector/priority register */
- uint32_t ide; /* IRQ destination register */
+typedef struct IRQSource {
+ uint32_t ivpr; /* IRQ vector/priority register */
+ uint32_t idr; /* IRQ destination register */
+ uint32_t destmask; /* bitmap of CPU destinations */
int last_cpu;
+ int output; /* IRQ level, e.g. OPENPIC_OUTPUT_INT */
int pending; /* TRUE if IRQ is pending */
-} IRQ_src_t;
-
-#define IPVP_MASK_SHIFT 31
-#define IPVP_MASK_MASK (1 << IPVP_MASK_SHIFT)
-#define IPVP_ACTIVITY_SHIFT 30
-#define IPVP_ACTIVITY_MASK (1 << IPVP_ACTIVITY_SHIFT)
-#define IPVP_MODE_SHIFT 29
-#define IPVP_MODE_MASK (1 << IPVP_MODE_SHIFT)
-#define IPVP_POLARITY_SHIFT 23
-#define IPVP_POLARITY_MASK (1 << IPVP_POLARITY_SHIFT)
-#define IPVP_SENSE_SHIFT 22
-#define IPVP_SENSE_MASK (1 << IPVP_SENSE_SHIFT)
-
-#define IPVP_PRIORITY_MASK (0x1F << 16)
-#define IPVP_PRIORITY(_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16))
-#define IPVP_VECTOR_MASK ((1 << VECTOR_BITS) - 1)
-#define IPVP_VECTOR(_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK)
-
-typedef struct IRQ_dst_t {
- uint32_t pctp; /* CPU current task priority */
- uint32_t pcsr; /* CPU sensitivity register */
- IRQ_queue_t raised;
- IRQ_queue_t servicing;
+ IRQType type;
+ bool level:1; /* level-triggered */
+ bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */
+} IRQSource;
+
+#define IVPR_MASK_SHIFT 31
+#define IVPR_MASK_MASK (1 << IVPR_MASK_SHIFT)
+#define IVPR_ACTIVITY_SHIFT 30
+#define IVPR_ACTIVITY_MASK (1 << IVPR_ACTIVITY_SHIFT)
+#define IVPR_MODE_SHIFT 29
+#define IVPR_MODE_MASK (1 << IVPR_MODE_SHIFT)
+#define IVPR_POLARITY_SHIFT 23
+#define IVPR_POLARITY_MASK (1 << IVPR_POLARITY_SHIFT)
+#define IVPR_SENSE_SHIFT 22
+#define IVPR_SENSE_MASK (1 << IVPR_SENSE_SHIFT)
+
+#define IVPR_PRIORITY_MASK (0xF << 16)
+#define IVPR_PRIORITY(_ivprr_) ((int)(((_ivprr_) & IVPR_PRIORITY_MASK) >> 16))
+#define IVPR_VECTOR(opp, _ivprr_) ((_ivprr_) & (opp)->vector_mask)
+
+/* IDR[EP/CI] are only for FSL MPIC prior to v4.0 */
+#define IDR_EP 0x80000000 /* external pin */
+#define IDR_CI 0x40000000 /* critical interrupt */
+
+typedef struct IRQDest {
+ int32_t ctpr; /* CPU current task priority */
+ IRQQueue raised;
+ IRQQueue servicing;
qemu_irq *irqs;
-} IRQ_dst_t;
+
+ /* Count of IRQ sources asserting on non-INT outputs */
+ uint32_t outputs_active[OPENPIC_OUTPUT_NB];
+} IRQDest;
typedef struct OpenPICState {
SysBusDevice busdev;
@@ -212,31 +230,32 @@ typedef struct OpenPICState {
uint32_t flags;
uint32_t nb_irqs;
uint32_t vid;
- uint32_t veni; /* Vendor identification register */
- uint32_t spve_mask;
- uint32_t tifr_reset;
- uint32_t ipvp_reset;
- uint32_t ide_reset;
+ uint32_t vir; /* Vendor identification register */
+ uint32_t vector_mask;
+ uint32_t tfrr_reset;
+ uint32_t ivpr_reset;
+ uint32_t idr_reset;
uint32_t brr1;
+ uint32_t mpic_mode_mask;
/* Sub-regions */
MemoryRegion sub_io_mem[5];
/* Global registers */
- uint32_t frep; /* Feature reporting register */
- uint32_t glbc; /* Global configuration register */
- uint32_t pint; /* Processor initialization register */
+ uint32_t frr; /* Feature reporting register */
+ uint32_t gcr; /* Global configuration register */
+ uint32_t pir; /* Processor initialization register */
uint32_t spve; /* Spurious vector register */
- uint32_t tifr; /* Timer frequency reporting register */
+ uint32_t tfrr; /* Timer frequency reporting register */
/* Source registers */
- IRQ_src_t src[MAX_IRQ];
+ IRQSource src[MAX_IRQ];
/* Local registers per output pin */
- IRQ_dst_t dst[MAX_CPU];
+ IRQDest dst[MAX_CPU];
uint32_t nb_cpus;
/* Timer registers */
struct {
- uint32_t ticc; /* Global timer current count register */
- uint32_t tibc; /* Global timer base count register */
+ uint32_t tccr; /* Global timer current count register */
+ uint32_t tbcr; /* Global timer base count register */
} timers[MAX_TMR];
/* Shared MSI registers */
struct {
@@ -248,156 +267,195 @@ typedef struct OpenPICState {
uint32_t irq_msi;
} OpenPICState;
-static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src);
-
-static inline void IRQ_setbit(IRQ_queue_t *q, int n_IRQ)
+static inline void IRQ_setbit(IRQQueue *q, int n_IRQ)
{
- q->pending++;
- set_bit(q->queue, n_IRQ);
+ set_bit(n_IRQ, q->queue);
}
-static inline void IRQ_resetbit(IRQ_queue_t *q, int n_IRQ)
+static inline void IRQ_resetbit(IRQQueue *q, int n_IRQ)
{
- q->pending--;
- reset_bit(q->queue, n_IRQ);
+ clear_bit(n_IRQ, q->queue);
}
-static inline int IRQ_testbit(IRQ_queue_t *q, int n_IRQ)
+static inline int IRQ_testbit(IRQQueue *q, int n_IRQ)
{
- return test_bit(q->queue, n_IRQ);
+ return test_bit(n_IRQ, q->queue);
}
-static void IRQ_check(OpenPICState *opp, IRQ_queue_t *q)
+static void IRQ_check(OpenPICState *opp, IRQQueue *q)
{
- int next, i;
- int priority;
-
- next = -1;
- priority = -1;
+ int irq = -1;
+ int next = -1;
+ int priority = -1;
+
+ for (;;) {
+ irq = find_next_bit(q->queue, opp->max_irq, irq + 1);
+ if (irq == opp->max_irq) {
+ break;
+ }
- if (!q->pending) {
- /* IRQ bitmap is empty */
- goto out;
- }
+ DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n",
+ irq, IVPR_PRIORITY(opp->src[irq].ivpr), priority);
- for (i = 0; i < opp->max_irq; i++) {
- if (IRQ_testbit(q, i)) {
- DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
- i, IPVP_PRIORITY(opp->src[i].ipvp), priority);
- if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) {
- next = i;
- priority = IPVP_PRIORITY(opp->src[i].ipvp);
- }
+ if (IVPR_PRIORITY(opp->src[irq].ivpr) > priority) {
+ next = irq;
+ priority = IVPR_PRIORITY(opp->src[irq].ivpr);
}
}
-out:
q->next = next;
q->priority = priority;
}
-static int IRQ_get_next(OpenPICState *opp, IRQ_queue_t *q)
+static int IRQ_get_next(OpenPICState *opp, IRQQueue *q)
{
- if (q->next == -1) {
- /* XXX: optimize */
- IRQ_check(opp, q);
- }
+ /* XXX: optimize */
+ IRQ_check(opp, q);
return q->next;
}
-static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ)
+static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ,
+ bool active, bool was_active)
{
- IRQ_dst_t *dst;
- IRQ_src_t *src;
+ IRQDest *dst;
+ IRQSource *src;
int priority;
dst = &opp->dst[n_CPU];
src = &opp->src[n_IRQ];
- priority = IPVP_PRIORITY(src->ipvp);
- if (priority <= dst->pctp) {
- /* Too low priority */
- DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",
- __func__, n_IRQ, n_CPU);
+
+ DPRINTF("%s: IRQ %d active %d was %d\n",
+ __func__, n_IRQ, active, was_active);
+
+ if (src->output != OPENPIC_OUTPUT_INT) {
+ DPRINTF("%s: output %d irq %d active %d was %d count %d\n",
+ __func__, src->output, n_IRQ, active, was_active,
+ dst->outputs_active[src->output]);
+
+ /* On Freescale MPIC, critical interrupts ignore priority,
+ * IACK, EOI, etc. Before MPIC v4.1 they also ignore
+ * masking.
+ */
+ if (active) {
+ if (!was_active && dst->outputs_active[src->output]++ == 0) {
+ DPRINTF("%s: Raise OpenPIC output %d cpu %d irq %d\n",
+ __func__, src->output, n_CPU, n_IRQ);
+ qemu_irq_raise(dst->irqs[src->output]);
+ }
+ } else {
+ if (was_active && --dst->outputs_active[src->output] == 0) {
+ DPRINTF("%s: Lower OpenPIC output %d cpu %d irq %d\n",
+ __func__, src->output, n_CPU, n_IRQ);
+ qemu_irq_lower(dst->irqs[src->output]);
+ }
+ }
+
return;
}
- if (IRQ_testbit(&dst->raised, n_IRQ)) {
- /* Interrupt miss */
- DPRINTF("%s: IRQ %d was missed on CPU %d\n",
- __func__, n_IRQ, n_CPU);
- return;
+
+ priority = IVPR_PRIORITY(src->ivpr);
+
+ /* Even if the interrupt doesn't have enough priority,
+ * it is still raised, in case ctpr is lowered later.
+ */
+ if (active) {
+ IRQ_setbit(&dst->raised, n_IRQ);
+ } else {
+ IRQ_resetbit(&dst->raised, n_IRQ);
}
- src->ipvp |= IPVP_ACTIVITY_MASK;
- IRQ_setbit(&dst->raised, n_IRQ);
- if (priority < dst->raised.priority) {
- /* An higher priority IRQ is already raised */
- DPRINTF("%s: IRQ %d is hidden by raised IRQ %d on CPU %d\n",
- __func__, n_IRQ, dst->raised.next, n_CPU);
- return;
+
+ IRQ_check(opp, &dst->raised);
+
+ if (active && priority <= dst->ctpr) {
+ DPRINTF("%s: IRQ %d priority %d too low for ctpr %d on CPU %d\n",
+ __func__, n_IRQ, priority, dst->ctpr, n_CPU);
+ active = 0;
}
- IRQ_get_next(opp, &dst->raised);
- if (IRQ_get_next(opp, &dst->servicing) != -1 &&
- priority <= dst->servicing.priority) {
- DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
- __func__, n_IRQ, dst->servicing.next, n_CPU);
- /* Already servicing a higher priority IRQ */
- return;
+
+ if (active) {
+ if (IRQ_get_next(opp, &dst->servicing) >= 0 &&
+ priority <= dst->servicing.priority) {
+ DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
+ __func__, n_IRQ, dst->servicing.next, n_CPU);
+ } else {
+ DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d/%d\n",
+ __func__, n_CPU, n_IRQ, dst->raised.next);
+ qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
+ }
+ } else {
+ IRQ_get_next(opp, &dst->servicing);
+ if (dst->raised.priority > dst->ctpr &&
+ dst->raised.priority > dst->servicing.priority) {
+ DPRINTF("%s: IRQ %d inactive, IRQ %d prio %d above %d/%d, CPU %d\n",
+ __func__, n_IRQ, dst->raised.next, dst->raised.priority,
+ dst->ctpr, dst->servicing.priority, n_CPU);
+ /* IRQ line stays asserted */
+ } else {
+ DPRINTF("%s: IRQ %d inactive, current prio %d/%d, CPU %d\n",
+ __func__, n_IRQ, dst->ctpr, dst->servicing.priority, n_CPU);
+ qemu_irq_lower(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
+ }
}
- DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
- openpic_irq_raise(opp, n_CPU, src);
}
/* update pic state because registers for n_IRQ have changed value */
static void openpic_update_irq(OpenPICState *opp, int n_IRQ)
{
- IRQ_src_t *src;
+ IRQSource *src;
+ bool active, was_active;
int i;
src = &opp->src[n_IRQ];
+ active = src->pending;
- if (!src->pending) {
- /* no irq pending */
- DPRINTF("%s: IRQ %d is not pending\n", __func__, n_IRQ);
- return;
- }
- if (src->ipvp & IPVP_MASK_MASK) {
+ if ((src->ivpr & IVPR_MASK_MASK) && !src->nomask) {
/* Interrupt source is disabled */
DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);
- return;
+ active = false;
}
- if (IPVP_PRIORITY(src->ipvp) == 0) {
- /* Priority set to zero */
- DPRINTF("%s: IRQ %d has 0 priority\n", __func__, n_IRQ);
+
+ was_active = !!(src->ivpr & IVPR_ACTIVITY_MASK);
+
+ /*
+ * We don't have a similar check for already-active because
+ * ctpr may have changed and we need to withdraw the interrupt.
+ */
+ if (!active && !was_active) {
+ DPRINTF("%s: IRQ %d is already inactive\n", __func__, n_IRQ);
return;
}
- if (src->ipvp & IPVP_ACTIVITY_MASK) {
- /* IRQ already active */
- DPRINTF("%s: IRQ %d is already active\n", __func__, n_IRQ);
- return;
+
+ if (active) {
+ src->ivpr |= IVPR_ACTIVITY_MASK;
+ } else {
+ src->ivpr &= ~IVPR_ACTIVITY_MASK;
}
- if (src->ide == 0x00000000) {
+
+ if (src->idr == 0) {
/* No target */
DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);
return;
}
- if (src->ide == (1 << src->last_cpu)) {
+ if (src->idr == (1 << src->last_cpu)) {
/* Only one CPU is allowed to receive this IRQ */
- IRQ_local_pipe(opp, src->last_cpu, n_IRQ);
- } else if (!(src->ipvp & IPVP_MODE_MASK)) {
+ IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active);
+ } else if (!(src->ivpr & IVPR_MODE_MASK)) {
/* Directed delivery mode */
for (i = 0; i < opp->nb_cpus; i++) {
- if (src->ide & (1 << i)) {
- IRQ_local_pipe(opp, i, n_IRQ);
+ if (src->destmask & (1 << i)) {
+ IRQ_local_pipe(opp, i, n_IRQ, active, was_active);
}
}
} else {
/* Distributed delivery mode */
for (i = src->last_cpu + 1; i != src->last_cpu; i++) {
- if (i == opp->nb_cpus)
+ if (i == opp->nb_cpus) {
i = 0;
- if (src->ide & (1 << i)) {
- IRQ_local_pipe(opp, i, n_IRQ);
+ }
+ if (src->destmask & (1 << i)) {
+ IRQ_local_pipe(opp, i, n_IRQ, active, was_active);
src->last_cpu = i;
break;
}
@@ -408,23 +466,38 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)
static void openpic_set_irq(void *opaque, int n_IRQ, int level)
{
OpenPICState *opp = opaque;
- IRQ_src_t *src;
+ IRQSource *src;
+
+ if (n_IRQ >= MAX_IRQ) {
+ fprintf(stderr, "%s: IRQ %d out of range\n", __func__, n_IRQ);
+ abort();
+ }
src = &opp->src[n_IRQ];
- DPRINTF("openpic: set irq %d = %d ipvp=%08x\n",
- n_IRQ, level, src->ipvp);
- if (src->ipvp & IPVP_SENSE_MASK) {
+ DPRINTF("openpic: set irq %d = %d ivpr=0x%08x\n",
+ n_IRQ, level, src->ivpr);
+ if (src->level) {
/* level-sensitive irq */
src->pending = level;
- if (!level) {
- src->ipvp &= ~IPVP_ACTIVITY_MASK;
- }
+ openpic_update_irq(opp, n_IRQ);
} else {
/* edge-sensitive irq */
- if (level)
+ if (level) {
src->pending = 1;
+ openpic_update_irq(opp, n_IRQ);
+ }
+
+ if (src->output != OPENPIC_OUTPUT_INT) {
+ /* Edge-triggered interrupts shouldn't be used
+ * with non-INT delivery, but just in case,
+ * try to make it do something sane rather than
+ * cause an interrupt storm. This is close to
+ * what you'd probably see happen in real hardware.
+ */
+ src->pending = 0;
+ openpic_update_irq(opp, n_IRQ);
+ }
}
- openpic_update_irq(opp, n_IRQ);
}
static void openpic_reset(DeviceState *d)
@@ -432,79 +505,154 @@ static void openpic_reset(DeviceState *d)
OpenPICState *opp = FROM_SYSBUS(typeof (*opp), sysbus_from_qdev(d));
int i;
- opp->glbc = 0x80000000;
+ opp->gcr = GCR_RESET;
/* Initialise controller registers */
- opp->frep = ((opp->nb_irqs -1) << FREP_NIRQ_SHIFT) |
- ((opp->nb_cpus -1) << FREP_NCPU_SHIFT) |
- (opp->vid << FREP_VID_SHIFT);
+ opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) |
+ ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) |
+ (opp->vid << FRR_VID_SHIFT);
- opp->pint = 0x00000000;
- opp->spve = -1 & opp->spve_mask;
- opp->tifr = opp->tifr_reset;
+ opp->pir = 0;
+ opp->spve = -1 & opp->vector_mask;
+ opp->tfrr = opp->tfrr_reset;
/* Initialise IRQ sources */
for (i = 0; i < opp->max_irq; i++) {
- opp->src[i].ipvp = opp->ipvp_reset;
- opp->src[i].ide = opp->ide_reset;
+ opp->src[i].ivpr = opp->ivpr_reset;
+ opp->src[i].idr = opp->idr_reset;
+
+ switch (opp->src[i].type) {
+ case IRQ_TYPE_NORMAL:
+ opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK);
+ break;
+
+ case IRQ_TYPE_FSLINT:
+ opp->src[i].ivpr |= IVPR_POLARITY_MASK;
+ break;
+
+ case IRQ_TYPE_FSLSPECIAL:
+ break;
+ }
}
/* Initialise IRQ destinations */
for (i = 0; i < MAX_CPU; i++) {
- opp->dst[i].pctp = 0x0000000F;
- opp->dst[i].pcsr = 0x00000000;
- memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));
+ opp->dst[i].ctpr = 15;
+ memset(&opp->dst[i].raised, 0, sizeof(IRQQueue));
opp->dst[i].raised.next = -1;
- memset(&opp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
+ memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue));
opp->dst[i].servicing.next = -1;
}
/* Initialise timers */
for (i = 0; i < MAX_TMR; i++) {
- opp->timers[i].ticc = 0x00000000;
- opp->timers[i].tibc = 0x80000000;
+ opp->timers[i].tccr = 0;
+ opp->timers[i].tbcr = TBCR_CI;
}
/* Go out of RESET state */
- opp->glbc = 0x00000000;
+ opp->gcr = 0;
}
-static inline uint32_t read_IRQreg_ide(OpenPICState *opp, int n_IRQ)
+static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ)
{
- return opp->src[n_IRQ].ide;
+ return opp->src[n_IRQ].idr;
}
-static inline uint32_t read_IRQreg_ipvp(OpenPICState *opp, int n_IRQ)
+static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ)
{
- return opp->src[n_IRQ].ipvp;
+ return opp->src[n_IRQ].ivpr;
}
-static inline void write_IRQreg_ide(OpenPICState *opp, int n_IRQ, uint32_t val)
+static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val)
{
- uint32_t tmp;
+ IRQSource *src = &opp->src[n_IRQ];
+ uint32_t normal_mask = (1UL << opp->nb_cpus) - 1;
+ uint32_t crit_mask = 0;
+ uint32_t mask = normal_mask;
+ int crit_shift = IDR_EP_SHIFT - opp->nb_cpus;
+ int i;
+
+ if (opp->flags & OPENPIC_FLAG_IDR_CRIT) {
+ crit_mask = mask << crit_shift;
+ mask |= crit_mask | IDR_EP;
+ }
+
+ src->idr = val & mask;
+ DPRINTF("Set IDR %d to 0x%08x\n", n_IRQ, src->idr);
+
+ if (opp->flags & OPENPIC_FLAG_IDR_CRIT) {
+ if (src->idr & crit_mask) {
+ if (src->idr & normal_mask) {
+ DPRINTF("%s: IRQ configured for multiple output types, using "
+ "critical\n", __func__);
+ }
- tmp = val & 0xC0000000;
- tmp |= val & ((1ULL << MAX_CPU) - 1);
- opp->src[n_IRQ].ide = tmp;
- DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide);
+ src->output = OPENPIC_OUTPUT_CINT;
+ src->nomask = true;
+ src->destmask = 0;
+
+ for (i = 0; i < opp->nb_cpus; i++) {
+ int n_ci = IDR_CI0_SHIFT - i;
+
+ if (src->idr & (1UL << n_ci)) {
+ src->destmask |= 1UL << i;
+ }
+ }
+ } else {
+ src->output = OPENPIC_OUTPUT_INT;
+ src->nomask = false;
+ src->destmask = src->idr & normal_mask;
+ }
+ } else {
+ src->destmask = src->idr;
+ }
}
-static inline void write_IRQreg_ipvp(OpenPICState *opp, int n_IRQ, uint32_t val)
+static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
{
- /* NOTE: not fully accurate for special IRQs, but simple and sufficient */
+ uint32_t mask;
+
+ /* NOTE when implementing newer FSL MPIC models: starting with v4.0,
+ * the polarity bit is read-only on internal interrupts.
+ */
+ mask = IVPR_MASK_MASK | IVPR_PRIORITY_MASK | IVPR_SENSE_MASK |
+ IVPR_POLARITY_MASK | opp->vector_mask;
+
/* ACTIVITY bit is read-only */
- opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp & 0x40000000)
- | (val & 0x800F00FF);
+ opp->src[n_IRQ].ivpr =
+ (opp->src[n_IRQ].ivpr & IVPR_ACTIVITY_MASK) | (val & mask);
+
+ /* For FSL internal interrupts, The sense bit is reserved and zero,
+ * and the interrupt is always level-triggered. Timers and IPIs
+ * have no sense or polarity bits, and are edge-triggered.
+ */
+ switch (opp->src[n_IRQ].type) {
+ case IRQ_TYPE_NORMAL:
+ opp->src[n_IRQ].level = !!(opp->src[n_IRQ].ivpr & IVPR_SENSE_MASK);
+ break;
+
+ case IRQ_TYPE_FSLINT:
+ opp->src[n_IRQ].ivpr &= ~IVPR_SENSE_MASK;
+ break;
+
+ case IRQ_TYPE_FSLSPECIAL:
+ opp->src[n_IRQ].ivpr &= ~(IVPR_POLARITY_MASK | IVPR_SENSE_MASK);
+ break;
+ }
+
openpic_update_irq(opp, n_IRQ);
- DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", n_IRQ, val,
- opp->src[n_IRQ].ipvp);
+ DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x\n", n_IRQ, val,
+ opp->src[n_IRQ].ivpr);
}
static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
unsigned len)
{
OpenPICState *opp = opaque;
- IRQ_dst_t *dst;
+ IRQDest *dst;
int idx;
- DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
+ DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
+ __func__, addr, val);
+ if (addr & 0xF) {
return;
+ }
switch (addr) {
case 0x00: /* Block Revision Register1 (BRR1) is Readonly */
break;
@@ -518,41 +666,55 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
case 0xB0:
openpic_cpu_write_internal(opp, addr, val, get_current_cpu());
break;
- case 0x1000: /* FREP */
+ case 0x1000: /* FRR */
break;
- case 0x1020: /* GLBC */
- if (val & 0x80000000) {
+ case 0x1020: /* GCR */
+ if (val & GCR_RESET) {
openpic_reset(&opp->busdev.qdev);
+ } else if (opp->mpic_mode_mask) {
+ CPUArchState *env;
+ int mpic_proxy = 0;
+
+ opp->gcr &= ~opp->mpic_mode_mask;
+ opp->gcr |= val & opp->mpic_mode_mask;
+
+ /* Set external proxy mode */
+ if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
+ mpic_proxy = 1;
+ }
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ env->mpic_proxy = mpic_proxy;
+ }
}
break;
- case 0x1080: /* VENI */
+ case 0x1080: /* VIR */
break;
- case 0x1090: /* PINT */
+ case 0x1090: /* PIR */
for (idx = 0; idx < opp->nb_cpus; idx++) {
- if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) {
+ if ((val & (1 << idx)) && !(opp->pir & (1 << idx))) {
DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx);
dst = &opp->dst[idx];
qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]);
- } else if (!(val & (1 << idx)) && (opp->pint & (1 << idx))) {
+ } else if (!(val & (1 << idx)) && (opp->pir & (1 << idx))) {
DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx);
dst = &opp->dst[idx];
qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]);
}
}
- opp->pint = val;
+ opp->pir = val;
break;
- case 0x10A0: /* IPI_IPVP */
+ case 0x10A0: /* IPI_IVPR */
case 0x10B0:
case 0x10C0:
case 0x10D0:
{
int idx;
idx = (addr - 0x10A0) >> 4;
- write_IRQreg_ipvp(opp, opp->irq_ipi0 + idx, val);
+ write_IRQreg_ivpr(opp, opp->irq_ipi0 + idx, val);
}
break;
case 0x10E0: /* SPVE */
- opp->spve = val & opp->spve_mask;
+ opp->spve = val & opp->vector_mask;
break;
default:
break;
@@ -564,24 +726,27 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)
OpenPICState *opp = opaque;
uint32_t retval;
- DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+ DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
retval = 0xFFFFFFFF;
- if (addr & 0xF)
+ if (addr & 0xF) {
return retval;
+ }
switch (addr) {
- case 0x1000: /* FREP */
- retval = opp->frep;
+ case 0x1000: /* FRR */
+ retval = opp->frr;
break;
- case 0x1020: /* GLBC */
- retval = opp->glbc;
+ case 0x1020: /* GCR */
+ retval = opp->gcr;
break;
- case 0x1080: /* VENI */
- retval = opp->veni;
+ case 0x1080: /* VIR */
+ retval = opp->vir;
break;
- case 0x1090: /* PINT */
+ case 0x1090: /* PIR */
retval = 0x00000000;
break;
case 0x00: /* Block Revision Register1 (BRR1) */
+ retval = opp->brr1;
+ break;
case 0x40:
case 0x50:
case 0x60:
@@ -592,14 +757,14 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)
case 0xB0:
retval = openpic_cpu_read_internal(opp, addr, get_current_cpu());
break;
- case 0x10A0: /* IPI_IPVP */
+ case 0x10A0: /* IPI_IVPR */
case 0x10B0:
case 0x10C0:
case 0x10D0:
{
int idx;
idx = (addr - 0x10A0) >> 4;
- retval = read_IRQreg_ipvp(opp, opp->irq_ipi0 + idx);
+ retval = read_IRQreg_ivpr(opp, opp->irq_ipi0 + idx);
}
break;
case 0x10E0: /* SPVE */
@@ -608,7 +773,7 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)
default:
break;
}
- DPRINTF("%s: => %08x\n", __func__, retval);
+ DPRINTF("%s: => 0x%08x\n", __func__, retval);
return retval;
}
@@ -619,32 +784,35 @@ static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,
OpenPICState *opp = opaque;
int idx;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
+ DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
+ __func__, addr, val);
+ if (addr & 0xF) {
return;
+ }
idx = (addr >> 6) & 0x3;
addr = addr & 0x30;
if (addr == 0x0) {
- /* TIFR (TFRR) */
- opp->tifr = val;
+ /* TFRR */
+ opp->tfrr = val;
return;
}
switch (addr & 0x30) {
- case 0x00: /* TICC (GTCCR) */
+ case 0x00: /* TCCR */
break;
- case 0x10: /* TIBC (GTBCR) */
- if ((opp->timers[idx].ticc & 0x80000000) != 0 &&
- (val & 0x80000000) == 0 &&
- (opp->timers[idx].tibc & 0x80000000) != 0)
- opp->timers[idx].ticc &= ~0x80000000;
- opp->timers[idx].tibc = val;
+ case 0x10: /* TBCR */
+ if ((opp->timers[idx].tccr & TCCR_TOG) != 0 &&
+ (val & TBCR_CI) == 0 &&
+ (opp->timers[idx].tbcr & TBCR_CI) != 0) {
+ opp->timers[idx].tccr &= ~TCCR_TOG;
+ }
+ opp->timers[idx].tbcr = val;
break;
- case 0x20: /* TIVP (GTIVPR) */
- write_IRQreg_ipvp(opp, opp->irq_tim0 + idx, val);
+ case 0x20: /* TVPR */
+ write_IRQreg_ivpr(opp, opp->irq_tim0 + idx, val);
break;
- case 0x30: /* TIDE (GTIDR) */
- write_IRQreg_ide(opp, opp->irq_tim0 + idx, val);
+ case 0x30: /* TDR */
+ write_IRQreg_idr(opp, opp->irq_tim0 + idx, val);
break;
}
}
@@ -655,33 +823,33 @@ static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len)
uint32_t retval = -1;
int idx;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
if (addr & 0xF) {
goto out;
}
idx = (addr >> 6) & 0x3;
if (addr == 0x0) {
- /* TIFR (TFRR) */
- retval = opp->tifr;
+ /* TFRR */
+ retval = opp->tfrr;
goto out;
}
switch (addr & 0x30) {
- case 0x00: /* TICC (GTCCR) */
- retval = opp->timers[idx].ticc;
+ case 0x00: /* TCCR */
+ retval = opp->timers[idx].tccr;
break;
- case 0x10: /* TIBC (GTBCR) */
- retval = opp->timers[idx].tibc;
+ case 0x10: /* TBCR */
+ retval = opp->timers[idx].tbcr;
break;
- case 0x20: /* TIPV (TIPV) */
- retval = read_IRQreg_ipvp(opp, opp->irq_tim0 + idx);
+ case 0x20: /* TIPV */
+ retval = read_IRQreg_ivpr(opp, opp->irq_tim0 + idx);
break;
case 0x30: /* TIDE (TIDR) */
- retval = read_IRQreg_ide(opp, opp->irq_tim0 + idx);
+ retval = read_IRQreg_idr(opp, opp->irq_tim0 + idx);
break;
}
out:
- DPRINTF("%s: => %08x\n", __func__, retval);
+ DPRINTF("%s: => 0x%08x\n", __func__, retval);
return retval;
}
@@ -692,17 +860,19 @@ static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,
OpenPICState *opp = opaque;
int idx;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
+ DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
+ __func__, addr, val);
+ if (addr & 0xF) {
return;
+ }
addr = addr & 0xFFF0;
idx = addr >> 5;
if (addr & 0x10) {
/* EXDE / IFEDE / IEEDE */
- write_IRQreg_ide(opp, idx, val);
+ write_IRQreg_idr(opp, idx, val);
} else {
/* EXVP / IFEVP / IEEVP */
- write_IRQreg_ipvp(opp, idx, val);
+ write_IRQreg_ivpr(opp, idx, val);
}
}
@@ -712,20 +882,21 @@ static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)
uint32_t retval;
int idx;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
retval = 0xFFFFFFFF;
- if (addr & 0xF)
+ if (addr & 0xF) {
return retval;
+ }
addr = addr & 0xFFF0;
idx = addr >> 5;
if (addr & 0x10) {
/* EXDE / IFEDE / IEEDE */
- retval = read_IRQreg_ide(opp, idx);
+ retval = read_IRQreg_idr(opp, idx);
} else {
/* EXVP / IFEVP / IEEVP */
- retval = read_IRQreg_ipvp(opp, idx);
+ retval = read_IRQreg_ivpr(opp, idx);
}
- DPRINTF("%s: => %08x\n", __func__, retval);
+ DPRINTF("%s: => 0x%08x\n", __func__, retval);
return retval;
}
@@ -737,7 +908,8 @@ static void openpic_msi_write(void *opaque, hwaddr addr, uint64_t val,
int idx = opp->irq_msi;
int srs, ibs;
- DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64 "\n",
+ __func__, addr, val);
if (addr & 0xF) {
return;
}
@@ -762,7 +934,7 @@ static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size)
uint64_t r = 0;
int i, srs;
- DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+ DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
if (addr & 0xF) {
return -1;
}
@@ -781,6 +953,7 @@ static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size)
r = opp->msi[srs].msir;
/* Clear on read */
opp->msi[srs].msir = 0;
+ openpic_set_irq(opp, opp->irq_msi + srs, 0);
break;
case 0x120: /* MSISR */
for (i = 0; i < MAX_MSI; i++) {
@@ -796,14 +969,20 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
uint32_t val, int idx)
{
OpenPICState *opp = opaque;
- IRQ_src_t *src;
- IRQ_dst_t *dst;
+ IRQSource *src;
+ IRQDest *dst;
int s_IRQ, n_IRQ;
- DPRINTF("%s: cpu %d addr " TARGET_FMT_plx " <= %08x\n", __func__, idx,
+ DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx " <= 0x%08x\n", __func__, idx,
addr, val);
- if (addr & 0xF)
+
+ if (idx < 0) {
return;
+ }
+
+ if (addr & 0xF) {
+ return;
+ }
dst = &opp->dst[idx];
addr &= 0xFF0;
switch (addr) {
@@ -813,25 +992,45 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
case 0x70:
idx = (addr - 0x40) >> 4;
/* we use IDE as mask which CPUs to deliver the IPI to still. */
- write_IRQreg_ide(opp, opp->irq_ipi0 + idx,
- opp->src[opp->irq_ipi0 + idx].ide | val);
+ write_IRQreg_idr(opp, opp->irq_ipi0 + idx,
+ opp->src[opp->irq_ipi0 + idx].idr | val);
openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);
openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);
break;
- case 0x80: /* PCTP */
- dst->pctp = val & 0x0000000F;
+ case 0x80: /* CTPR */
+ dst->ctpr = val & 0x0000000F;
+
+ DPRINTF("%s: set CPU %d ctpr to %d, raised %d servicing %d\n",
+ __func__, idx, dst->ctpr, dst->raised.priority,
+ dst->servicing.priority);
+
+ if (dst->raised.priority <= dst->ctpr) {
+ DPRINTF("%s: Lower OpenPIC INT output cpu %d due to ctpr\n",
+ __func__, idx);
+ qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
+ } else if (dst->raised.priority > dst->servicing.priority) {
+ DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d\n",
+ __func__, idx, dst->raised.next);
+ qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
+ }
+
break;
case 0x90: /* WHOAMI */
/* Read-only register */
break;
- case 0xA0: /* PIAC */
+ case 0xA0: /* IACK */
/* Read-only register */
break;
- case 0xB0: /* PEOI */
- DPRINTF("PEOI\n");
+ case 0xB0: /* EOI */
+ DPRINTF("EOI\n");
s_IRQ = IRQ_get_next(opp, &dst->servicing);
+
+ if (s_IRQ < 0) {
+ DPRINTF("%s: EOI with no interrupt in service\n", __func__);
+ break;
+ }
+
IRQ_resetbit(&dst->servicing, s_IRQ);
- dst->servicing.next = -1;
/* Set up next servicing IRQ */
s_IRQ = IRQ_get_next(opp, &dst->servicing);
/* Check queued interrupts. */
@@ -839,10 +1038,10 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
src = &opp->src[n_IRQ];
if (n_IRQ != -1 &&
(s_IRQ == -1 ||
- IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
+ IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) {
DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
idx, n_IRQ);
- openpic_irq_raise(opp, idx, src);
+ qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]);
}
break;
default:
@@ -856,81 +1055,93 @@ static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val,
openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12);
}
+
+static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu)
+{
+ IRQSource *src;
+ int retval, irq;
+
+ DPRINTF("Lower OpenPIC INT output\n");
+ qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
+
+ irq = IRQ_get_next(opp, &dst->raised);
+ DPRINTF("IACK: irq=%d\n", irq);
+
+ if (irq == -1) {
+ /* No more interrupt pending */
+ return opp->spve;
+ }
+
+ src = &opp->src[irq];
+ if (!(src->ivpr & IVPR_ACTIVITY_MASK) ||
+ !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) {
+ fprintf(stderr, "%s: bad raised IRQ %d ctpr %d ivpr 0x%08x\n",
+ __func__, irq, dst->ctpr, src->ivpr);
+ openpic_update_irq(opp, irq);
+ retval = opp->spve;
+ } else {
+ /* IRQ enter servicing state */
+ IRQ_setbit(&dst->servicing, irq);
+ retval = IVPR_VECTOR(opp, src->ivpr);
+ }
+
+ if (!src->level) {
+ /* edge-sensitive IRQ */
+ src->ivpr &= ~IVPR_ACTIVITY_MASK;
+ src->pending = 0;
+ IRQ_resetbit(&dst->raised, irq);
+ }
+
+ if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + MAX_IPI))) {
+ src->idr &= ~(1 << cpu);
+ if (src->idr && !src->level) {
+ /* trigger on CPUs that didn't know about it yet */
+ openpic_set_irq(opp, irq, 1);
+ openpic_set_irq(opp, irq, 0);
+ /* if all CPUs knew about it, set active bit again */
+ src->ivpr |= IVPR_ACTIVITY_MASK;
+ }
+ }
+
+ return retval;
+}
+
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
int idx)
{
OpenPICState *opp = opaque;
- IRQ_src_t *src;
- IRQ_dst_t *dst;
+ IRQDest *dst;
uint32_t retval;
- int n_IRQ;
- DPRINTF("%s: cpu %d addr " TARGET_FMT_plx "\n", __func__, idx, addr);
+ DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx "\n", __func__, idx, addr);
retval = 0xFFFFFFFF;
- if (addr & 0xF)
+
+ if (idx < 0) {
+ return retval;
+ }
+
+ if (addr & 0xF) {
return retval;
+ }
dst = &opp->dst[idx];
addr &= 0xFF0;
switch (addr) {
- case 0x00: /* Block Revision Register1 (BRR1) */
- retval = opp->brr1;
- break;
- case 0x80: /* PCTP */
- retval = dst->pctp;
+ case 0x80: /* CTPR */
+ retval = dst->ctpr;
break;
case 0x90: /* WHOAMI */
retval = idx;
break;
- case 0xA0: /* PIAC */
- DPRINTF("Lower OpenPIC INT output\n");
- qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
- n_IRQ = IRQ_get_next(opp, &dst->raised);
- DPRINTF("PIAC: irq=%d\n", n_IRQ);
- if (n_IRQ == -1) {
- /* No more interrupt pending */
- retval = IPVP_VECTOR(opp->spve);
- } else {
- src = &opp->src[n_IRQ];
- if (!(src->ipvp & IPVP_ACTIVITY_MASK) ||
- !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) {
- /* - Spurious level-sensitive IRQ
- * - Priorities has been changed
- * and the pending IRQ isn't allowed anymore
- */
- src->ipvp &= ~IPVP_ACTIVITY_MASK;
- retval = IPVP_VECTOR(opp->spve);
- } else {
- /* IRQ enter servicing state */
- IRQ_setbit(&dst->servicing, n_IRQ);
- retval = IPVP_VECTOR(src->ipvp);
- }
- IRQ_resetbit(&dst->raised, n_IRQ);
- dst->raised.next = -1;
- if (!(src->ipvp & IPVP_SENSE_MASK)) {
- /* edge-sensitive IRQ */
- src->ipvp &= ~IPVP_ACTIVITY_MASK;
- src->pending = 0;
- }
-
- if ((n_IRQ >= opp->irq_ipi0) && (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) {
- src->ide &= ~(1 << idx);
- if (src->ide && !(src->ipvp & IPVP_SENSE_MASK)) {
- /* trigger on CPUs that didn't know about it yet */
- openpic_set_irq(opp, n_IRQ, 1);
- openpic_set_irq(opp, n_IRQ, 0);
- /* if all CPUs knew about it, set active bit again */
- src->ipvp |= IPVP_ACTIVITY_MASK;
- }
- }
- }
+ case 0xA0: /* IACK */
+ retval = openpic_iack(opp, dst, idx);
break;
- case 0xB0: /* PEOI */
+ case 0xB0: /* EOI */
retval = 0;
break;
default:
break;
}
- DPRINTF("%s: => %08x\n", __func__, retval);
+ DPRINTF("%s: => 0x%08x\n", __func__, retval);
return retval;
}
@@ -1040,12 +1251,20 @@ static const MemoryRegionOps openpic_msi_ops_be = {
},
};
-static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
+static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q)
{
unsigned int i;
- for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)
- qemu_put_be32s(f, &q->queue[i]);
+ for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
+ /* Always put the lower half of a 64-bit long first, in case we
+ * restore on a 32-bit host. The least significant bits correspond
+ * to lower IRQ numbers in the bitmap.
+ */
+ qemu_put_be32(f, (uint32_t)q->queue[i]);
+#if LONG_MAX > 0x7FFFFFFF
+ qemu_put_be32(f, (uint32_t)(q->queue[i] >> 32));
+#endif
+ }
qemu_put_sbe32s(f, &q->next);
qemu_put_sbe32s(f, &q->priority);
@@ -1056,40 +1275,50 @@ static void openpic_save(QEMUFile* f, void *opaque)
OpenPICState *opp = (OpenPICState *)opaque;
unsigned int i;
- qemu_put_be32s(f, &opp->glbc);
- qemu_put_be32s(f, &opp->veni);
- qemu_put_be32s(f, &opp->pint);
+ qemu_put_be32s(f, &opp->gcr);
+ qemu_put_be32s(f, &opp->vir);
+ qemu_put_be32s(f, &opp->pir);
qemu_put_be32s(f, &opp->spve);
- qemu_put_be32s(f, &opp->tifr);
-
- for (i = 0; i < opp->max_irq; i++) {
- qemu_put_be32s(f, &opp->src[i].ipvp);
- qemu_put_be32s(f, &opp->src[i].ide);
- qemu_put_sbe32s(f, &opp->src[i].last_cpu);
- qemu_put_sbe32s(f, &opp->src[i].pending);
- }
+ qemu_put_be32s(f, &opp->tfrr);
qemu_put_be32s(f, &opp->nb_cpus);
for (i = 0; i < opp->nb_cpus; i++) {
- qemu_put_be32s(f, &opp->dst[i].pctp);
- qemu_put_be32s(f, &opp->dst[i].pcsr);
+ qemu_put_sbe32s(f, &opp->dst[i].ctpr);
openpic_save_IRQ_queue(f, &opp->dst[i].raised);
openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
+ qemu_put_buffer(f, (uint8_t *)&opp->dst[i].outputs_active,
+ sizeof(opp->dst[i].outputs_active));
}
for (i = 0; i < MAX_TMR; i++) {
- qemu_put_be32s(f, &opp->timers[i].ticc);
- qemu_put_be32s(f, &opp->timers[i].tibc);
+ qemu_put_be32s(f, &opp->timers[i].tccr);
+ qemu_put_be32s(f, &opp->timers[i].tbcr);
+ }
+
+ for (i = 0; i < opp->max_irq; i++) {
+ qemu_put_be32s(f, &opp->src[i].ivpr);
+ qemu_put_be32s(f, &opp->src[i].idr);
+ qemu_put_sbe32s(f, &opp->src[i].last_cpu);
+ qemu_put_sbe32s(f, &opp->src[i].pending);
}
}
-static void openpic_load_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
+static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)
{
unsigned int i;
- for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)
- qemu_get_be32s(f, &q->queue[i]);
+ for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
+ unsigned long val;
+
+ val = qemu_get_be32(f);
+#if LONG_MAX > 0x7FFFFFFF
+ val <<= 32;
+ val |= qemu_get_be32(f);
+#endif
+
+ q->queue[i] = val;
+ }
qemu_get_sbe32s(f, &q->next);
qemu_get_sbe32s(f, &q->priority);
@@ -1100,63 +1329,61 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
OpenPICState *opp = (OpenPICState *)opaque;
unsigned int i;
- if (version_id != 1)
+ if (version_id != 1) {
return -EINVAL;
+ }
- qemu_get_be32s(f, &opp->glbc);
- qemu_get_be32s(f, &opp->veni);
- qemu_get_be32s(f, &opp->pint);
+ qemu_get_be32s(f, &opp->gcr);
+ qemu_get_be32s(f, &opp->vir);
+ qemu_get_be32s(f, &opp->pir);
qemu_get_be32s(f, &opp->spve);
- qemu_get_be32s(f, &opp->tifr);
-
- for (i = 0; i < opp->max_irq; i++) {
- qemu_get_be32s(f, &opp->src[i].ipvp);
- qemu_get_be32s(f, &opp->src[i].ide);
- qemu_get_sbe32s(f, &opp->src[i].last_cpu);
- qemu_get_sbe32s(f, &opp->src[i].pending);
- }
+ qemu_get_be32s(f, &opp->tfrr);
qemu_get_be32s(f, &opp->nb_cpus);
for (i = 0; i < opp->nb_cpus; i++) {
- qemu_get_be32s(f, &opp->dst[i].pctp);
- qemu_get_be32s(f, &opp->dst[i].pcsr);
+ qemu_get_sbe32s(f, &opp->dst[i].ctpr);
openpic_load_IRQ_queue(f, &opp->dst[i].raised);
openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
+ qemu_get_buffer(f, (uint8_t *)&opp->dst[i].outputs_active,
+ sizeof(opp->dst[i].outputs_active));
}
for (i = 0; i < MAX_TMR; i++) {
- qemu_get_be32s(f, &opp->timers[i].ticc);
- qemu_get_be32s(f, &opp->timers[i].tibc);
+ qemu_get_be32s(f, &opp->timers[i].tccr);
+ qemu_get_be32s(f, &opp->timers[i].tbcr);
}
- return 0;
-}
+ for (i = 0; i < opp->max_irq; i++) {
+ uint32_t val;
-static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src)
-{
- int n_ci = IDR_CI0_SHIFT - n_CPU;
+ val = qemu_get_be32(f);
+ write_IRQreg_idr(opp, i, val);
+ val = qemu_get_be32(f);
+ write_IRQreg_ivpr(opp, i, val);
- if ((opp->flags & OPENPIC_FLAG_IDE_CRIT) && (src->ide & (1 << n_ci))) {
- qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
- } else {
- qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
+ qemu_get_be32s(f, &opp->src[i].ivpr);
+ qemu_get_be32s(f, &opp->src[i].idr);
+ qemu_get_sbe32s(f, &opp->src[i].last_cpu);
+ qemu_get_sbe32s(f, &opp->src[i].pending);
}
+
+ return 0;
}
-struct memreg {
+typedef struct MemReg {
const char *name;
MemoryRegionOps const *ops;
bool map;
hwaddr start_addr;
ram_addr_t size;
-};
+} MemReg;
static int openpic_init(SysBusDevice *dev)
{
OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev);
int i, j;
- struct memreg list_le[] = {
+ MemReg list_le[] = {
{"glb", &openpic_glb_ops_le, true,
OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
{"tmr", &openpic_tmr_ops_le, true,
@@ -1168,7 +1395,7 @@ static int openpic_init(SysBusDevice *dev)
{"cpu", &openpic_cpu_ops_le, true,
OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
};
- struct memreg list_be[] = {
+ MemReg list_be[] = {
{"glb", &openpic_glb_ops_be, true,
OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
{"tmr", &openpic_tmr_ops_be, true,
@@ -1180,35 +1407,56 @@ static int openpic_init(SysBusDevice *dev)
{"cpu", &openpic_cpu_ops_be, true,
OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
};
- struct memreg *list;
+ MemReg *list;
switch (opp->model) {
case OPENPIC_MODEL_FSL_MPIC_20:
default:
- opp->flags |= OPENPIC_FLAG_IDE_CRIT;
+ opp->flags |= OPENPIC_FLAG_IDR_CRIT;
opp->nb_irqs = 80;
opp->vid = VID_REVISION_1_2;
- opp->veni = VENI_GENERIC;
- opp->spve_mask = 0xFFFF;
- opp->tifr_reset = 0x00000000;
- opp->ipvp_reset = 0x80000000;
- opp->ide_reset = 0x00000001;
+ opp->vir = VIR_GENERIC;
+ opp->vector_mask = 0xFFFF;
+ opp->tfrr_reset = 0;
+ opp->ivpr_reset = IVPR_MASK_MASK;
+ opp->idr_reset = 1 << 0;
opp->max_irq = FSL_MPIC_20_MAX_IRQ;
opp->irq_ipi0 = FSL_MPIC_20_IPI_IRQ;
opp->irq_tim0 = FSL_MPIC_20_TMR_IRQ;
opp->irq_msi = FSL_MPIC_20_MSI_IRQ;
opp->brr1 = FSL_BRR1_IPID | FSL_BRR1_IPMJ | FSL_BRR1_IPMN;
+ /* XXX really only available as of MPIC 4.0 */
+ opp->mpic_mode_mask = GCR_MODE_PROXY;
+
msi_supported = true;
list = list_be;
+
+ for (i = 0; i < FSL_MPIC_20_MAX_EXT; i++) {
+ opp->src[i].level = false;
+ }
+
+ /* Internal interrupts, including message and MSI */
+ for (i = 16; i < MAX_SRC; i++) {
+ opp->src[i].type = IRQ_TYPE_FSLINT;
+ opp->src[i].level = true;
+ }
+
+ /* timers and IPIs */
+ for (i = MAX_SRC; i < MAX_IRQ; i++) {
+ opp->src[i].type = IRQ_TYPE_FSLSPECIAL;
+ opp->src[i].level = false;
+ }
+
break;
+
case OPENPIC_MODEL_RAVEN:
opp->nb_irqs = RAVEN_MAX_EXT;
opp->vid = VID_REVISION_1_3;
- opp->veni = VENI_GENERIC;
- opp->spve_mask = 0xFF;
- opp->tifr_reset = 0x003F7A00;
- opp->ipvp_reset = 0xA0000000;
- opp->ide_reset = 0x00000000;
+ opp->vir = VIR_GENERIC;
+ opp->vector_mask = 0xFF;
+ opp->tfrr_reset = 4160000;
+ opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK;
+ opp->idr_reset = 0;
opp->max_irq = RAVEN_MAX_IRQ;
opp->irq_ipi0 = RAVEN_IPI_IRQ;
opp->irq_tim0 = RAVEN_TMR_IRQ;
@@ -1270,7 +1518,7 @@ static void openpic_class_init(ObjectClass *klass, void *data)
dc->reset = openpic_reset;
}
-static TypeInfo openpic_info = {
+static const TypeInfo openpic_info = {
.name = "openpic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(OpenPICState),
diff --git a/hw/parallel.c b/hw/parallel.c
index 64a46c6055..3a4e06bab0 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -599,7 +599,7 @@ static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
dc->props = parallel_isa_properties;
}
-static TypeInfo parallel_isa_info = {
+static const TypeInfo parallel_isa_info = {
.name = "isa-parallel",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISAParallelState),
diff --git a/hw/pc-testdev.c b/hw/pc-testdev.c
index 192848998c..ec0bc4bb95 100644
--- a/hw/pc-testdev.c
+++ b/hw/pc-testdev.c
@@ -172,7 +172,7 @@ static void testdev_class_init(ObjectClass *klass, void *data)
k->init = init_test_device;
}
-static TypeInfo testdev_info = {
+static const TypeInfo testdev_info = {
.name = TYPE_TESTDEV,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(struct PCTestdev),
diff --git a/hw/pc.c b/hw/pc.c
index df0c48e41b..ba1f19d7e8 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -103,6 +103,11 @@ static void ioport80_write(void *opaque, hwaddr addr, uint64_t data,
{
}
+static uint64_t ioport80_read(void *opaque, hwaddr addr, unsigned size)
+{
+ return 0xffffffffffffffffULL;
+}
+
/* MSDOS compatibility mode FPU exception support */
static qemu_irq ferr_irq;
@@ -123,6 +128,11 @@ static void ioportF0_write(void *opaque, hwaddr addr, uint64_t data,
qemu_irq_lower(ferr_irq);
}
+static uint64_t ioportF0_read(void *opaque, hwaddr addr, unsigned size)
+{
+ return 0xffffffffffffffffULL;
+}
+
/* TSC handling */
uint64_t cpu_get_tsc(CPUX86State *env)
{
@@ -501,7 +511,7 @@ static void port92_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_port92_isa;
}
-static TypeInfo port92_info = {
+static const TypeInfo port92_info = {
.name = "port92",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(Port92State),
@@ -960,6 +970,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
static const MemoryRegionOps ioport80_io_ops = {
.write = ioport80_write,
+ .read = ioport80_read,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
@@ -969,6 +980,7 @@ static const MemoryRegionOps ioport80_io_ops = {
static const MemoryRegionOps ioportF0_io_ops = {
.write = ioportF0_write,
+ .read = ioportF0_read,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
diff --git a/hw/pc87312.c b/hw/pc87312.c
new file mode 100644
index 0000000000..6a17afd45c
--- /dev/null
+++ b/hw/pc87312.c
@@ -0,0 +1,387 @@
+/*
+ * QEMU National Semiconductor PC87312 (Super I/O)
+ *
+ * Copyright (c) 2010-2012 Herve Poussineau
+ * Copyright (c) 2011-2012 Andreas Färber
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "pc87312.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/sysemu.h"
+#include "char/char.h"
+#include "trace.h"
+
+
+#define REG_FER 0
+#define REG_FAR 1
+#define REG_PTR 2
+
+#define FER regs[REG_FER]
+#define FAR regs[REG_FAR]
+#define PTR regs[REG_PTR]
+
+#define FER_PARALLEL_EN 0x01
+#define FER_UART1_EN 0x02
+#define FER_UART2_EN 0x04
+#define FER_FDC_EN 0x08
+#define FER_FDC_4 0x10
+#define FER_FDC_ADDR 0x20
+#define FER_IDE_EN 0x40
+#define FER_IDE_ADDR 0x80
+
+#define FAR_PARALLEL_ADDR 0x03
+#define FAR_UART1_ADDR 0x0C
+#define FAR_UART2_ADDR 0x30
+#define FAR_UART_3_4 0xC0
+
+#define PTR_POWER_DOWN 0x01
+#define PTR_CLOCK_DOWN 0x02
+#define PTR_PWDN 0x04
+#define PTR_IRQ_5_7 0x08
+#define PTR_UART1_TEST 0x10
+#define PTR_UART2_TEST 0x20
+#define PTR_LOCK_CONF 0x40
+#define PTR_EPP_MODE 0x80
+
+
+/* Parallel port */
+
+static inline bool is_parallel_enabled(PC87312State *s)
+{
+ return s->FER & FER_PARALLEL_EN;
+}
+
+static const uint32_t parallel_base[] = { 0x378, 0x3bc, 0x278, 0x00 };
+
+static inline uint32_t get_parallel_iobase(PC87312State *s)
+{
+ return parallel_base[s->FAR & FAR_PARALLEL_ADDR];
+}
+
+static const uint32_t parallel_irq[] = { 5, 7, 5, 0 };
+
+static inline uint32_t get_parallel_irq(PC87312State *s)
+{
+ int idx;
+ idx = (s->FAR & FAR_PARALLEL_ADDR);
+ if (idx == 0) {
+ return (s->PTR & PTR_IRQ_5_7) ? 7 : 5;
+ } else {
+ return parallel_irq[idx];
+ }
+}
+
+static inline bool is_parallel_epp(PC87312State *s)
+{
+ return s->PTR & PTR_EPP_MODE;
+}
+
+
+/* UARTs */
+
+static const uint32_t uart_base[2][4] = {
+ { 0x3e8, 0x338, 0x2e8, 0x220 },
+ { 0x2e8, 0x238, 0x2e0, 0x228 }
+};
+
+static inline uint32_t get_uart_iobase(PC87312State *s, int i)
+{
+ int idx;
+ idx = (s->FAR >> (2 * i + 2)) & 0x3;
+ if (idx == 0) {
+ return 0x3f8;
+ } else if (idx == 1) {
+ return 0x2f8;
+ } else {
+ return uart_base[idx & 1][(s->FAR & FAR_UART_3_4) >> 6];
+ }
+}
+
+static inline uint32_t get_uart_irq(PC87312State *s, int i)
+{
+ int idx;
+ idx = (s->FAR >> (2 * i + 2)) & 0x3;
+ return (idx & 1) ? 3 : 4;
+}
+
+static inline bool is_uart_enabled(PC87312State *s, int i)
+{
+ return s->FER & (FER_UART1_EN << i);
+}
+
+
+/* Floppy controller */
+
+static inline bool is_fdc_enabled(PC87312State *s)
+{
+ return s->FER & FER_FDC_EN;
+}
+
+static inline uint32_t get_fdc_iobase(PC87312State *s)
+{
+ return (s->FER & FER_FDC_ADDR) ? 0x370 : 0x3f0;
+}
+
+
+/* IDE controller */
+
+static inline bool is_ide_enabled(PC87312State *s)
+{
+ return s->FER & FER_IDE_EN;
+}
+
+static inline uint32_t get_ide_iobase(PC87312State *s)
+{
+ return (s->FER & FER_IDE_ADDR) ? 0x170 : 0x1f0;
+}
+
+
+static void reconfigure_devices(PC87312State *s)
+{
+ error_report("pc87312: unsupported device reconfiguration (%02x %02x %02x)",
+ s->FER, s->FAR, s->PTR);
+}
+
+static void pc87312_soft_reset(PC87312State *s)
+{
+ static const uint8_t fer_init[] = {
+ 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4b, 0x4b,
+ 0x4b, 0x4b, 0x4b, 0x4b, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x49, 0x49, 0x49, 0x49, 0x07, 0x07, 0x07, 0x07,
+ 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x08, 0x00,
+ };
+ static const uint8_t far_init[] = {
+ 0x10, 0x11, 0x11, 0x39, 0x24, 0x38, 0x00, 0x01,
+ 0x01, 0x09, 0x08, 0x08, 0x10, 0x11, 0x39, 0x24,
+ 0x00, 0x01, 0x01, 0x00, 0x10, 0x11, 0x39, 0x24,
+ 0x10, 0x11, 0x11, 0x39, 0x24, 0x38, 0x10, 0x10,
+ };
+ static const uint8_t ptr_init[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ };
+
+ s->read_id_step = 0;
+ s->selected_index = REG_FER;
+
+ s->FER = fer_init[s->config & 0x1f];
+ s->FAR = far_init[s->config & 0x1f];
+ s->PTR = ptr_init[s->config & 0x1f];
+}
+
+static void pc87312_hard_reset(PC87312State *s)
+{
+ pc87312_soft_reset(s);
+}
+
+static void pc87312_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ PC87312State *s = opaque;
+
+ trace_pc87312_io_write(addr, val);
+
+ if ((addr & 1) == 0) {
+ /* Index register */
+ s->read_id_step = 2;
+ s->selected_index = val;
+ } else {
+ /* Data register */
+ if (s->selected_index < 3) {
+ s->regs[s->selected_index] = val;
+ reconfigure_devices(s);
+ }
+ }
+}
+
+static uint32_t pc87312_ioport_read(void *opaque, uint32_t addr)
+{
+ PC87312State *s = opaque;
+ uint32_t val;
+
+ if ((addr & 1) == 0) {
+ /* Index register */
+ if (s->read_id_step++ == 0) {
+ val = 0x88;
+ } else if (s->read_id_step++ == 1) {
+ val = 0;
+ } else {
+ val = s->selected_index;
+ }
+ } else {
+ /* Data register */
+ if (s->selected_index < 3) {
+ val = s->regs[s->selected_index];
+ } else {
+ /* Invalid selected index */
+ val = 0;
+ }
+ }
+
+ trace_pc87312_io_read(addr, val);
+ return val;
+}
+
+static int pc87312_post_load(void *opaque, int version_id)
+{
+ PC87312State *s = opaque;
+
+ reconfigure_devices(s);
+ return 0;
+}
+
+static void pc87312_reset(DeviceState *d)
+{
+ PC87312State *s = PC87312(d);
+
+ pc87312_soft_reset(s);
+}
+
+static int pc87312_init(ISADevice *dev)
+{
+ PC87312State *s;
+ DeviceState *d;
+ ISADevice *isa;
+ ISABus *bus;
+ CharDriverState *chr;
+ DriveInfo *drive;
+ char name[5];
+ int i;
+
+ s = PC87312(dev);
+ bus = isa_bus_from_device(dev);
+ pc87312_hard_reset(s);
+
+ if (is_parallel_enabled(s)) {
+ chr = parallel_hds[0];
+ if (chr == NULL) {
+ chr = qemu_chr_new("par0", "null", NULL);
+ }
+ isa = isa_create(bus, "isa-parallel");
+ d = DEVICE(isa);
+ qdev_prop_set_uint32(d, "index", 0);
+ qdev_prop_set_uint32(d, "iobase", get_parallel_iobase(s));
+ qdev_prop_set_uint32(d, "irq", get_parallel_irq(s));
+ qdev_prop_set_chr(d, "chardev", chr);
+ qdev_init_nofail(d);
+ s->parallel.dev = isa;
+ trace_pc87312_info_parallel(get_parallel_iobase(s),
+ get_parallel_irq(s));
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (is_uart_enabled(s, i)) {
+ chr = serial_hds[i];
+ if (chr == NULL) {
+ snprintf(name, sizeof(name), "ser%d", i);
+ chr = qemu_chr_new(name, "null", NULL);
+ }
+ isa = isa_create(bus, "isa-serial");
+ d = DEVICE(isa);
+ qdev_prop_set_uint32(d, "index", i);
+ qdev_prop_set_uint32(d, "iobase", get_uart_iobase(s, i));
+ qdev_prop_set_uint32(d, "irq", get_uart_irq(s, i));
+ qdev_prop_set_chr(d, "chardev", chr);
+ qdev_init_nofail(d);
+ s->uart[i].dev = isa;
+ trace_pc87312_info_serial(i, get_uart_iobase(s, i),
+ get_uart_irq(s, i));
+ }
+ }
+
+ if (is_fdc_enabled(s)) {
+ isa = isa_create(bus, "isa-fdc");
+ d = DEVICE(isa);
+ qdev_prop_set_uint32(d, "iobase", get_fdc_iobase(s));
+ qdev_prop_set_uint32(d, "irq", 6);
+ drive = drive_get(IF_FLOPPY, 0, 0);
+ if (drive != NULL) {
+ qdev_prop_set_drive_nofail(d, "driveA", drive->bdrv);
+ }
+ drive = drive_get(IF_FLOPPY, 0, 1);
+ if (drive != NULL) {
+ qdev_prop_set_drive_nofail(d, "driveB", drive->bdrv);
+ }
+ qdev_init_nofail(d);
+ s->fdc.dev = isa;
+ trace_pc87312_info_floppy(get_fdc_iobase(s));
+ }
+
+ if (is_ide_enabled(s)) {
+ isa = isa_create(bus, "isa-ide");
+ d = DEVICE(isa);
+ qdev_prop_set_uint32(d, "iobase", get_ide_iobase(s));
+ qdev_prop_set_uint32(d, "iobase2", get_ide_iobase(s) + 0x206);
+ qdev_prop_set_uint32(d, "irq", 14);
+ qdev_init_nofail(d);
+ s->ide.dev = isa;
+ trace_pc87312_info_ide(get_ide_iobase(s));
+ }
+
+ register_ioport_write(s->iobase, 2, 1, pc87312_ioport_write, s);
+ register_ioport_read(s->iobase, 2, 1, pc87312_ioport_read, s);
+ return 0;
+}
+
+static const VMStateDescription vmstate_pc87312 = {
+ .name = "pc87312",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = pc87312_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(read_id_step, PC87312State),
+ VMSTATE_UINT8(selected_index, PC87312State),
+ VMSTATE_UINT8_ARRAY(regs, PC87312State, 3),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static Property pc87312_properties[] = {
+ DEFINE_PROP_HEX32("iobase", PC87312State, iobase, 0x398),
+ DEFINE_PROP_UINT8("config", PC87312State, config, 1),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void pc87312_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+
+ ic->init = pc87312_init;
+ dc->reset = pc87312_reset;
+ dc->vmsd = &vmstate_pc87312;
+ dc->props = pc87312_properties;
+}
+
+static const TypeInfo pc87312_type_info = {
+ .name = TYPE_PC87312,
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(PC87312State),
+ .class_init = pc87312_class_init,
+};
+
+static void pc87312_register_types(void)
+{
+ type_register_static(&pc87312_type_info);
+}
+
+type_init(pc87312_register_types)
diff --git a/hw/pc87312.h b/hw/pc87312.h
new file mode 100644
index 0000000000..7ca7912ba7
--- /dev/null
+++ b/hw/pc87312.h
@@ -0,0 +1,66 @@
+/*
+ * QEMU National Semiconductor PC87312 (Super I/O)
+ *
+ * Copyright (c) 2010-2012 Herve Poussineau
+ * Copyright (c) 2011-2012 Andreas Färber
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef QEMU_PC87312_H
+#define QEMU_PC87312_H
+
+#include "isa.h"
+
+
+#define TYPE_PC87312 "pc87312"
+#define PC87312(obj) OBJECT_CHECK(PC87312State, (obj), TYPE_PC87312)
+
+typedef struct PC87312State {
+ ISADevice dev;
+
+ uint32_t iobase;
+ uint8_t config; /* initial configuration */
+
+ struct {
+ ISADevice *dev;
+ } parallel;
+
+ struct {
+ ISADevice *dev;
+ } uart[2];
+
+ struct {
+ ISADevice *dev;
+ BlockDriverState *drive[2];
+ uint32_t base;
+ } fdc;
+
+ struct {
+ ISADevice *dev;
+ uint32_t base;
+ } ide;
+
+ uint8_t read_id_step;
+ uint8_t selected_index;
+
+ uint8_t regs[3];
+} PC87312State;
+
+
+#endif
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 2b3d58b852..e630aeab9d 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -282,10 +282,10 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
}
#endif
-static QEMUMachine pc_machine_v1_4 = {
- .name = "pc-1.4",
+static QEMUMachine pc_i440fx_machine_v1_4 = {
+ .name = "pc-i440fx-1.4",
.alias = "pc",
- .desc = "Standard PC",
+ .desc = "Standard PC (i440FX + PIIX, 1996)",
.init = pc_init_pci_1_3,
.max_cpus = 255,
.is_default = 1,
@@ -646,7 +646,7 @@ static QEMUMachine xenfv_machine = {
static void pc_machine_init(void)
{
- qemu_register_machine(&pc_machine_v1_4);
+ qemu_register_machine(&pc_i440fx_machine_v1_4);
qemu_register_machine(&pc_machine_v1_3);
qemu_register_machine(&pc_machine_v1_2);
qemu_register_machine(&pc_machine_v1_1);
diff --git a/hw/pc_q35.c b/hw/pc_q35.c
index ef540b6a71..52d997613f 100644
--- a/hw/pc_q35.c
+++ b/hw/pc_q35.c
@@ -209,9 +209,9 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
}
static QEMUMachine pc_q35_machine = {
- .name = "q35-next",
+ .name = "pc-q35-1.4",
.alias = "q35",
- .desc = "Q35 chipset PC",
+ .desc = "Standard PC (Q35 + ICH9, 2009)",
.init = pc_q35_init,
.max_cpus = 255,
};
diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c
index 7567593a63..7f6c12c8a8 100644
--- a/hw/pc_sysfw.c
+++ b/hw/pc_sysfw.c
@@ -256,7 +256,7 @@ static void pcsysfw_class_init (ObjectClass *klass, void *data)
dc->props = pcsysfw_properties;
}
-static TypeInfo pcsysfw_info = {
+static const TypeInfo pcsysfw_info = {
.name = "pc-sysfw",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof (PcSysFwDevice),
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 94840c4af7..5fd1bcf08e 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2150,7 +2150,7 @@ void pci_setup_iommu(PCIBus *bus, PCIDMAContextFunc fn, void *opaque)
bus->dma_context_opaque = opaque;
}
-static TypeInfo pci_device_type_info = {
+static const TypeInfo pci_device_type_info = {
.name = TYPE_PCI_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(PCIDevice),
diff --git a/hw/pci_bridge_dev.c b/hw/pci_bridge_dev.c
index 2dd312db35..1124c53b8c 100644
--- a/hw/pci_bridge_dev.c
+++ b/hw/pci_bridge_dev.c
@@ -152,7 +152,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
dc->vmsd = &pci_bridge_dev_vmstate;
}
-static TypeInfo pci_bridge_dev_info = {
+static const TypeInfo pci_bridge_dev_info = {
.name = "pci-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIBridgeDev),
diff --git a/hw/pckbd.c b/hw/pckbd.c
index 6db7bbcc06..3bad09baf2 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -512,7 +512,7 @@ static void i8042_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_kbd_isa;
}
-static TypeInfo i8042_info = {
+static const TypeInfo i8042_info = {
.name = "i8042",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISAKBDState),
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 40a0e6eda4..a94f642136 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -361,7 +361,7 @@ static void pcnet_class_init(ObjectClass *klass, void *data)
dc->props = pcnet_properties;
}
-static TypeInfo pcnet_info = {
+static const TypeInfo pcnet_info = {
.name = "pcnet",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIPCNetState),
diff --git a/hw/pcspk.c b/hw/pcspk.c
index 6d55ebe82f..dfab9559ae 100644
--- a/hw/pcspk.c
+++ b/hw/pcspk.c
@@ -187,7 +187,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
dc->props = pcspk_properties;
}
-static TypeInfo pcspk_info = {
+static const TypeInfo pcspk_info = {
.name = "isa-pcspk",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(PCSpkState),
diff --git a/hw/piix4.c b/hw/piix4.c
index 799ed1729c..c1cb94d39f 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -117,7 +117,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_piix4;
}
-static TypeInfo piix4_info = {
+static const TypeInfo piix4_info = {
.name = "PIIX4",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PIIX4State),
diff --git a/hw/pl011.c b/hw/pl011.c
index 35835f36c0..002a50e16a 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -300,7 +300,7 @@ static void pl011_arm_class_init(ObjectClass *klass, void *data)
sdc->init = pl011_arm_init;
}
-static TypeInfo pl011_arm_info = {
+static const TypeInfo pl011_arm_info = {
.name = "pl011",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl011_state),
@@ -314,7 +314,7 @@ static void pl011_luminary_class_init(ObjectClass *klass, void *data)
sdc->init = pl011_luminary_init;
}
-static TypeInfo pl011_luminary_info = {
+static const TypeInfo pl011_luminary_info = {
.name = "pl011_luminary",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl011_state),
diff --git a/hw/pl022.c b/hw/pl022.c
index fbd7ded0cf..c160e9061c 100644
--- a/hw/pl022.c
+++ b/hw/pl022.c
@@ -293,7 +293,7 @@ static void pl022_class_init(ObjectClass *klass, void *data)
sdc->init = pl022_init;
}
-static TypeInfo pl022_info = {
+static const TypeInfo pl022_info = {
.name = "pl022",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl022_state),
diff --git a/hw/pl031.c b/hw/pl031.c
index 3a23ecde48..757867ff79 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -250,7 +250,7 @@ static void pl031_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl031;
}
-static TypeInfo pl031_info = {
+static const TypeInfo pl031_info = {
.name = "pl031",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl031_state),
diff --git a/hw/pl041.c b/hw/pl041.c
index 4436d97c50..0b71c45748 100644
--- a/hw/pl041.c
+++ b/hw/pl041.c
@@ -632,7 +632,7 @@ static void pl041_device_class_init(ObjectClass *klass, void *data)
dc->props = pl041_device_properties;
}
-static TypeInfo pl041_device_info = {
+static const TypeInfo pl041_device_info = {
.name = "pl041",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl041_state),
diff --git a/hw/pl050.c b/hw/pl050.c
index 47032f1260..5d06bc9a3f 100644
--- a/hw/pl050.c
+++ b/hw/pl050.c
@@ -168,7 +168,7 @@ static void pl050_kbd_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl050;
}
-static TypeInfo pl050_kbd_info = {
+static const TypeInfo pl050_kbd_info = {
.name = "pl050_keyboard",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl050_state),
@@ -184,7 +184,7 @@ static void pl050_mouse_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl050;
}
-static TypeInfo pl050_mouse_info = {
+static const TypeInfo pl050_mouse_info = {
.name = "pl050_mouse",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl050_state),
diff --git a/hw/pl061.c b/hw/pl061.c
index f1ed5ced1d..a78e819d96 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -304,7 +304,7 @@ static void pl061_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl061;
}
-static TypeInfo pl061_info = {
+static const TypeInfo pl061_info = {
.name = "pl061",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl061_state),
@@ -320,7 +320,7 @@ static void pl061_luminary_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl061;
}
-static TypeInfo pl061_luminary_info = {
+static const TypeInfo pl061_luminary_info = {
.name = "pl061_luminary",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl061_state),
diff --git a/hw/pl080.c b/hw/pl080.c
index 26150af757..f6bbf98a7e 100644
--- a/hw/pl080.c
+++ b/hw/pl080.c
@@ -386,7 +386,7 @@ static void pl080_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl080;
}
-static TypeInfo pl080_info = {
+static const TypeInfo pl080_info = {
.name = "pl080",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl080_state),
@@ -403,7 +403,7 @@ static void pl081_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl080;
}
-static TypeInfo pl081_info = {
+static const TypeInfo pl081_info = {
.name = "pl081",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl080_state),
diff --git a/hw/pl110.c b/hw/pl110.c
index 098e335aea..3d0ac00ade 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -480,7 +480,7 @@ static void pl110_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl110;
}
-static TypeInfo pl110_info = {
+static const TypeInfo pl110_info = {
.name = "pl110",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl110_state),
@@ -497,7 +497,7 @@ static void pl110_versatile_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl110;
}
-static TypeInfo pl110_versatile_info = {
+static const TypeInfo pl110_versatile_info = {
.name = "pl110_versatile",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl110_state),
@@ -514,7 +514,7 @@ static void pl111_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl110;
}
-static TypeInfo pl111_info = {
+static const TypeInfo pl111_info = {
.name = "pl111",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl110_state),
diff --git a/hw/pl181.c b/hw/pl181.c
index cbddb741ce..98529f7821 100644
--- a/hw/pl181.c
+++ b/hw/pl181.c
@@ -500,7 +500,7 @@ static void pl181_class_init(ObjectClass *klass, void *data)
k->no_user = 1;
}
-static TypeInfo pl181_info = {
+static const TypeInfo pl181_info = {
.name = "pl181",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl181_state),
diff --git a/hw/pl190.c b/hw/pl190.c
index 40199302a9..76ac159374 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -274,7 +274,7 @@ static void pl190_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pl190;
}
-static TypeInfo pl190_info = {
+static const TypeInfo pl190_info = {
.name = "pl190",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(pl190_state),
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index b262f31e5a..3a9e1c7b43 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -225,6 +225,10 @@ static int ppce500_load_device_tree(CPUPPCState *env,
kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
hypercall, sizeof(hypercall));
+ /* if KVM supports the idle hcall, set property indicating this */
+ if (kvmppc_get_hasidle(env)) {
+ qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
+ }
}
/* Create CPU nodes */
@@ -493,8 +497,8 @@ void ppce500_init(PPCE500Params *params)
irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
env->spr[SPR_BOOKE_PIR] = env->cpu_index = i;
- env->mpic_cpu_base = MPC8544_CCSRBAR_BASE +
- MPC8544_MPIC_REGS_OFFSET + 0x20000;
+ env->mpic_iack = MPC8544_CCSRBAR_BASE +
+ MPC8544_MPIC_REGS_OFFSET + 0x200A0;
ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);
diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c
index 4483b8d292..25a4e91b69 100644
--- a/hw/ppc_booke.c
+++ b/hw/ppc_booke.c
@@ -237,6 +237,17 @@ void store_booke_tcr(CPUPPCState *env, target_ulong val)
}
+static void ppc_booke_timer_reset_handle(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
+
+ env->spr[SPR_BOOKE_TSR] = 0;
+ env->spr[SPR_BOOKE_TCR] = 0;
+
+ booke_update_irq(cpu);
+}
+
void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags)
{
ppc_tb_t *tb_env;
@@ -257,4 +268,6 @@ void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags)
qemu_new_timer_ns(vm_clock, &booke_fit_cb, cpu);
booke_timer->wdt_timer =
qemu_new_timer_ns(vm_clock, &booke_wdt_cb, cpu);
+
+ qemu_register_reset(ppc_booke_timer_reset_handle, cpu);
}
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 9c78c863e8..417583a96d 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -37,6 +37,7 @@
#include "ide.h"
#include "loader.h"
#include "mc146818rtc.h"
+#include "pc87312.h"
#include "sysemu/blockdev.h"
#include "sysemu/arch_init.h"
#include "exec/address-spaces.h"
@@ -181,7 +182,6 @@ typedef struct sysctrl_t {
M48t59State *nvram;
uint8_t state;
uint8_t syscontrol;
- uint8_t fake_io[2];
int contiguous_map;
int endian;
} sysctrl_t;
@@ -192,24 +192,6 @@ enum {
static sysctrl_t *sysctrl;
-static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
-{
- sysctrl_t *sysctrl = opaque;
-
- PPC_IO_DPRINTF("0x%08" PRIx32 " => 0x%02" PRIx32 "\n", addr - PPC_IO_BASE,
- val);
- sysctrl->fake_io[addr - 0x0398] = val;
-}
-
-static uint32_t PREP_io_read (void *opaque, uint32_t addr)
-{
- sysctrl_t *sysctrl = opaque;
-
- PPC_IO_DPRINTF("0x%08" PRIx32 " <= 0x%02" PRIx32 "\n", addr - PPC_IO_BASE,
- sysctrl->fake_io[addr - 0x0398]);
- return sysctrl->fake_io[addr - 0x0398];
-}
-
static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
{
sysctrl_t *sysctrl = opaque;
@@ -476,10 +458,10 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
PCIBus *pci_bus;
PCIDevice *pci;
ISABus *isa_bus;
+ ISADevice *isa;
qemu_irq *cpu_exit_irq;
int ppc_boot_device;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- DriveInfo *fd[MAX_FD];
sysctrl = g_malloc0(sizeof(sysctrl_t));
@@ -606,6 +588,11 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
sysbus_connect_irq(&pcihost->busdev, 3, qdev_get_gpio_in(&pci->qdev, 11));
isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&pci->qdev, "isa.0"));
+ /* Super I/O (parallel + serial ports) */
+ isa = isa_create(isa_bus, TYPE_PC87312);
+ qdev_prop_set_uint8(&isa->qdev, "config", 13); /* fdc, ser0, ser1, par0 */
+ qdev_init_nofail(&isa->qdev);
+
/* Register 8 MB of ISA IO space (needed for non-contiguous map) */
memory_region_init_io(PPC_io_memory, &PPC_prep_io_ops, sysctrl,
"ppc-io", 0x00800000);
@@ -614,8 +601,6 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
/* init basic PC hardware */
pci_vga_init(pci_bus);
- if (serial_hds[0])
- serial_isa_init(isa_bus, 0, serial_hds[0]);
nb_nics1 = nb_nics;
if (nb_nics1 > NE2000_NB_MAX)
nb_nics1 = NE2000_NB_MAX;
@@ -639,17 +624,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
}
isa_create_simple(isa_bus, "i8042");
- // SB16_init();
-
- for(i = 0; i < MAX_FD; i++) {
- fd[i] = drive_get(IF_FLOPPY, 0, i);
- }
- fdctrl_init_isa(isa_bus, fd);
-
- /* Register fake IO ports for PREP */
sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
- register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
- register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
/* System control ports */
register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c
index 177aa2d122..1b2c34f92c 100644
--- a/hw/ppce500_spin.c
+++ b/hw/ppce500_spin.c
@@ -212,7 +212,7 @@ static void ppce500_spin_class_init(ObjectClass *klass, void *data)
k->init = ppce500_spin_initfn;
}
-static TypeInfo ppce500_spin_info = {
+static const TypeInfo ppce500_spin_info = {
.name = "e500-spin",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SpinState),
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 3c51bc82aa..f3dffef5ab 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1194,7 +1194,7 @@ static void pxa2xx_rtc_sysbus_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pxa2xx_rtc_regs;
}
-static TypeInfo pxa2xx_rtc_sysbus_info = {
+static const TypeInfo pxa2xx_rtc_sysbus_info = {
.name = "pxa2xx_rtc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxRTCState),
@@ -1442,7 +1442,7 @@ static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
k->send = pxa2xx_i2c_tx;
}
-static TypeInfo pxa2xx_i2c_slave_info = {
+static const TypeInfo pxa2xx_i2c_slave_info = {
.name = "pxa2xx-i2c-slave",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(PXA2xxI2CSlaveState),
@@ -1510,7 +1510,7 @@ static void pxa2xx_i2c_class_init(ObjectClass *klass, void *data)
dc->props = pxa2xx_i2c_properties;
}
-static TypeInfo pxa2xx_i2c_info = {
+static const TypeInfo pxa2xx_i2c_info = {
.name = "pxa2xx_i2c",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxI2CState),
@@ -2273,7 +2273,7 @@ static void pxa2xx_ssp_class_init(ObjectClass *klass, void *data)
sdc->init = pxa2xx_ssp_init;
}
-static TypeInfo pxa2xx_ssp_info = {
+static const TypeInfo pxa2xx_ssp_info = {
.name = "pxa2xx-ssp",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxSSPState),
diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
index dbea1d2098..693b1c23d9 100644
--- a/hw/pxa2xx_dma.c
+++ b/hw/pxa2xx_dma.c
@@ -559,7 +559,7 @@ static void pxa2xx_dma_class_init(ObjectClass *klass, void *data)
dc->props = pxa2xx_dma_properties;
}
-static TypeInfo pxa2xx_dma_info = {
+static const TypeInfo pxa2xx_dma_info = {
.name = "pxa2xx-dma",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxDMAState),
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index 7aaf4092df..016833dfa1 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -334,7 +334,7 @@ static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
dc->props = pxa2xx_gpio_properties;
}
-static TypeInfo pxa2xx_gpio_info = {
+static const TypeInfo pxa2xx_gpio_info = {
.name = "pxa2xx-gpio",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxGPIOInfo),
diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
index 70b2b79d07..138245b0f9 100644
--- a/hw/pxa2xx_pic.c
+++ b/hw/pxa2xx_pic.c
@@ -319,7 +319,7 @@ static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pxa2xx_pic_regs;
}
-static TypeInfo pxa2xx_pic_info = {
+static const TypeInfo pxa2xx_pic_info = {
.name = "pxa2xx_pic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxPICState),
diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index e4ffb15bb2..32c1872680 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -495,7 +495,7 @@ static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
dc->props = pxa25x_timer_dev_properties;
}
-static TypeInfo pxa25x_timer_dev_info = {
+static const TypeInfo pxa25x_timer_dev_info = {
.name = "pxa25x-timer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxTimerInfo),
@@ -520,7 +520,7 @@ static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
dc->props = pxa27x_timer_dev_properties;
}
-static TypeInfo pxa27x_timer_dev_info = {
+static const TypeInfo pxa27x_timer_dev_info = {
.name = "pxa27x-timer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxTimerInfo),
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index fdf14ec4a6..853bd08a1f 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -182,6 +182,18 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
qbus_walkerfn *busfn, void *opaque);
void qdev_reset_all(DeviceState *dev);
+
+/**
+ * @qbus_reset_all:
+ * @bus: Bus to be reset.
+ *
+ * Reset @bus and perform a bus-level ("hard") reset of all devices connected
+ * to it, including recursive processing of all buses below @bus itself. A
+ * hard reset means that qbus_reset_all will reset all state of the device.
+ * For PCI devices, for example, this will include the base address registers
+ * or configuration space.
+ */
+void qbus_reset_all(BusState *bus);
void qbus_reset_all_fn(void *opaque);
void qbus_free(BusState *bus);
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index b73986759b..93283ee57a 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -615,3 +615,54 @@ void qdev_machine_init(void)
qdev_get_peripheral_anon();
qdev_get_peripheral();
}
+
+QemuOptsList qemu_device_opts = {
+ .name = "device",
+ .implied_opt_name = "driver",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
+ .desc = {
+ /*
+ * no elements => accept any
+ * sanity checking will happen later
+ * when setting device properties
+ */
+ { /* end of list */ }
+ },
+};
+
+QemuOptsList qemu_global_opts = {
+ .name = "global",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
+ .desc = {
+ {
+ .name = "driver",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "property",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "value",
+ .type = QEMU_OPT_STRING,
+ },
+ { /* end of list */ }
+ },
+};
+
+int qemu_global_option(const char *str)
+{
+ char driver[64], property[64];
+ QemuOpts *opts;
+ int rc, offset;
+
+ rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
+ if (rc < 2 || str[offset] != '=') {
+ error_report("can't parse: \"%s\"", str);
+ return -1;
+ }
+
+ opts = qemu_opts_create_nofail(&qemu_global_opts);
+ qemu_opt_set(opts, "driver", driver);
+ qemu_opt_set(opts, "property", property);
+ qemu_opt_set(opts, "value", str+offset+1);
+ return 0;
+}
diff --git a/hw/qdev.c b/hw/qdev.c
index f2c248451c..1b68d0234a 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -228,10 +228,15 @@ void qdev_reset_all(DeviceState *dev)
qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
}
+void qbus_reset_all(BusState *bus)
+{
+ qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
+}
+
void qbus_reset_all_fn(void *opaque)
{
BusState *bus = opaque;
- qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
+ qbus_reset_all(bus);
}
/* can be used as ->unplug() callback for the simple cases */
@@ -698,16 +703,18 @@ static void device_class_base_init(ObjectClass *class, void *data)
klass->props = NULL;
}
-static void qdev_remove_from_bus(Object *obj)
+static void device_unparent(Object *obj)
{
DeviceState *dev = DEVICE(obj);
- bus_remove_child(dev->parent_bus, dev);
+ if (dev->parent_bus != NULL) {
+ bus_remove_child(dev->parent_bus, dev);
+ }
}
static void device_class_init(ObjectClass *class, void *data)
{
- class->unparent = qdev_remove_from_bus;
+ class->unparent = device_unparent;
}
void device_reset(DeviceState *dev)
@@ -730,7 +737,7 @@ Object *qdev_get_machine(void)
return dev;
}
-static TypeInfo device_type_info = {
+static const TypeInfo device_type_info = {
.name = TYPE_DEVICE,
.parent = TYPE_OBJECT,
.instance_size = sizeof(DeviceState),
diff --git a/hw/qxl.c b/hw/qxl.c
index d08b9bd3c1..00e517aaa3 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -2310,7 +2310,7 @@ static void qxl_primary_class_init(ObjectClass *klass, void *data)
dc->props = qxl_properties;
}
-static TypeInfo qxl_primary_info = {
+static const TypeInfo qxl_primary_info = {
.name = "qxl-vga",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIQXLDevice),
@@ -2332,7 +2332,7 @@ static void qxl_secondary_class_init(ObjectClass *klass, void *data)
dc->props = qxl_properties;
}
-static TypeInfo qxl_secondary_info = {
+static const TypeInfo qxl_secondary_info = {
.name = "qxl",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIQXLDevice),
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 5bc37a7120..b1b74d8e9c 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -59,7 +59,7 @@ static void realview_gic_class_init(ObjectClass *klass, void *data)
sdc->init = realview_gic_init;
}
-static TypeInfo realview_gic_info = {
+static const TypeInfo realview_gic_info = {
.name = "realview_gic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(RealViewGICState),
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index c59ec6b6df..cfbf3f47c1 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -1258,7 +1258,8 @@ static void rtl8139_reset(DeviceState *d)
s->BasicModeStatus = 0x7809;
//s->BasicModeStatus |= 0x0040; /* UTP medium */
s->BasicModeStatus |= 0x0020; /* autonegotiation completed */
- s->BasicModeStatus |= 0x0004; /* link is up */
+ /* preserve link state */
+ s->BasicModeStatus |= s->nic->nc.link_down ? 0 : 0x04;
s->NWayAdvert = 0x05e1; /* all modes, full duplex */
s->NWayLPAR = 0x05e1; /* all modes, full duplex */
@@ -3539,7 +3540,7 @@ static void rtl8139_class_init(ObjectClass *klass, void *data)
dc->props = rtl8139_properties;
}
-static TypeInfo rtl8139_info = {
+static const TypeInfo rtl8139_info = {
.name = "rtl8139",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(RTL8139State),
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 7e991755b4..bcb09f202e 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -419,7 +419,7 @@ static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
dc->props = s390_virtio_net_properties;
}
-static TypeInfo s390_virtio_net = {
+static const TypeInfo s390_virtio_net = {
.name = "virtio-net-s390",
.parent = TYPE_VIRTIO_S390_DEVICE,
.instance_size = sizeof(VirtIOS390Device),
@@ -445,7 +445,7 @@ static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
dc->props = s390_virtio_blk_properties;
}
-static TypeInfo s390_virtio_blk = {
+static const TypeInfo s390_virtio_blk = {
.name = "virtio-blk-s390",
.parent = TYPE_VIRTIO_S390_DEVICE,
.instance_size = sizeof(VirtIOS390Device),
@@ -467,7 +467,7 @@ static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
dc->props = s390_virtio_serial_properties;
}
-static TypeInfo s390_virtio_serial = {
+static const TypeInfo s390_virtio_serial = {
.name = "virtio-serial-s390",
.parent = TYPE_VIRTIO_S390_DEVICE,
.instance_size = sizeof(VirtIOS390Device),
@@ -489,7 +489,7 @@ static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
k->init = s390_virtio_rng_init;
}
-static TypeInfo s390_virtio_rng = {
+static const TypeInfo s390_virtio_rng = {
.name = "virtio-rng-s390",
.parent = TYPE_VIRTIO_S390_DEVICE,
.instance_size = sizeof(VirtIOS390Device),
@@ -514,7 +514,7 @@ static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
dc->unplug = qdev_simple_unplug_cb;
}
-static TypeInfo virtio_s390_device_info = {
+static const TypeInfo virtio_s390_device_info = {
.name = TYPE_VIRTIO_S390_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(VirtIOS390Device),
@@ -537,7 +537,7 @@ static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
dc->props = s390_virtio_scsi_properties;
}
-static TypeInfo s390_virtio_scsi = {
+static const TypeInfo s390_virtio_scsi = {
.name = "virtio-scsi-s390",
.parent = TYPE_VIRTIO_S390_DEVICE,
.instance_size = sizeof(VirtIOS390Device),
@@ -562,7 +562,7 @@ static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo s390_virtio_bridge_info = {
+static const TypeInfo s390_virtio_bridge_info = {
.name = "s390-virtio-bridge",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusDevice),
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 89b1b66bd2..6b56995189 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -345,7 +345,7 @@ static void init_event_facility_class(ObjectClass *klass, void *data)
k->init = init_event_facility;
}
-static TypeInfo s390_sclp_event_facility_info = {
+static const TypeInfo s390_sclp_event_facility_info = {
.name = "s390-sclp-event-facility",
.parent = TYPE_DEVICE_S390_SCLP,
.instance_size = sizeof(S390SCLPDevice),
@@ -380,7 +380,7 @@ static void event_class_init(ObjectClass *klass, void *data)
dc->exit = event_qdev_exit;
}
-static TypeInfo s390_sclp_event_type_info = {
+static const TypeInfo s390_sclp_event_type_info = {
.name = TYPE_SCLP_EVENT,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SCLPEvent),
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 7ad791d5e3..a9d3a6a91d 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -146,7 +146,7 @@ static void s390_sclp_device_class_init(ObjectClass *klass, void *data)
dc->init = s390_sclp_dev_init;
}
-static TypeInfo s390_sclp_device_info = {
+static const TypeInfo s390_sclp_device_info = {
.name = TYPE_DEVICE_S390_SCLP,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(S390SCLPDevice),
diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c
index aa70e16665..adc0ee83f4 100644
--- a/hw/s390x/sclpconsole.c
+++ b/hw/s390x/sclpconsole.c
@@ -291,7 +291,7 @@ static void console_class_init(ObjectClass *klass, void *data)
ec->write_event_data = write_event_data;
}
-static TypeInfo sclp_console_info = {
+static const TypeInfo sclp_console_info = {
.name = "sclpconsole",
.parent = TYPE_SCLP_EVENT,
.instance_size = sizeof(SCLPConsole),
diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c
index 6e6f5624df..2538498959 100644
--- a/hw/s390x/sclpquiesce.c
+++ b/hw/s390x/sclpquiesce.c
@@ -107,7 +107,7 @@ static void quiesce_class_init(ObjectClass *klass, void *data)
k->write_event_data = NULL;
}
-static TypeInfo sclp_quiesce_info = {
+static const TypeInfo sclp_quiesce_info = {
.name = "sclpquiesce",
.parent = TYPE_SCLP_EVENT,
.instance_size = sizeof(SCLPEvent),
diff --git a/hw/sb16.c b/hw/sb16.c
index bb460ccb60..52dfedf5f1 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -1409,7 +1409,7 @@ static void sb16_class_initfn (ObjectClass *klass, void *data)
dc->props = sb16_properties;
}
-static TypeInfo sb16_info = {
+static const TypeInfo sb16_info = {
.name = "sb16",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof (SB16State),
diff --git a/hw/sbi.c b/hw/sbi.c
index ca78a384c7..d58184a6aa 100644
--- a/hw/sbi.c
+++ b/hw/sbi.c
@@ -141,7 +141,7 @@ static void sbi_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_sbi;
}
-static TypeInfo sbi_info = {
+static const TypeInfo sbi_info = {
.name = "sbi",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SBIState),
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 970c1fc01b..267a942f76 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1863,7 +1863,7 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
k->props = scsi_props;
}
-static TypeInfo scsi_device_type_info = {
+static const TypeInfo scsi_device_type_info = {
.name = TYPE_SCSI_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SCSIDevice),
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a69735b0a6..f8d7ef3374 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -2389,7 +2389,7 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_scsi_disk_state;
}
-static TypeInfo scsi_hd_info = {
+static const TypeInfo scsi_hd_info = {
.name = "scsi-hd",
.parent = TYPE_SCSI_DEVICE,
.instance_size = sizeof(SCSIDiskState),
@@ -2418,7 +2418,7 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_scsi_disk_state;
}
-static TypeInfo scsi_cd_info = {
+static const TypeInfo scsi_cd_info = {
.name = "scsi-cd",
.parent = TYPE_SCSI_DEVICE,
.instance_size = sizeof(SCSIDiskState),
@@ -2447,7 +2447,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_scsi_disk_state;
}
-static TypeInfo scsi_block_info = {
+static const TypeInfo scsi_block_info = {
.name = "scsi-block",
.parent = TYPE_SCSI_DEVICE,
.instance_size = sizeof(SCSIDiskState),
@@ -2481,7 +2481,7 @@ static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_scsi_disk_state;
}
-static TypeInfo scsi_disk_info = {
+static const TypeInfo scsi_disk_info = {
.name = "scsi-disk",
.parent = TYPE_SCSI_DEVICE,
.instance_size = sizeof(SCSIDiskState),
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 4c702be19f..8175474a67 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -499,7 +499,7 @@ static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_scsi_device;
}
-static TypeInfo scsi_generic_info = {
+static const TypeInfo scsi_generic_info = {
.name = "scsi-generic",
.parent = TYPE_SCSI_DEVICE,
.instance_size = sizeof(SCSIDevice),
diff --git a/hw/serial-isa.c b/hw/serial-isa.c
index 96c78f7f8d..5a6f51f856 100644
--- a/hw/serial-isa.c
+++ b/hw/serial-isa.c
@@ -99,7 +99,7 @@ static void serial_isa_class_initfn(ObjectClass *klass, void *data)
dc->props = serial_isa_properties;
}
-static TypeInfo serial_isa_info = {
+static const TypeInfo serial_isa_info = {
.name = "isa-serial",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISASerialState),
diff --git a/hw/serial-pci.c b/hw/serial-pci.c
index 50e8ab7faf..1c31353f6d 100644
--- a/hw/serial-pci.c
+++ b/hw/serial-pci.c
@@ -221,21 +221,21 @@ static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
dc->props = multi_4x_serial_pci_properties;
}
-static TypeInfo serial_pci_info = {
+static const TypeInfo serial_pci_info = {
.name = "pci-serial",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCISerialState),
.class_init = serial_pci_class_initfn,
};
-static TypeInfo multi_2x_serial_pci_info = {
+static const TypeInfo multi_2x_serial_pci_info = {
.name = "pci-serial-2x",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIMultiSerialState),
.class_init = multi_2x_serial_pci_class_initfn,
};
-static TypeInfo multi_4x_serial_pci_info = {
+static const TypeInfo multi_4x_serial_pci_info = {
.name = "pci-serial-4x",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIMultiSerialState),
diff --git a/hw/sga.c b/hw/sga.c
index d5c91ed98e..29bc3e0246 100644
--- a/hw/sga.c
+++ b/hw/sga.c
@@ -48,7 +48,7 @@ static void sga_class_initfn(ObjectClass *klass, void *data)
dc->desc = "Serial Graphics Adapter";
}
-static TypeInfo sga_info = {
+static const TypeInfo sga_info = {
.name = "sga",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISASGAState),
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index 018b1c198b..077d957003 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -156,7 +156,7 @@ static void sh_pci_host_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R;
}
-static TypeInfo sh_pci_host_info = {
+static const TypeInfo sh_pci_host_info = {
.name = "sh_pci_host",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -170,7 +170,7 @@ static void sh_pci_device_class_init(ObjectClass *klass, void *data)
sdc->init = sh_pci_device_init;
}
-static TypeInfo sh_pci_device_info = {
+static const TypeInfo sh_pci_device_info = {
.name = "sh_pci",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SHPCIState),
diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index a44ce95c1f..d67c8ccc9f 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -456,7 +456,7 @@ static void slavio_intctl_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_intctl;
}
-static TypeInfo slavio_intctl_info = {
+static const TypeInfo slavio_intctl_info = {
.name = "slavio_intctl",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SLAVIO_INTCTLState),
diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
index 704f2b173b..af24cc1ae8 100644
--- a/hw/slavio_misc.c
+++ b/hw/slavio_misc.c
@@ -478,7 +478,7 @@ static void slavio_misc_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_misc;
}
-static TypeInfo slavio_misc_info = {
+static const TypeInfo slavio_misc_info = {
.name = "slavio_misc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MiscState),
@@ -492,7 +492,7 @@ static void apc_class_init(ObjectClass *klass, void *data)
k->init = apc_init1;
}
-static TypeInfo apc_info = {
+static const TypeInfo apc_info = {
.name = "apc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MiscState),
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index 584629f1a5..68a4c0cca4 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -420,7 +420,7 @@ static void slavio_timer_class_init(ObjectClass *klass, void *data)
dc->props = slavio_timer_properties;
}
-static TypeInfo slavio_timer_info = {
+static const TypeInfo slavio_timer_info = {
.name = "slavio_timer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SLAVIO_TIMERState),
diff --git a/hw/smbus.c b/hw/smbus.c
index e3cf6a2cc8..a908591590 100644
--- a/hw/smbus.c
+++ b/hw/smbus.c
@@ -318,7 +318,7 @@ static void smbus_device_class_init(ObjectClass *klass, void *data)
sc->send = smbus_i2c_send;
}
-static TypeInfo smbus_device_type_info = {
+static const TypeInfo smbus_device_type_info = {
.name = TYPE_SMBUS_DEVICE,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(SMBusDevice),
diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c
index 11adab01b8..d36dc7bbe3 100644
--- a/hw/smbus_eeprom.c
+++ b/hw/smbus_eeprom.c
@@ -123,7 +123,7 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
dc->props = smbus_eeprom_properties;
}
-static TypeInfo smbus_eeprom_info = {
+static const TypeInfo smbus_eeprom_info = {
.name = "smbus-eeprom",
.parent = TYPE_SMBUS_DEVICE,
.instance_size = sizeof(SMBusEEPROMDevice),
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 2161b4af7a..a34698f9e3 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -774,7 +774,7 @@ static void smc91c111_class_init(ObjectClass *klass, void *data)
dc->props = smc91c111_properties;
}
-static TypeInfo smc91c111_info = {
+static const TypeInfo smc91c111_info = {
.name = "smc91c111",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(smc91c111_state),
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index 8077eb94bc..db34b485aa 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -502,7 +502,7 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data)
k->rtce_window_size = 0x10000000;
}
-static TypeInfo spapr_vlan_info = {
+static const TypeInfo spapr_vlan_info = {
.name = "spapr-vlan",
.parent = TYPE_VIO_SPAPR_DEVICE,
.instance_size = sizeof(VIOsPAPRVLANDevice),
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index a58621d17e..3a1a4864e6 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -536,7 +536,7 @@ static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo spapr_vio_bridge_info = {
+static const TypeInfo spapr_vio_bridge_info = {
.name = "spapr-vio-bridge",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusDevice),
@@ -552,7 +552,7 @@ static void vio_spapr_device_class_init(ObjectClass *klass, void *data)
k->props = spapr_vio_props;
}
-static TypeInfo spapr_vio_type_info = {
+static const TypeInfo spapr_vio_type_info = {
.name = TYPE_VIO_SPAPR_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(VIOsPAPRDevice),
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 2d811320ca..7fc0e13f9f 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -967,7 +967,7 @@ static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
k->rtce_window_size = 0x10000000;
}
-static TypeInfo spapr_vscsi_info = {
+static const TypeInfo spapr_vscsi_info = {
.name = "spapr-vscsi",
.parent = TYPE_VIO_SPAPR_DEVICE,
.instance_size = sizeof(VSCSIState),
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index ec81a7e6e8..5c63eaafa9 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -150,7 +150,7 @@ static void spapr_vty_class_init(ObjectClass *klass, void *data)
dc->props = spapr_vty_properties;
}
-static TypeInfo spapr_vty_info = {
+static const TypeInfo spapr_vty_info = {
.name = "spapr-vty",
.parent = TYPE_VIO_SPAPR_DEVICE,
.instance_size = sizeof(VIOsPAPRVTYDevice),
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index d11a302f20..6d0df51749 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -300,7 +300,7 @@ static void sparc32_dma_class_init(ObjectClass *klass, void *data)
dc->props = sparc32_dma_properties;
}
-static TypeInfo sparc32_dma_info = {
+static const TypeInfo sparc32_dma_info = {
.name = "sparc32_dma",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(DMAState),
diff --git a/hw/spitz.c b/hw/spitz.c
index 8e1be7fb21..f1659c4502 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1022,7 +1022,7 @@ static void sl_nand_class_init(ObjectClass *klass, void *data)
dc->props = sl_nand_properties;
}
-static TypeInfo sl_nand_info = {
+static const TypeInfo sl_nand_info = {
.name = "sl-nand",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SLNANDState),
@@ -1057,7 +1057,7 @@ static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
dc->props = spitz_keyboard_properties;
}
-static TypeInfo spitz_keyboard_info = {
+static const TypeInfo spitz_keyboard_info = {
.name = "spitz-keyboard",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SpitzKeyboardState),
@@ -1086,7 +1086,7 @@ static void corgi_ssp_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_corgi_ssp_regs;
}
-static TypeInfo corgi_ssp_info = {
+static const TypeInfo corgi_ssp_info = {
.name = "corgi-ssp",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(CorgiSSPState),
@@ -1116,7 +1116,7 @@ static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_spitz_lcdtg_regs;
}
-static TypeInfo spitz_lcdtg_info = {
+static const TypeInfo spitz_lcdtg_info = {
.name = "spitz-lcdtg",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(SpitzLCDTG),
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index cbdf49af57..8777b1681a 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -306,7 +306,7 @@ static void ssd0303_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ssd0303;
}
-static TypeInfo ssd0303_info = {
+static const TypeInfo ssd0303_info = {
.name = "ssd0303",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(ssd0303_state),
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index fe6f801ae7..84c86a5244 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -357,7 +357,7 @@ static void ssd0323_class_init(ObjectClass *klass, void *data)
k->cs_polarity = SSI_CS_HIGH;
}
-static TypeInfo ssd0323_info = {
+static const TypeInfo ssd0323_info = {
.name = "ssd0323",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ssd0323_state),
diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c
index d61c3328d9..dca8906e7d 100644
--- a/hw/ssi-sd.c
+++ b/hw/ssi-sd.c
@@ -259,7 +259,7 @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
k->cs_polarity = SSI_CS_LOW;
}
-static TypeInfo ssi_sd_info = {
+static const TypeInfo ssi_sd_info = {
.name = "ssi-sd",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ssi_sd_state),
diff --git a/hw/ssi.c b/hw/ssi.c
index 2b56357153..0b18176f7a 100644
--- a/hw/ssi.c
+++ b/hw/ssi.c
@@ -78,7 +78,7 @@ static void ssi_slave_class_init(ObjectClass *klass, void *data)
}
}
-static TypeInfo ssi_slave_info = {
+static const TypeInfo ssi_slave_info = {
.name = TYPE_SSI_SLAVE,
.parent = TYPE_DEVICE,
.class_init = ssi_slave_class_init,
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 26da3c7f60..12e4568534 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1354,7 +1354,7 @@ static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
sdc->init = stellaris_i2c_init;
}
-static TypeInfo stellaris_i2c_info = {
+static const TypeInfo stellaris_i2c_info = {
.name = "stellaris-i2c",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(stellaris_i2c_state),
@@ -1368,7 +1368,7 @@ static void stellaris_gptm_class_init(ObjectClass *klass, void *data)
sdc->init = stellaris_gptm_init;
}
-static TypeInfo stellaris_gptm_info = {
+static const TypeInfo stellaris_gptm_info = {
.name = "stellaris-gptm",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(gptm_state),
@@ -1382,7 +1382,7 @@ static void stellaris_adc_class_init(ObjectClass *klass, void *data)
sdc->init = stellaris_adc_init;
}
-static TypeInfo stellaris_adc_info = {
+static const TypeInfo stellaris_adc_info = {
.name = "stellaris-adc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(stellaris_adc_state),
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index d7e1e21ff9..5e9053fa26 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -434,7 +434,7 @@ static void stellaris_enet_class_init(ObjectClass *klass, void *data)
dc->props = stellaris_enet_properties;
}
-static TypeInfo stellaris_enet_info = {
+static const TypeInfo stellaris_enet_info = {
.name = "stellaris_enet",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(stellaris_enet_state),
diff --git a/hw/stream.c b/hw/stream.c
index be57e8b247..d4cf84d4c0 100644
--- a/hw/stream.c
+++ b/hw/stream.c
@@ -8,7 +8,7 @@ stream_push(StreamSlave *sink, uint8_t *buf, size_t len, uint32_t *app)
k->push(sink, buf, len, app);
}
-static TypeInfo stream_slave_info = {
+static const TypeInfo stream_slave_info = {
.name = TYPE_STREAM_SLAVE,
.parent = TYPE_INTERFACE,
.class_size = sizeof(StreamSlaveClass),
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 804c1a37a6..af688ac4ca 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -212,7 +212,7 @@ static void strongarm_pic_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_strongarm_pic_regs;
}
-static TypeInfo strongarm_pic_info = {
+static const TypeInfo strongarm_pic_info = {
.name = "strongarm_pic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMPICState),
@@ -433,7 +433,7 @@ static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_strongarm_rtc_regs;
}
-static TypeInfo strongarm_rtc_sysbus_info = {
+static const TypeInfo strongarm_rtc_sysbus_info = {
.name = "strongarm-rtc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMRTCState),
@@ -674,7 +674,7 @@ static void strongarm_gpio_class_init(ObjectClass *klass, void *data)
dc->desc = "StrongARM GPIO controller";
}
-static TypeInfo strongarm_gpio_info = {
+static const TypeInfo strongarm_gpio_info = {
.name = "strongarm-gpio",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMGPIOInfo),
@@ -840,7 +840,7 @@ static void strongarm_ppc_class_init(ObjectClass *klass, void *data)
dc->desc = "StrongARM PPC controller";
}
-static TypeInfo strongarm_ppc_info = {
+static const TypeInfo strongarm_ppc_info = {
.name = "strongarm-ppc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMPPCInfo),
@@ -1299,7 +1299,7 @@ static void strongarm_uart_class_init(ObjectClass *klass, void *data)
dc->props = strongarm_uart_properties;
}
-static TypeInfo strongarm_uart_info = {
+static const TypeInfo strongarm_uart_info = {
.name = "strongarm-uart",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMUARTState),
@@ -1538,7 +1538,7 @@ static void strongarm_ssp_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_strongarm_ssp_regs;
}
-static TypeInfo strongarm_ssp_info = {
+static const TypeInfo strongarm_ssp_info = {
.name = "strongarm-ssp",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMSSPState),
diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c
index b78d54f232..f8f4d023a3 100644
--- a/hw/sun4c_intctl.c
+++ b/hw/sun4c_intctl.c
@@ -193,7 +193,7 @@ static void sun4c_intctl_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_sun4c_intctl;
}
-static TypeInfo sun4c_intctl_info = {
+static const TypeInfo sun4c_intctl_info = {
.name = "sun4c_intctl",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Sun4c_INTCTLState),
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 0d84b373b1..5925d292c3 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -633,7 +633,7 @@ static void idreg_class_init(ObjectClass *klass, void *data)
k->init = idreg_init1;
}
-static TypeInfo idreg_info = {
+static const TypeInfo idreg_info = {
.name = "macio_idreg",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(IDRegState),
@@ -675,7 +675,7 @@ static void afx_class_init(ObjectClass *klass, void *data)
k->init = afx_init1;
}
-static TypeInfo afx_info = {
+static const TypeInfo afx_info = {
.name = "tcx_afx",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(AFXState),
@@ -752,7 +752,7 @@ static void prom_class_init(ObjectClass *klass, void *data)
dc->props = prom_properties;
}
-static TypeInfo prom_info = {
+static const TypeInfo prom_info = {
.name = "openprom",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PROMState),
@@ -816,7 +816,7 @@ static void ram_class_init(ObjectClass *klass, void *data)
dc->props = ram_properties;
}
-static TypeInfo ram_info = {
+static const TypeInfo ram_info = {
.name = "memory",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(RamDevice),
diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c
index ce6819e10b..8f9635f343 100644
--- a/hw/sun4m_iommu.c
+++ b/hw/sun4m_iommu.c
@@ -373,7 +373,7 @@ static void iommu_class_init(ObjectClass *klass, void *data)
dc->props = iommu_properties;
}
-static TypeInfo iommu_info = {
+static const TypeInfo iommu_info = {
.name = "iommu",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(IOMMUState),
diff --git a/hw/sun4u.c b/hw/sun4u.c
index cbfd217587..3a06d70795 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -618,7 +618,7 @@ static void ebus_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_OTHER;
}
-static TypeInfo ebus_info = {
+static const TypeInfo ebus_info = {
.name = "ebus",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(EbusState),
@@ -695,7 +695,7 @@ static void prom_class_init(ObjectClass *klass, void *data)
dc->props = prom_properties;
}
-static TypeInfo prom_info = {
+static const TypeInfo prom_info = {
.name = "openprom",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PROMState),
@@ -752,7 +752,7 @@ static void ram_class_init(ObjectClass *klass, void *data)
dc->props = ram_properties;
}
-static TypeInfo ram_info = {
+static const TypeInfo ram_info = {
.name = "memory",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(RamDevice),
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 49a41775f8..f0ab8a859a 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -255,7 +255,7 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data)
k->bus_type = TYPE_SYSTEM_BUS;
}
-static TypeInfo sysbus_device_type_info = {
+static const TypeInfo sysbus_device_type_info = {
.name = TYPE_SYS_BUS_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SysBusDevice),
diff --git a/hw/tcx.c b/hw/tcx.c
index 185588b49c..0ce2952f73 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -716,7 +716,7 @@ static void tcx_class_init(ObjectClass *klass, void *data)
dc->props = tcx_properties;
}
-static TypeInfo tcx_info = {
+static const TypeInfo tcx_info = {
.name = "SUNW,tcx",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(TCXState),
diff --git a/hw/tmp105.c b/hw/tmp105.c
index 9c67e644dd..0ade4eb6bd 100644
--- a/hw/tmp105.c
+++ b/hw/tmp105.c
@@ -239,7 +239,7 @@ static void tmp105_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_tmp105;
}
-static TypeInfo tmp105_info = {
+static const TypeInfo tmp105_info = {
.name = "tmp105",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(TMP105State),
diff --git a/hw/tosa.c b/hw/tosa.c
index 6ee4693840..7048b797d3 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -270,7 +270,7 @@ static void tosa_dac_class_init(ObjectClass *klass, void *data)
k->send = tosa_dac_send;
}
-static TypeInfo tosa_dac_info = {
+static const TypeInfo tosa_dac_info = {
.name = "tosa_dac",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(TosaDACState),
@@ -285,7 +285,7 @@ static void tosa_ssp_class_init(ObjectClass *klass, void *data)
k->transfer = tosa_ssp_tansfer;
}
-static TypeInfo tosa_ssp_info = {
+static const TypeInfo tosa_ssp_info = {
.name = "tosa-ssp",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(SSISlave),
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index 990d50619d..7d05b31024 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -798,7 +798,7 @@ static void tusb6010_class_init(ObjectClass *klass, void *data)
dc->reset = tusb6010_reset;
}
-static TypeInfo tusb6010_info = {
+static const TypeInfo tusb6010_info = {
.name = "tusb6010",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(TUSBState),
diff --git a/hw/twl92230.c b/hw/twl92230.c
index c71e4a2af0..70d9b03e55 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -867,7 +867,7 @@ static void twl92230_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_menelaus;
}
-static TypeInfo twl92230_info = {
+static const TypeInfo twl92230_info = {
.name = "twl92230",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(MenelausState),
diff --git a/hw/usb.h b/hw/usb.h
index 81e265c4fd..50c297f341 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -307,6 +307,12 @@ typedef struct USBDeviceClass {
*/
void (*flush_ep_queue)(USBDevice *dev, USBEndpoint *ep);
+ /*
+ * Called by the hcd to let the device know the queue for an endpoint
+ * has been unlinked / stopped. Optional may be NULL.
+ */
+ void (*ep_stopped)(USBDevice *dev, USBEndpoint *ep);
+
const char *product_desc;
const USBDesc *usb_desc;
} USBDeviceClass;
@@ -539,11 +545,23 @@ void usb_device_set_interface(USBDevice *dev, int interface,
void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep);
+void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep);
+
const char *usb_device_get_product_desc(USBDevice *dev);
const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
int ehci_create_ich9_with_companions(PCIBus *bus, int slot);
-#endif
+/* quirks.c */
+
+/* In bulk endpoints are streaming data sources (iow behave like isoc eps) */
+#define USB_QUIRK_BUFFER_BULK_IN 0x01
+/* Bulk pkts in FTDI format, need special handling when combining packets */
+#define USB_QUIRK_IS_FTDI 0x02
+int usb_get_quirks(uint16_t vendor_id, uint16_t product_id,
+ uint8_t interface_class, uint8_t interface_subclass,
+ uint8_t interface_protocol);
+
+#endif
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index 5a4eeb6d13..d1bbbc06e7 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -4,11 +4,11 @@ common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o hcd-ehci-pci.o hcd-ehci-sysbus.o
common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o
common-obj-y += libhw.o
-common-obj-$(CONFIG_SMARTCARD) += dev-smartcard-reader.o
-common-obj-$(CONFIG_USB_REDIR) += redirect.o
+common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
common-obj-y += core.o combined-packet.o bus.o desc.o dev-hub.o
common-obj-y += host-$(HOST_USB).o dev-bluetooth.o
common-obj-y += dev-hid.o dev-storage.o dev-wacom.o
common-obj-y += dev-serial.o dev-network.o dev-audio.o
+common-obj-y += dev-smartcard-reader.o
common-obj-y += dev-uas.o
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 10260a13ac..2dc76756a0 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -189,6 +189,14 @@ void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
}
}
+void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep)
+{
+ USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+ if (klass->ep_stopped) {
+ klass->ep_stopped(dev, ep);
+ }
+}
+
static int usb_qdev_init(DeviceState *qdev)
{
USBDevice *dev = USB_DEVICE(qdev);
@@ -620,7 +628,7 @@ static void usb_device_class_init(ObjectClass *klass, void *data)
k->props = usb_props;
}
-static TypeInfo usb_device_type_info = {
+static const TypeInfo usb_device_type_info = {
.name = TYPE_USB_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(USBDevice),
diff --git a/hw/usb/core.c b/hw/usb/core.c
index e315fc1021..d057aab900 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -761,7 +761,7 @@ USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
USBPacket *p;
- while ((p = QTAILQ_FIRST(&uep->queue)) != NULL) {
+ QTAILQ_FOREACH(p, &uep->queue, queue) {
if (p->id == id) {
return p;
}
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index b669601c92..b8c79b85e9 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -684,7 +684,7 @@ static void usb_audio_class_init(ObjectClass *klass, void *data)
k->set_interface = usb_audio_set_interface;
}
-static TypeInfo usb_audio_info = {
+static const TypeInfo usb_audio_info = {
.name = "usb-audio",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBAudioState),
diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
index a0d7a88d91..adbf9d4697 100644
--- a/hw/usb/dev-bluetooth.c
+++ b/hw/usb/dev-bluetooth.c
@@ -555,7 +555,7 @@ static void usb_bt_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_usb_bt;
}
-static TypeInfo bt_info = {
+static const TypeInfo bt_info = {
.name = "usb-bt-dongle",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(struct USBBtState),
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index ce38fef9f6..29b64819ab 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -501,7 +501,7 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p,
break;
case SET_IDLE:
hs->idle = (uint8_t) (value >> 8);
- hid_set_next_idle(hs, qemu_get_clock_ns(vm_clock));
+ hid_set_next_idle(hs);
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
hid_pointer_activate(hs);
}
@@ -523,16 +523,14 @@ static void usb_hid_handle_data(USBDevice *dev, USBPacket *p)
switch (p->pid) {
case USB_TOKEN_IN:
if (p->ep->nr == 1) {
- int64_t curtime = qemu_get_clock_ns(vm_clock);
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
hid_pointer_activate(hs);
}
- if (!hid_has_events(hs) &&
- (!hs->idle || hs->next_idle_clock - curtime > 0)) {
+ if (!hid_has_events(hs)) {
p->status = USB_RET_NAK;
return;
}
- hid_set_next_idle(hs, curtime);
+ hid_set_next_idle(hs);
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
len = hid_pointer_poll(hs, buf, p->iov.size);
} else if (hs->kind == HID_KEYBOARD) {
@@ -659,7 +657,7 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
dc->props = usb_tablet_properties;
}
-static TypeInfo usb_tablet_info = {
+static const TypeInfo usb_tablet_info = {
.name = "usb-tablet",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHIDState),
@@ -678,7 +676,7 @@ static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_usb_ptr;
}
-static TypeInfo usb_mouse_info = {
+static const TypeInfo usb_mouse_info = {
.name = "usb-mouse",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHIDState),
@@ -697,7 +695,7 @@ static void usb_keyboard_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_usb_kbd;
}
-static TypeInfo usb_keyboard_info = {
+static const TypeInfo usb_keyboard_info = {
.name = "usb-kbd",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHIDState),
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 470fbbb86c..79f2f46d55 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -568,7 +568,7 @@ static void usb_hub_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_usb_hub;
}
-static TypeInfo hub_info = {
+static const TypeInfo hub_info = {
.name = "usb-hub",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHubState),
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 1c54863452..9dede4c68d 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1433,7 +1433,7 @@ static void usb_net_class_initfn(ObjectClass *klass, void *data)
dc->props = net_properties;
}
-static TypeInfo net_info = {
+static const TypeInfo net_info = {
.name = "usb-net",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBNetState),
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 20cf5337b7..47ac8c9b69 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -600,7 +600,7 @@ static void usb_serial_class_initfn(ObjectClass *klass, void *data)
dc->props = serial_properties;
}
-static TypeInfo serial_info = {
+static const TypeInfo serial_info = {
.name = "usb-serial",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBSerialState),
@@ -628,7 +628,7 @@ static void usb_braille_class_initfn(ObjectClass *klass, void *data)
dc->props = braille_properties;
}
-static TypeInfo braille_info = {
+static const TypeInfo braille_info = {
.name = "usb-braille",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBSerialState),
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index f26bb341f7..979a473b37 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1322,7 +1322,7 @@ static void ccid_class_initfn(ObjectClass *klass, void *data)
dc->props = ccid_properties;
}
-static TypeInfo ccid_info = {
+static const TypeInfo ccid_info = {
.name = CCID_DEV_NAME,
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBCCIDState),
@@ -1338,7 +1338,7 @@ static void ccid_card_class_init(ObjectClass *klass, void *data)
k->props = ccid_props;
}
-static TypeInfo ccid_card_type_info = {
+static const TypeInfo ccid_card_type_info = {
.name = TYPE_CCID_CARD,
.parent = TYPE_DEVICE,
.instance_size = sizeof(CCIDCardState),
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 5025597673..1b87352db0 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -716,7 +716,7 @@ static void usb_msd_class_initfn(ObjectClass *klass, void *data)
dc->props = msd_properties;
}
-static TypeInfo msd_info = {
+static const TypeInfo msd_info = {
.name = "usb-storage",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(MSDState),
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 9a0088928f..d904d1a40b 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -757,7 +757,7 @@ static void usb_uas_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_usb_uas;
}
-static TypeInfo uas_info = {
+static const TypeInfo uas_info = {
.name = "usb-uas",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(UASDevice),
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 9ab368a6c5..ab9fa2ef48 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -366,7 +366,7 @@ static void usb_wacom_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_usb_wacom;
}
-static TypeInfo wacom_info = {
+static const TypeInfo wacom_info = {
.name = "usb-wacom-tablet",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBWacomState),
diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
index ee77d41db5..0eb78269f7 100644
--- a/hw/usb/hcd-ehci-pci.c
+++ b/hw/usb/hcd-ehci-pci.c
@@ -16,14 +16,8 @@
*/
#include "hw/usb/hcd-ehci.h"
-#include "hw/pci/pci.h"
#include "qemu/range.h"
-typedef struct EHCIPCIState {
- PCIDevice pcidev;
- EHCIState ehci;
-} EHCIPCIState;
-
typedef struct EHCIPCIInfo {
const char *name;
uint16_t vendor_id;
@@ -33,7 +27,7 @@ typedef struct EHCIPCIInfo {
static int usb_ehci_pci_initfn(PCIDevice *dev)
{
- EHCIPCIState *i = DO_UPCAST(EHCIPCIState, pcidev, dev);
+ EHCIPCIState *i = PCI_EHCI(dev);
EHCIState *s = &i->ehci;
uint8_t *pci_conf = dev->config;
@@ -83,7 +77,7 @@ static int usb_ehci_pci_initfn(PCIDevice *dev)
static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr,
uint32_t val, int l)
{
- EHCIPCIState *i = DO_UPCAST(EHCIPCIState, pcidev, dev);
+ EHCIPCIState *i = PCI_EHCI(dev);
bool busmaster;
pci_default_write_config(dev, addr, val, l);
@@ -115,12 +109,8 @@ static void ehci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- EHCIPCIInfo *i = data;
k->init = usb_ehci_pci_initfn;
- k->vendor_id = i->vendor_id;
- k->device_id = i->device_id;
- k->revision = i->revision;
k->class_id = PCI_CLASS_SERIAL_USB;
k->config_write = usb_ehci_pci_write_config;
k->no_hotplug = 1;
@@ -128,6 +118,24 @@ static void ehci_class_init(ObjectClass *klass, void *data)
dc->props = ehci_pci_properties;
}
+static const TypeInfo ehci_pci_type_info = {
+ .name = TYPE_PCI_EHCI,
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(EHCIPCIState),
+ .abstract = true,
+ .class_init = ehci_class_init,
+};
+
+static void ehci_data_class_init(ObjectClass *klass, void *data)
+{
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ EHCIPCIInfo *i = data;
+
+ k->vendor_id = i->vendor_id;
+ k->device_id = i->device_id;
+ k->revision = i->revision;
+}
+
static struct EHCIPCIInfo ehci_pci_info[] = {
{
.name = "usb-ehci",
@@ -150,12 +158,13 @@ static struct EHCIPCIInfo ehci_pci_info[] = {
static void ehci_pci_register_types(void)
{
TypeInfo ehci_type_info = {
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(EHCIPCIState),
- .class_init = ehci_class_init,
+ .parent = TYPE_PCI_EHCI,
+ .class_init = ehci_data_class_init,
};
int i;
+ type_register_static(&ehci_pci_type_info);
+
for (i = 0; i < ARRAY_SIZE(ehci_pci_info); i++) {
ehci_type_info.name = ehci_pci_info[i].name;
ehci_type_info.class_data = ehci_pci_info + i;
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index 803df92f31..b68a66a63b 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -16,12 +16,6 @@
*/
#include "hw/usb/hcd-ehci.h"
-#include "hw/sysbus.h"
-
-typedef struct EHCISysBusState {
- SysBusDevice busdev;
- EHCIState ehci;
-} EHCISysBusState;
static const VMStateDescription vmstate_ehci_sysbus = {
.name = "ehci-sysbus",
@@ -40,11 +34,12 @@ static Property ehci_sysbus_properties[] = {
static int usb_ehci_sysbus_initfn(SysBusDevice *dev)
{
- EHCISysBusState *i = FROM_SYSBUS(EHCISysBusState, dev);
+ EHCISysBusState *i = SYS_BUS_EHCI(dev);
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_GET_CLASS(dev);
EHCIState *s = &i->ehci;
- s->capsbase = 0x100;
- s->opregbase = 0x140;
+ s->capsbase = sec->capsbase;
+ s->opregbase = sec->opregbase;
s->dma = &dma_context_memory;
usb_ehci_initfn(s, DEVICE(dev));
@@ -63,16 +58,48 @@ static void ehci_sysbus_class_init(ObjectClass *klass, void *data)
dc->props = ehci_sysbus_properties;
}
-TypeInfo ehci_xlnx_type_info = {
- .name = "xlnx,ps7-usb",
+static const TypeInfo ehci_type_info = {
+ .name = TYPE_SYS_BUS_EHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(EHCISysBusState),
+ .abstract = true,
.class_init = ehci_sysbus_class_init,
+ .class_size = sizeof(SysBusEHCIClass),
+};
+
+static void ehci_xlnx_class_init(ObjectClass *oc, void *data)
+{
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+
+ sec->capsbase = 0x100;
+ sec->opregbase = 0x140;
+}
+
+static const TypeInfo ehci_xlnx_type_info = {
+ .name = "xlnx,ps7-usb",
+ .parent = TYPE_SYS_BUS_EHCI,
+ .class_init = ehci_xlnx_class_init,
+};
+
+static void ehci_exynos4210_class_init(ObjectClass *oc, void *data)
+{
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+
+ sec->capsbase = 0x0;
+ sec->opregbase = 0x10;
+}
+
+static const TypeInfo ehci_exynos4210_type_info = {
+ .name = TYPE_EXYNOS4210_EHCI,
+ .parent = TYPE_SYS_BUS_EHCI,
+ .class_init = ehci_exynos4210_class_init,
};
static void ehci_sysbus_register_types(void)
{
+ type_register_static(&ehci_type_info);
type_register_static(&ehci_xlnx_type_info);
+ type_register_static(&ehci_exynos4210_type_info);
}
type_init(ehci_sysbus_register_types)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 7536837fb2..320b7e7239 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -109,12 +109,13 @@
#define FRAME_TIMER_FREQ 1000
#define FRAME_TIMER_NS (1000000000 / FRAME_TIMER_FREQ)
+#define UFRAME_TIMER_NS (FRAME_TIMER_NS / 8)
#define NB_MAXINTRATE 8 // Max rate at which controller issues ints
#define BUFF_SIZE 5*4096 // Max bytes to transfer per transaction
#define MAX_QH 100 // Max allowable queue heads in a chain
-#define MIN_FR_PER_TICK 3 // Min frames to process when catching up
-#define PERIODIC_ACTIVE 64
+#define MIN_UFR_PER_TICK 24 /* Min frames to process when catching up */
+#define PERIODIC_ACTIVE 512 /* Micro-frames */
/* Internal periodic / asynchronous schedule state machine states
*/
@@ -192,6 +193,7 @@ static int ehci_state_executing(EHCIQueue *q);
static int ehci_state_writeback(EHCIQueue *q);
static int ehci_state_advqueue(EHCIQueue *q);
static int ehci_fill_queue(EHCIPacket *p);
+static void ehci_free_packet(EHCIPacket *p);
static const char *nr2str(const char **n, size_t len, uint32_t nr)
{
@@ -438,6 +440,136 @@ static inline bool ehci_periodic_enabled(EHCIState *s)
return ehci_enabled(s) && (s->usbcmd & USBCMD_PSE);
}
+/* Get an array of dwords from main memory */
+static inline int get_dwords(EHCIState *ehci, uint32_t addr,
+ uint32_t *buf, int num)
+{
+ int i;
+
+ if (!ehci->dma) {
+ ehci_raise_irq(ehci, USBSTS_HSE);
+ ehci->usbcmd &= ~USBCMD_RUNSTOP;
+ trace_usb_ehci_dma_error();
+ return -1;
+ }
+
+ for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
+ dma_memory_read(ehci->dma, addr, buf, sizeof(*buf));
+ *buf = le32_to_cpu(*buf);
+ }
+
+ return num;
+}
+
+/* Put an array of dwords in to main memory */
+static inline int put_dwords(EHCIState *ehci, uint32_t addr,
+ uint32_t *buf, int num)
+{
+ int i;
+
+ if (!ehci->dma) {
+ ehci_raise_irq(ehci, USBSTS_HSE);
+ ehci->usbcmd &= ~USBCMD_RUNSTOP;
+ trace_usb_ehci_dma_error();
+ return -1;
+ }
+
+ for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
+ uint32_t tmp = cpu_to_le32(*buf);
+ dma_memory_write(ehci->dma, addr, &tmp, sizeof(tmp));
+ }
+
+ return num;
+}
+
+static int ehci_get_pid(EHCIqtd *qtd)
+{
+ switch (get_field(qtd->token, QTD_TOKEN_PID)) {
+ case 0:
+ return USB_TOKEN_OUT;
+ case 1:
+ return USB_TOKEN_IN;
+ case 2:
+ return USB_TOKEN_SETUP;
+ default:
+ fprintf(stderr, "bad token\n");
+ return 0;
+ }
+}
+
+static bool ehci_verify_qh(EHCIQueue *q, EHCIqh *qh)
+{
+ uint32_t devaddr = get_field(qh->epchar, QH_EPCHAR_DEVADDR);
+ uint32_t endp = get_field(qh->epchar, QH_EPCHAR_EP);
+ if ((devaddr != get_field(q->qh.epchar, QH_EPCHAR_DEVADDR)) ||
+ (endp != get_field(q->qh.epchar, QH_EPCHAR_EP)) ||
+ (qh->current_qtd != q->qh.current_qtd) ||
+ (q->async && qh->next_qtd != q->qh.next_qtd) ||
+ (memcmp(&qh->altnext_qtd, &q->qh.altnext_qtd,
+ 7 * sizeof(uint32_t)) != 0) ||
+ (q->dev != NULL && q->dev->addr != devaddr)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static bool ehci_verify_qtd(EHCIPacket *p, EHCIqtd *qtd)
+{
+ if (p->qtdaddr != p->queue->qtdaddr ||
+ (p->queue->async && !NLPTR_TBIT(p->qtd.next) &&
+ (p->qtd.next != qtd->next)) ||
+ (!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd->altnext)) ||
+ p->qtd.token != qtd->token ||
+ p->qtd.bufptr[0] != qtd->bufptr[0]) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static bool ehci_verify_pid(EHCIQueue *q, EHCIqtd *qtd)
+{
+ int ep = get_field(q->qh.epchar, QH_EPCHAR_EP);
+ int pid = ehci_get_pid(qtd);
+
+ /* Note the pid changing is normal for ep 0 (the control ep) */
+ if (q->last_pid && ep != 0 && pid != q->last_pid) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/* Finish executing and writeback a packet outside of the regular
+ fetchqh -> fetchqtd -> execute -> writeback cycle */
+static void ehci_writeback_async_complete_packet(EHCIPacket *p)
+{
+ EHCIQueue *q = p->queue;
+ EHCIqtd qtd;
+ EHCIqh qh;
+ int state;
+
+ /* Verify the qh + qtd, like we do when going through fetchqh & fetchqtd */
+ get_dwords(q->ehci, NLPTR_GET(q->qhaddr),
+ (uint32_t *) &qh, sizeof(EHCIqh) >> 2);
+ get_dwords(q->ehci, NLPTR_GET(q->qtdaddr),
+ (uint32_t *) &qtd, sizeof(EHCIqtd) >> 2);
+ if (!ehci_verify_qh(q, &qh) || !ehci_verify_qtd(p, &qtd)) {
+ p->async = EHCI_ASYNC_INITIALIZED;
+ ehci_free_packet(p);
+ return;
+ }
+
+ state = ehci_get_state(q->ehci, q->async);
+ ehci_state_executing(q);
+ ehci_state_writeback(q); /* Frees the packet! */
+ if (!(q->qh.token & QTD_TOKEN_HALT)) {
+ ehci_state_advqueue(q);
+ }
+ ehci_set_state(q->ehci, q->async, state);
+}
+
/* packet management */
static EHCIPacket *ehci_alloc_packet(EHCIQueue *q)
@@ -455,17 +587,7 @@ static EHCIPacket *ehci_alloc_packet(EHCIQueue *q)
static void ehci_free_packet(EHCIPacket *p)
{
if (p->async == EHCI_ASYNC_FINISHED) {
- EHCIQueue *q = p->queue;
- int state = ehci_get_state(q->ehci, q->async);
- /* This is a normal, but rare condition (cancel racing completion) */
- fprintf(stderr, "EHCI: Warning packet completed but not processed\n");
- ehci_state_executing(q);
- ehci_state_writeback(q);
- if (!(q->qh.token & QTD_TOKEN_HALT)) {
- ehci_state_advqueue(q);
- }
- ehci_set_state(q->ehci, q->async, state);
- /* state_writeback recurses into us with async == EHCI_ASYNC_NONE!! */
+ ehci_writeback_async_complete_packet(p);
return;
}
trace_usb_ehci_packet_action(p->queue, p, "free");
@@ -500,6 +622,17 @@ static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, uint32_t addr, int async)
return q;
}
+static void ehci_queue_stopped(EHCIQueue *q)
+{
+ int endp = get_field(q->qh.epchar, QH_EPCHAR_EP);
+
+ if (!q->last_pid || !q->dev) {
+ return;
+ }
+
+ usb_device_ep_stopped(q->dev, usb_ep_get(q->dev, q->last_pid, endp));
+}
+
static int ehci_cancel_queue(EHCIQueue *q)
{
EHCIPacket *p;
@@ -507,7 +640,7 @@ static int ehci_cancel_queue(EHCIQueue *q)
p = QTAILQ_FIRST(&q->packets);
if (p == NULL) {
- return 0;
+ goto leave;
}
trace_usb_ehci_queue_action(q, "cancel");
@@ -515,6 +648,9 @@ static int ehci_cancel_queue(EHCIQueue *q)
ehci_free_packet(p);
packets++;
} while ((p = QTAILQ_FIRST(&q->packets)) != NULL);
+
+leave:
+ ehci_queue_stopped(q);
return packets;
}
@@ -526,6 +662,7 @@ static int ehci_reset_queue(EHCIQueue *q)
packets = ehci_cancel_queue(q);
q->dev = NULL;
q->qtdaddr = 0;
+ q->last_pid = 0;
return packets;
}
@@ -634,7 +771,6 @@ static void ehci_attach(USBPort *port)
*portsc |= PORTSC_CSC;
ehci_raise_irq(s, USBSTS_PCD);
- ehci_commit_irq(s);
}
static void ehci_detach(USBPort *port)
@@ -664,7 +800,6 @@ static void ehci_detach(USBPort *port)
*portsc |= PORTSC_CSC;
ehci_raise_irq(s, USBSTS_PCD);
- ehci_commit_irq(s);
}
static void ehci_child_detach(USBPort *port, USBDevice *child)
@@ -833,7 +968,15 @@ static uint64_t ehci_opreg_read(void *ptr, hwaddr addr,
EHCIState *s = ptr;
uint32_t val;
- val = s->opreg[addr >> 2];
+ switch (addr) {
+ case FRINDEX:
+ /* Round down to mult of 8, else it can go backwards on migration */
+ val = s->frindex & ~7;
+ break;
+ default:
+ val = s->opreg[addr >> 2];
+ }
+
trace_usb_ehci_opreg_read(addr + s->opregbase, addr2str(addr), val);
return val;
}
@@ -984,7 +1127,8 @@ static void ehci_opreg_write(void *ptr, hwaddr addr,
break;
case FRINDEX:
- val &= 0x00003ff8; /* frindex is 14bits and always a multiple of 8 */
+ val &= 0x00003fff; /* frindex is 14bits */
+ s->usbsts_frindex = val;
break;
case CONFIGFLAG:
@@ -1017,48 +1161,6 @@ static void ehci_opreg_write(void *ptr, hwaddr addr,
*mmio, old);
}
-/* Get an array of dwords from main memory */
-static inline int get_dwords(EHCIState *ehci, uint32_t addr,
- uint32_t *buf, int num)
-{
- int i;
-
- if (!ehci->dma) {
- ehci_raise_irq(ehci, USBSTS_HSE);
- ehci->usbcmd &= ~USBCMD_RUNSTOP;
- trace_usb_ehci_dma_error();
- return -1;
- }
-
- for(i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- dma_memory_read(ehci->dma, addr, buf, sizeof(*buf));
- *buf = le32_to_cpu(*buf);
- }
-
- return num;
-}
-
-/* Put an array of dwords in to main memory */
-static inline int put_dwords(EHCIState *ehci, uint32_t addr,
- uint32_t *buf, int num)
-{
- int i;
-
- if (!ehci->dma) {
- ehci_raise_irq(ehci, USBSTS_HSE);
- ehci->usbcmd &= ~USBCMD_RUNSTOP;
- trace_usb_ehci_dma_error();
- return -1;
- }
-
- for(i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- uint32_t tmp = cpu_to_le32(*buf);
- dma_memory_write(ehci->dma, addr, &tmp, sizeof(tmp));
- }
-
- return num;
-}
-
/*
* Write the qh back to guest physical memory. This step isn't
* in the EHCI spec but we need to do it since we don't share
@@ -1257,6 +1359,9 @@ static void ehci_execute_complete(EHCIQueue *q)
if (tbytes) {
/* 4.15.1.2 must raise int on a short input packet */
ehci_raise_irq(q->ehci, USBSTS_INT);
+ if (q->async) {
+ q->ehci->int_req_by_async = true;
+ }
}
} else {
tbytes = 0;
@@ -1301,22 +1406,11 @@ static int ehci_execute(EHCIPacket *p, const char *action)
return -1;
}
- p->pid = (p->qtd.token & QTD_TOKEN_PID_MASK) >> QTD_TOKEN_PID_SH;
- switch (p->pid) {
- case 0:
- p->pid = USB_TOKEN_OUT;
- break;
- case 1:
- p->pid = USB_TOKEN_IN;
- break;
- case 2:
- p->pid = USB_TOKEN_SETUP;
- break;
- default:
- fprintf(stderr, "bad token\n");
- break;
+ if (!ehci_verify_pid(p->queue, &p->qtd)) {
+ ehci_queue_stopped(p->queue); /* Mark the ep in the prev dir stopped */
}
-
+ p->pid = ehci_get_pid(&p->qtd);
+ p->queue->last_pid = p->pid;
endp = get_field(p->queue->qh.epchar, QH_EPCHAR_EP);
ep = usb_ep_get(p->queue->dev, p->pid, endp);
@@ -1551,8 +1645,7 @@ out:
static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
{
- EHCIPacket *p;
- uint32_t entry, devaddr, endp;
+ uint32_t entry;
EHCIQueue *q;
EHCIqh qh;
@@ -1561,7 +1654,6 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
if (NULL == q) {
q = ehci_alloc_queue(ehci, entry, async);
}
- p = QTAILQ_FIRST(&q->packets);
q->seen++;
if (q->seen > 1) {
@@ -1582,19 +1674,10 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
* The overlay area of the qh should never be changed by the guest,
* except when idle, in which case the reset is a nop.
*/
- devaddr = get_field(qh.epchar, QH_EPCHAR_DEVADDR);
- endp = get_field(qh.epchar, QH_EPCHAR_EP);
- if ((devaddr != get_field(q->qh.epchar, QH_EPCHAR_DEVADDR)) ||
- (endp != get_field(q->qh.epchar, QH_EPCHAR_EP)) ||
- (qh.current_qtd != q->qh.current_qtd) ||
- (q->async && qh.next_qtd != q->qh.next_qtd) ||
- (memcmp(&qh.altnext_qtd, &q->qh.altnext_qtd,
- 7 * sizeof(uint32_t)) != 0) ||
- (q->dev != NULL && q->dev->addr != devaddr)) {
+ if (!ehci_verify_qh(q, &qh)) {
if (ehci_reset_queue(q) > 0) {
ehci_trace_guest_bug(ehci, "guest updated active QH");
}
- p = NULL;
}
q->qh = qh;
@@ -1604,14 +1687,8 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
}
if (q->dev == NULL) {
- q->dev = ehci_find_device(q->ehci, devaddr);
- }
-
- if (p && p->async == EHCI_ASYNC_FINISHED) {
- /* I/O finished -- continue processing queue */
- trace_usb_ehci_packet_action(p->queue, p, "complete");
- ehci_set_state(ehci, async, EST_EXECUTING);
- goto out;
+ q->dev = ehci_find_device(q->ehci,
+ get_field(q->qh.epchar, QH_EPCHAR_DEVADDR));
}
if (async && (q->qh.epchar & QH_EPCHAR_H)) {
@@ -1762,13 +1839,11 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
p = QTAILQ_FIRST(&q->packets);
if (p != NULL) {
- if (p->qtdaddr != q->qtdaddr ||
- (q->async && !NLPTR_TBIT(p->qtd.next) &&
- (p->qtd.next != qtd.next)) ||
- (!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd.altnext)) ||
- p->qtd.bufptr[0] != qtd.bufptr[0]) {
+ if (!ehci_verify_qtd(p, &qtd)) {
ehci_cancel_queue(q);
- ehci_trace_guest_bug(q->ehci, "guest updated active QH or qTD");
+ if (qtd.token & QTD_TOKEN_ACTIVE) {
+ ehci_trace_guest_bug(q->ehci, "guest updated active qTD");
+ }
p = NULL;
} else {
p->qtd = qtd;
@@ -1777,11 +1852,6 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
}
if (!(qtd.token & QTD_TOKEN_ACTIVE)) {
- if (p != NULL) {
- /* transfer canceled by guest (clear active) */
- ehci_cancel_queue(q);
- p = NULL;
- }
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
} else if (p != NULL) {
switch (p->async) {
@@ -1797,10 +1867,7 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
break;
case EHCI_ASYNC_FINISHED:
- /*
- * We get here when advqueue moves to a packet which is already
- * finished, which can happen with packets queued up by fill_queue
- */
+ /* Complete executing of the packet */
ehci_set_state(q->ehci, q->async, EST_EXECUTING);
break;
}
@@ -1859,6 +1926,10 @@ static int ehci_fill_queue(EHCIPacket *p)
if (!(qtd.token & QTD_TOKEN_ACTIVE)) {
break;
}
+ if (!ehci_verify_pid(q, &qtd)) {
+ ehci_trace_guest_bug(q->ehci, "guest queued token with wrong pid");
+ break;
+ }
p = ehci_alloc_packet(q);
p->qtdaddr = qtdaddr;
p->qtd = qtd;
@@ -2176,16 +2247,16 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
}
}
-static void ehci_update_frindex(EHCIState *ehci, int frames)
+static void ehci_update_frindex(EHCIState *ehci, int uframes)
{
int i;
- if (!ehci_enabled(ehci)) {
+ if (!ehci_enabled(ehci) && ehci->pstate == EST_INACTIVE) {
return;
}
- for (i = 0; i < frames; i++) {
- ehci->frindex += 8;
+ for (i = 0; i < uframes; i++) {
+ ehci->frindex++;
if (ehci->frindex == 0x00002000) {
ehci_raise_irq(ehci, USBSTS_FLR);
@@ -2209,33 +2280,33 @@ static void ehci_frame_timer(void *opaque)
int need_timer = 0;
int64_t expire_time, t_now;
uint64_t ns_elapsed;
- int frames, skipped_frames;
+ int uframes, skipped_uframes;
int i;
t_now = qemu_get_clock_ns(vm_clock);
ns_elapsed = t_now - ehci->last_run_ns;
- frames = ns_elapsed / FRAME_TIMER_NS;
+ uframes = ns_elapsed / UFRAME_TIMER_NS;
if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) {
need_timer++;
- if (frames > ehci->maxframes) {
- skipped_frames = frames - ehci->maxframes;
- ehci_update_frindex(ehci, skipped_frames);
- ehci->last_run_ns += FRAME_TIMER_NS * skipped_frames;
- frames -= skipped_frames;
- DPRINTF("WARNING - EHCI skipped %d frames\n", skipped_frames);
+ if (uframes > (ehci->maxframes * 8)) {
+ skipped_uframes = uframes - (ehci->maxframes * 8);
+ ehci_update_frindex(ehci, skipped_uframes);
+ ehci->last_run_ns += UFRAME_TIMER_NS * skipped_uframes;
+ uframes -= skipped_uframes;
+ DPRINTF("WARNING - EHCI skipped %d uframes\n", skipped_uframes);
}
- for (i = 0; i < frames; i++) {
+ for (i = 0; i < uframes; i++) {
/*
* If we're running behind schedule, we should not catch up
* too fast, as that will make some guests unhappy:
- * 1) We must process a minimum of MIN_FR_PER_TICK frames,
+ * 1) We must process a minimum of MIN_UFR_PER_TICK frames,
* otherwise we will never catch up
* 2) Process frames until the guest has requested an irq (IOC)
*/
- if (i >= MIN_FR_PER_TICK) {
+ if (i >= MIN_UFR_PER_TICK) {
ehci_commit_irq(ehci);
if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) {
break;
@@ -2245,13 +2316,15 @@ static void ehci_frame_timer(void *opaque)
ehci->periodic_sched_active--;
}
ehci_update_frindex(ehci, 1);
- ehci_advance_periodic_state(ehci);
- ehci->last_run_ns += FRAME_TIMER_NS;
+ if ((ehci->frindex & 7) == 0) {
+ ehci_advance_periodic_state(ehci);
+ }
+ ehci->last_run_ns += UFRAME_TIMER_NS;
}
} else {
ehci->periodic_sched_active = 0;
- ehci_update_frindex(ehci, frames);
- ehci->last_run_ns += FRAME_TIMER_NS * frames;
+ ehci_update_frindex(ehci, uframes);
+ ehci->last_run_ns += UFRAME_TIMER_NS * uframes;
}
if (ehci->periodic_sched_active) {
@@ -2282,7 +2355,7 @@ static void ehci_frame_timer(void *opaque)
/* If we've raised int, we speed up the timer, so that we quickly
* notice any new packets queued up in response */
if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) {
- expire_time = t_now + get_ticks_per_sec() / (FRAME_TIMER_FREQ * 2);
+ expire_time = t_now + get_ticks_per_sec() / (FRAME_TIMER_FREQ * 4);
ehci->int_req_by_async = false;
} else {
expire_time = t_now + (get_ticks_per_sec()
@@ -2330,6 +2403,17 @@ static USBBusOps ehci_bus_ops = {
.wakeup_endpoint = ehci_wakeup_endpoint,
};
+static void usb_ehci_pre_save(void *opaque)
+{
+ EHCIState *ehci = opaque;
+ uint32_t new_frindex;
+
+ /* Round down frindex to a multiple of 8 for migration compatibility */
+ new_frindex = ehci->frindex & ~7;
+ ehci->last_run_ns -= (ehci->frindex - new_frindex) * UFRAME_TIMER_NS;
+ ehci->frindex = new_frindex;
+}
+
static int usb_ehci_post_load(void *opaque, int version_id)
{
EHCIState *s = opaque;
@@ -2380,6 +2464,7 @@ const VMStateDescription vmstate_ehci = {
.name = "ehci-core",
.version_id = 2,
.minimum_version_id = 1,
+ .pre_save = usb_ehci_pre_save,
.post_load = usb_ehci_post_load,
.fields = (VMStateField[]) {
/* mmio registers */
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index e35144d386..e95bb7ec46 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -24,6 +24,8 @@
#include "trace.h"
#include "sysemu/dma.h"
#include "sysemu/sysemu.h"
+#include "hw/pci/pci.h"
+#include "hw/sysbus.h"
#ifndef EHCI_DEBUG
#define EHCI_DEBUG 0
@@ -248,6 +250,7 @@ struct EHCIQueue {
EHCIqh qh; /* copy of current QH (being worked on) */
uint32_t qhaddr; /* address QH read from */
uint32_t qtdaddr; /* address QTD read from */
+ int last_pid; /* pid of last packet executed */
USBDevice *dev;
QTAILQ_HEAD(pkts_head, EHCIPacket) packets;
};
@@ -321,4 +324,43 @@ extern const VMStateDescription vmstate_ehci;
void usb_ehci_initfn(EHCIState *s, DeviceState *dev);
+#define TYPE_PCI_EHCI "pci-ehci-usb"
+#define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI)
+
+typedef struct EHCIPCIState {
+ /*< private >*/
+ PCIDevice pcidev;
+ /*< public >*/
+
+ EHCIState ehci;
+} EHCIPCIState;
+
+
+#define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb"
+#define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb"
+
+#define SYS_BUS_EHCI(obj) \
+ OBJECT_CHECK(EHCISysBusState, (obj), TYPE_SYS_BUS_EHCI)
+#define SYS_BUS_EHCI_CLASS(class) \
+ OBJECT_CLASS_CHECK(SysBusEHCIClass, (class), TYPE_SYS_BUS_EHCI)
+#define SYS_BUS_EHCI_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(SysBusEHCIClass, (obj), TYPE_SYS_BUS_EHCI)
+
+typedef struct EHCISysBusState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ EHCIState ehci;
+} EHCISysBusState;
+
+typedef struct SysBusEHCIClass {
+ /*< private >*/
+ SysBusDeviceClass parent_class;
+ /*< public >*/
+
+ uint16_t capsbase;
+ uint16_t opregbase;
+} SysBusEHCIClass;
+
#endif
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 052c4a3037..6a2f5f8c5d 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -430,6 +430,23 @@ static USBDevice *ohci_find_device(OHCIState *ohci, uint8_t addr)
return NULL;
}
+static void ohci_stop_endpoints(OHCIState *ohci)
+{
+ USBDevice *dev;
+ int i, j;
+
+ for (i = 0; i < ohci->num_ports; i++) {
+ dev = ohci->rhport[i].port.dev;
+ if (dev && dev->attached) {
+ usb_device_ep_stopped(dev, &dev->ep_ctl);
+ for (j = 0; j < USB_MAX_ENDPOINTS; j++) {
+ usb_device_ep_stopped(dev, &dev->ep_in[j]);
+ usb_device_ep_stopped(dev, &dev->ep_out[j]);
+ }
+ }
+ }
+}
+
/* Reset the controller */
static void ohci_reset(void *opaque)
{
@@ -478,6 +495,7 @@ static void ohci_reset(void *opaque)
usb_cancel_packet(&ohci->usb_packet);
ohci->async_td = 0;
}
+ ohci_stop_endpoints(ohci);
DPRINTF("usb-ohci: Reset %s\n", ohci->name);
}
@@ -1147,6 +1165,8 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
if (ohci->async_td && addr == ohci->async_td) {
usb_cancel_packet(&ohci->usb_packet);
ohci->async_td = 0;
+ usb_device_ep_stopped(ohci->usb_packet.ep->dev,
+ ohci->usb_packet.ep);
}
continue;
}
@@ -1227,10 +1247,12 @@ static void ohci_frame_boundary(void *opaque)
}
/* Cancel all pending packets if either of the lists has been disabled. */
- if (ohci->async_td &&
- ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
+ if (ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
+ if (ohci->async_td) {
+ usb_cancel_packet(&ohci->usb_packet);
+ ohci->async_td = 0;
+ }
+ ohci_stop_endpoints(ohci);
}
ohci->old_ctl = ohci->ctl;
ohci_process_lists(ohci, 0);
@@ -1887,7 +1909,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
dc->props = ohci_pci_properties;
}
-static TypeInfo ohci_pci_info = {
+static const TypeInfo ohci_pci_info = {
.name = "pci-ohci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(OHCIPCIState),
@@ -1910,7 +1932,7 @@ static void ohci_sysbus_class_init(ObjectClass *klass, void *data)
dc->props = ohci_sysbus_properties;
}
-static TypeInfo ohci_sysbus_info = {
+static const TypeInfo ohci_sysbus_info = {
.name = "sysbus-ohci",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(OHCISysBusState),
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 2af754b5cf..60645aa21f 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -75,6 +75,11 @@
#define FRAME_MAX_LOOPS 256
+/* Must be large enough to handle 10 frame delay for initial isoc requests */
+#define QH_VALID 32
+
+#define MAX_FRAMES_PER_TICK (QH_VALID / 2)
+
#define NB_PORTS 2
enum {
@@ -166,6 +171,7 @@ struct UHCIState {
/* Properties */
char *masterbus;
uint32_t firstport;
+ uint32_t maxframes;
};
typedef struct UHCI_TD {
@@ -206,9 +212,7 @@ static UHCIQueue *uhci_queue_new(UHCIState *s, uint32_t qh_addr, UHCI_TD *td,
queue->ep = ep;
QTAILQ_INIT(&queue->asyncs);
QTAILQ_INSERT_HEAD(&s->queues, queue, next);
- /* valid needs to be large enough to handle 10 frame delay
- * for initial isochronous requests */
- queue->valid = 32;
+ queue->valid = QH_VALID;
trace_usb_uhci_queue_add(queue->token);
return queue;
}
@@ -222,6 +226,7 @@ static void uhci_queue_free(UHCIQueue *queue, const char *reason)
async = QTAILQ_FIRST(&queue->asyncs);
uhci_async_cancel(async);
}
+ usb_device_ep_stopped(queue->ep->dev, queue->ep);
trace_usb_uhci_queue_del(queue->token, reason);
QTAILQ_REMOVE(&s->queues, queue, next);
@@ -433,7 +438,7 @@ static int uhci_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_uhci = {
.name = "uhci",
- .version_id = 2,
+ .version_id = 3,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.post_load = uhci_post_load,
@@ -451,44 +456,16 @@ static const VMStateDescription vmstate_uhci = {
VMSTATE_UINT8(status2, UHCIState),
VMSTATE_TIMER(frame_timer, UHCIState),
VMSTATE_INT64_V(expire_time, UHCIState, 2),
+ VMSTATE_UINT32_V(pending_int_mask, UHCIState, 3),
VMSTATE_END_OF_LIST()
}
};
-static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- UHCIState *s = opaque;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x0c:
- s->sof_timing = val;
- break;
- }
-}
-
-static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
-{
- UHCIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x0c:
- val = s->sof_timing;
- break;
- default:
- val = 0xff;
- break;
- }
- return val;
-}
-
-static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+static void uhci_port_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
{
UHCIState *s = opaque;
- addr &= 0x1f;
trace_usb_uhci_mmio_writew(addr, val);
switch(addr) {
@@ -498,7 +475,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
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));
+ qemu_mod_timer(s->frame_timer, s->expire_time);
s->status &= ~UHCI_STS_HCHALTED;
} else if (!(val & UHCI_CMD_RS)) {
s->status |= UHCI_STS_HCHALTED;
@@ -537,6 +514,17 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
if (s->status & UHCI_STS_HCHALTED)
s->frnum = val & 0x7ff;
break;
+ case 0x08:
+ s->fl_base_addr &= 0xffff0000;
+ s->fl_base_addr |= val & ~0xfff;
+ break;
+ case 0x0a:
+ s->fl_base_addr &= 0x0000ffff;
+ s->fl_base_addr |= (val << 16);
+ break;
+ case 0x0c:
+ s->sof_timing = val & 0xff;
+ break;
case 0x10 ... 0x1f:
{
UHCIPort *port;
@@ -568,12 +556,11 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
}
}
-static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
+static uint64_t uhci_port_read(void *opaque, hwaddr addr, unsigned size)
{
UHCIState *s = opaque;
uint32_t val;
- addr &= 0x1f;
switch(addr) {
case 0x00:
val = s->cmd;
@@ -587,6 +574,15 @@ static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
case 0x06:
val = s->frnum;
break;
+ case 0x08:
+ val = s->fl_base_addr & 0xffff;
+ break;
+ case 0x0a:
+ val = (s->fl_base_addr >> 16) & 0xffff;
+ break;
+ case 0x0c:
+ val = s->sof_timing;
+ break;
case 0x10 ... 0x1f:
{
UHCIPort *port;
@@ -609,38 +605,6 @@ static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
return val;
}
-static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- UHCIState *s = opaque;
-
- addr &= 0x1f;
- trace_usb_uhci_mmio_writel(addr, val);
-
- switch(addr) {
- case 0x08:
- s->fl_base_addr = val & ~0xfff;
- break;
- }
-}
-
-static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
-{
- UHCIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x08:
- val = s->fl_base_addr;
- break;
- default:
- val = 0xffffffff;
- break;
- }
- trace_usb_uhci_mmio_readl(addr, val);
- return val;
-}
-
/* signal resume if controller suspended */
static void uhci_resume (void *opaque)
{
@@ -853,7 +817,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
}
if (q) {
- q->valid = 32;
+ q->valid = QH_VALID;
}
/* Is active ? */
@@ -1174,10 +1138,10 @@ static void uhci_bh(void *opaque)
static void uhci_frame_timer(void *opaque)
{
UHCIState *s = opaque;
+ uint64_t t_now, t_last_run;
+ int i, frames;
+ const uint64_t frame_t = get_ticks_per_sec() / FRAME_TIMER_FREQ;
- /* prepare the timer for the next frame */
- s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ);
- s->frame_bytes = 0;
s->completions_only = false;
qemu_bh_cancel(s->bh);
@@ -1191,7 +1155,35 @@ static void uhci_frame_timer(void *opaque)
return;
}
- /* Complete the previous frame */
+ /* We still store expire_time in our state, for migration */
+ t_last_run = s->expire_time - frame_t;
+ t_now = qemu_get_clock_ns(vm_clock);
+
+ /* Process up to MAX_FRAMES_PER_TICK frames */
+ frames = (t_now - t_last_run) / frame_t;
+ if (frames > s->maxframes) {
+ int skipped = frames - s->maxframes;
+ s->expire_time += skipped * frame_t;
+ s->frnum = (s->frnum + skipped) & 0x7ff;
+ frames -= skipped;
+ }
+ if (frames > MAX_FRAMES_PER_TICK) {
+ frames = MAX_FRAMES_PER_TICK;
+ }
+
+ for (i = 0; i < frames; i++) {
+ s->frame_bytes = 0;
+ trace_usb_uhci_frame_start(s->frnum);
+ uhci_async_validate_begin(s);
+ uhci_process_frame(s);
+ uhci_async_validate_end(s);
+ /* The spec says frnum is the frame currently being processed, and
+ * the guest must look at frnum - 1 on interrupt, so inc frnum now */
+ s->frnum = (s->frnum + 1) & 0x7ff;
+ s->expire_time += frame_t;
+ }
+
+ /* Complete the previous frame(s) */
if (s->pending_int_mask) {
s->status2 |= s->pending_int_mask;
s->status |= UHCI_STS_USBINT;
@@ -1199,32 +1191,17 @@ static void uhci_frame_timer(void *opaque)
}
s->pending_int_mask = 0;
- /* Start new frame */
- s->frnum = (s->frnum + 1) & 0x7ff;
-
- trace_usb_uhci_frame_start(s->frnum);
-
- uhci_async_validate_begin(s);
-
- uhci_process_frame(s);
-
- uhci_async_validate_end(s);
-
- qemu_mod_timer(s->frame_timer, s->expire_time);
+ qemu_mod_timer(s->frame_timer, t_now + frame_t);
}
-static const MemoryRegionPortio uhci_portio[] = {
- { 0, 32, 2, .write = uhci_ioport_writew, },
- { 0, 32, 2, .read = uhci_ioport_readw, },
- { 0, 32, 4, .write = uhci_ioport_writel, },
- { 0, 32, 4, .read = uhci_ioport_readl, },
- { 0, 32, 1, .write = uhci_ioport_writeb, },
- { 0, 32, 1, .read = uhci_ioport_readb, },
- PORTIO_END_OF_LIST()
-};
-
static const MemoryRegionOps uhci_ioport_ops = {
- .old_portio = uhci_portio,
+ .read = uhci_port_read,
+ .write = uhci_port_write,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
+ .impl.min_access_size = 2,
+ .impl.max_access_size = 2,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static USBPortOps uhci_port_ops = {
@@ -1311,6 +1288,7 @@ static Property uhci_properties[] = {
DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
DEFINE_PROP_UINT32("bandwidth", UHCIState, frame_bandwidth, 1280),
+ DEFINE_PROP_UINT32("maxframes", UHCIState, maxframes, 128),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index e2de71ef1a..92f2eee3bc 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1177,6 +1177,7 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
XHCISlot *slot;
XHCIEPContext *epctx;
int i, xferi, killed = 0;
+ USBEndpoint *ep = NULL;
assert(slotid >= 1 && slotid <= xhci->numslots);
assert(epid >= 1 && epid <= 31);
@@ -1192,9 +1193,15 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
xferi = epctx->next_xfer;
for (i = 0; i < TD_QUEUE; i++) {
+ if (epctx->transfers[xferi].packet.ep) {
+ ep = epctx->transfers[xferi].packet.ep;
+ }
killed += xhci_ep_nuke_one_xfer(&epctx->transfers[xferi]);
xferi = (xferi + 1) % TD_QUEUE;
}
+ if (ep) {
+ usb_device_ep_stopped(ep->dev, ep);
+ }
return killed;
}
@@ -1963,13 +1970,18 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
if (bsr) {
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);
usb_device_reset(dev);
- usb_device_handle_control(dev, NULL,
+ usb_packet_setup(&p, USB_TOKEN_OUT,
+ usb_ep_get(dev, USB_TOKEN_OUT, 0),
+ 0, false, false);
+ usb_device_handle_control(dev, &p,
DeviceOutRequest | USB_REQ_SET_ADDRESS,
slot->devaddr, 0, 0, NULL);
+ assert(p.status != USB_RET_ASYNC);
}
res = xhci_enable_ep(xhci, slotid, 1, octx+32, ep0_ctx);
@@ -3170,7 +3182,7 @@ static void xhci_class_init(ObjectClass *klass, void *data)
k->no_hotplug = 1;
}
-static TypeInfo xhci_info = {
+static const TypeInfo xhci_info = {
.name = "nec-usb-xhci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(XHCIState),
diff --git a/hw/usb/host-bsd.c b/hw/usb/host-bsd.c
index 340c21aeb4..172aecbffd 100644
--- a/hw/usb/host-bsd.c
+++ b/hw/usb/host-bsd.c
@@ -407,7 +407,7 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
uc->handle_destroy = usb_host_handle_destroy;
}
-static TypeInfo usb_host_dev_info = {
+static const TypeInfo usb_host_dev_info = {
.name = "usb-host",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHostDevice),
diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c
index 669fbd245c..e8e6a42fb9 100644
--- a/hw/usb/host-linux.c
+++ b/hw/usb/host-linux.c
@@ -1534,7 +1534,7 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
dc->props = usb_host_dev_properties;
}
-static TypeInfo usb_host_dev_info = {
+static const TypeInfo usb_host_dev_info = {
.name = "usb-host",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHostDevice),
diff --git a/hw/usb/quirks-ftdi-ids.h b/hw/usb/quirks-ftdi-ids.h
new file mode 100644
index 0000000000..57c12ef662
--- /dev/null
+++ b/hw/usb/quirks-ftdi-ids.h
@@ -0,0 +1,1255 @@
+/*
+ * vendor/product IDs (VID/PID) of devices using FTDI USB serial converters.
+ * Please keep numerically sorted within individual areas, thanks!
+ *
+ * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
+ * from Rudolf Gugler
+ *
+ */
+
+
+/**********************************/
+/***** devices using FTDI VID *****/
+/**********************************/
+
+
+#define FTDI_VID 0x0403 /* Vendor Id */
+
+
+/*** "original" FTDI device PIDs ***/
+
+#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
+#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
+#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
+#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */
+#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */
+#define FTDI_FTX_PID 0x6015 /* FT-X series (FT201X, FT230X, FT231X, etc) */
+#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
+#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
+
+
+/*** third-party PIDs (using FTDI_VID) ***/
+
+#define FTDI_LUMEL_PD12_PID 0x6002
+
+/*
+ * Marvell OpenRD Base, Client
+ * http://www.open-rd.org
+ * OpenRD Base, Client use VID 0x0403
+ */
+#define MARVELL_OPENRD_PID 0x9e90
+
+/* www.candapter.com Ewert Energy Systems CANdapter device */
+#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */
+
+/*
+ * Texas Instruments XDS100v2 JTAG / BeagleBone A3
+ * http://processors.wiki.ti.com/index.php/XDS100
+ * http://beagleboard.org/bone
+ */
+#define TI_XDS100V2_PID 0xa6d0
+
+#define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */
+
+/* US Interface Navigator (http://www.usinterface.com/) */
+#define FTDI_USINT_CAT_PID 0xb810 /* Navigator CAT and 2nd PTT lines */
+#define FTDI_USINT_WKEY_PID 0xb811 /* Navigator WKEY and FSK lines */
+#define FTDI_USINT_RS232_PID 0xb812 /* Navigator RS232 and CONFIG lines */
+
+/* OOCDlink by Joern Kaipf <joernk@web.de>
+ * (http://www.joernonline.de/) */
+#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */
+
+/* Luminary Micro Stellaris Boards, VID = FTDI_VID */
+/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */
+#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8
+#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9
+#define LMI_LM3S_ICDI_BOARD_PID 0xbcda
+
+#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */
+
+/* OpenDCC (www.opendcc.de) product id */
+#define FTDI_OPENDCC_PID 0xBFD8
+#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9
+#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA
+#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB
+#define FTDI_OPENDCC_GBM_PID 0xBFDC
+
+/* NZR SEM 16+ USB (http://www.nzr.de) */
+#define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */
+
+/*
+ * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com)
+ */
+#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */
+
+/* DMX4ALL DMX Interfaces */
+#define FTDI_DMX4ALL 0xC850
+
+/*
+ * ASK.fr devices
+ */
+#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */
+
+/* www.starting-point-systems.com µChameleon device */
+#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */
+
+/*
+ * Tactrix OpenPort (ECU) devices.
+ * OpenPort 1.3M submitted by Donour Sizemore.
+ * OpenPort 1.3S and 1.3U submitted by Ian Abbott.
+ */
+#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */
+#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */
+#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */
+
+#define FTDI_DISTORTEC_JTAG_LOCK_PICK_PID 0xCFF8
+
+/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */
+/* the VID is the standard ftdi vid (FTDI_VID) */
+#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */
+#define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */
+#define FTDI_SCS_DEVICE_2_PID 0xD012
+#define FTDI_SCS_DEVICE_3_PID 0xD013
+#define FTDI_SCS_DEVICE_4_PID 0xD014
+#define FTDI_SCS_DEVICE_5_PID 0xD015
+#define FTDI_SCS_DEVICE_6_PID 0xD016
+#define FTDI_SCS_DEVICE_7_PID 0xD017
+
+/* iPlus device */
+#define FTDI_IPLUS_PID 0xD070 /* Product Id */
+#define FTDI_IPLUS2_PID 0xD071 /* Product Id */
+
+/*
+ * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com.
+ */
+#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */
+
+/* Propox devices */
+#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
+#define FTDI_PROPOX_ISPCABLEIII_PID 0xD739
+
+/* Lenz LI-USB Computer Interface. */
+#define FTDI_LENZ_LIUSB_PID 0xD780
+
+/* Vardaan Enterprises Serial Interface VEUSB422R3 */
+#define FTDI_VARDAAN_PID 0xF070
+
+/*
+ * Xsens Technologies BV products (http://www.xsens.com).
+ */
+#define XSENS_CONVERTER_0_PID 0xD388
+#define XSENS_CONVERTER_1_PID 0xD389
+#define XSENS_CONVERTER_2_PID 0xD38A
+#define XSENS_CONVERTER_3_PID 0xD38B
+#define XSENS_CONVERTER_4_PID 0xD38C
+#define XSENS_CONVERTER_5_PID 0xD38D
+#define XSENS_CONVERTER_6_PID 0xD38E
+#define XSENS_CONVERTER_7_PID 0xD38F
+
+/*
+ * NDI (www.ndigital.com) product ids
+ */
+#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */
+#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */
+#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */
+#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */
+#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */
+
+/*
+ * ChamSys Limited (www.chamsys.co.uk) USB wing/interface product IDs
+ */
+#define FTDI_CHAMSYS_24_MASTER_WING_PID 0xDAF8
+#define FTDI_CHAMSYS_PC_WING_PID 0xDAF9
+#define FTDI_CHAMSYS_USB_DMX_PID 0xDAFA
+#define FTDI_CHAMSYS_MIDI_TIMECODE_PID 0xDAFB
+#define FTDI_CHAMSYS_MINI_WING_PID 0xDAFC
+#define FTDI_CHAMSYS_MAXI_WING_PID 0xDAFD
+#define FTDI_CHAMSYS_MEDIA_WING_PID 0xDAFE
+#define FTDI_CHAMSYS_WING_PID 0xDAFF
+
+/*
+ * Westrex International devices submitted by Cory Lee
+ */
+#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */
+#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */
+
+/*
+ * ACG Identification Technologies GmbH products (http://www.acg.de/).
+ * Submitted by anton -at- goto10 -dot- org.
+ */
+#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */
+
+/*
+ * Definitions for Artemis astronomical USB based cameras
+ * Check it at http://www.artemisccd.co.uk/
+ */
+#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */
+
+/*
+ * Definitions for ATIK Instruments astronomical USB based cameras
+ * Check it at http://www.atik-instruments.com/
+ */
+#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */
+#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */
+#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */
+#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */
+#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */
+
+/*
+ * Yost Engineering, Inc. products (www.yostengineering.com).
+ * PID 0xE050 submitted by Aaron Prose.
+ */
+#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */
+
+/*
+ * ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
+ * All of these devices use FTDI's vendor ID (0x0403).
+ * Further IDs taken from ELV Windows .inf file.
+ *
+ * The previously included PID for the UO 100 module was incorrect.
+ * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58).
+ *
+ * Armin Laeuger originally sent the PID for the UM 100 module.
+ */
+#define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */
+#define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */
+#define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */
+#define FTDI_ELV_WS550_PID 0xE004 /* WS 550 */
+#define FTDI_ELV_EC3000_PID 0xE006 /* ENERGY CONTROL 3000 USB */
+#define FTDI_ELV_WS888_PID 0xE008 /* WS 888 */
+#define FTDI_ELV_TWS550_PID 0xE009 /* Technoline WS 550 */
+#define FTDI_ELV_FEM_PID 0xE00A /* Funk Energie Monitor */
+#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */
+#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */
+#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */
+#define FTDI_ELV_UMS100_PID 0xE0EB /* ELV USB Master-Slave Schaltsteckdose UMS 100 */
+#define FTDI_ELV_TFD128_PID 0xE0EC /* ELV Temperatur-Feuchte-Datenlogger TFD 128 */
+#define FTDI_ELV_FM3RX_PID 0xE0ED /* ELV Messwertuebertragung FM3 RX */
+#define FTDI_ELV_WS777_PID 0xE0EE /* Conrad WS 777 */
+#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Energy monitor EM 1010 PC */
+#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */
+#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */
+#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */
+#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */
+#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */
+#define FTDI_ELV_UTP8_PID 0xE0F5 /* ELV UTP 8 */
+#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */
+#define FTDI_ELV_WS444PC_PID 0xE0F7 /* Conrad WS 444 PC */
+#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */
+#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */
+#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */
+#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */
+#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */
+#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */
+#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */
+#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */
+#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */
+#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */
+#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */
+#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */
+/* Additional ELV PIDs that default to using the FTDI D2XX drivers on
+ * MS Windows, rather than the FTDI Virtual Com Port drivers.
+ * Maybe these will be easier to use with the libftdi/libusb user-space
+ * drivers, or possibly the Comedi drivers in some cases. */
+#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */
+#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */
+#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperatur-Feuchte-Messgeraet (TFM 100) */
+#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkuhr (UDF 77) */
+#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */
+
+/*
+ * EVER Eco Pro UPS (http://www.ever.com.pl/)
+ */
+
+#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */
+
+/*
+ * Active Robots product ids.
+ */
+#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */
+
+/* Pyramid Computer GmbH */
+#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */
+
+/* www.elsterelectricity.com Elster Unicom III Optical Probe */
+#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */
+
+/*
+ * Gude Analog- und Digitalsysteme GmbH
+ */
+#define FTDI_GUDEADS_E808_PID 0xE808
+#define FTDI_GUDEADS_E809_PID 0xE809
+#define FTDI_GUDEADS_E80A_PID 0xE80A
+#define FTDI_GUDEADS_E80B_PID 0xE80B
+#define FTDI_GUDEADS_E80C_PID 0xE80C
+#define FTDI_GUDEADS_E80D_PID 0xE80D
+#define FTDI_GUDEADS_E80E_PID 0xE80E
+#define FTDI_GUDEADS_E80F_PID 0xE80F
+#define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */
+#define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */
+#define FTDI_GUDEADS_E88A_PID 0xE88A
+#define FTDI_GUDEADS_E88B_PID 0xE88B
+#define FTDI_GUDEADS_E88C_PID 0xE88C
+#define FTDI_GUDEADS_E88D_PID 0xE88D
+#define FTDI_GUDEADS_E88E_PID 0xE88E
+#define FTDI_GUDEADS_E88F_PID 0xE88F
+
+/*
+ * Eclo (http://www.eclo.pt/) product IDs.
+ * PID 0xEA90 submitted by Martin Grill.
+ */
+#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */
+
+/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */
+#define FTDI_TNC_X_PID 0xEBE0
+
+/*
+ * Teratronik product ids.
+ * Submitted by O. Wölfelschneider.
+ */
+#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */
+#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */
+
+/* Rig Expert Ukraine devices */
+#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */
+
+/*
+ * Hameg HO820 and HO870 interface (using VID 0x0403)
+ */
+#define HAMEG_HO820_PID 0xed74
+#define HAMEG_HO730_PID 0xed73
+#define HAMEG_HO720_PID 0xed72
+#define HAMEG_HO870_PID 0xed71
+
+/*
+ * MaxStream devices www.maxstream.net
+ */
+#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */
+
+/*
+ * microHAM product IDs (http://www.microham.com).
+ * Submitted by Justin Burket (KL1RL) <zorton@jtan.com>
+ * and Mike Studer (K6EEP) <k6eep@hamsoftware.org>.
+ * Ian Abbott <abbotti@mev.co.uk> added a few more from the driver INF file.
+ */
+#define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */
+#define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */
+#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */
+#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */
+#define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */
+#define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */
+#define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */
+#define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */
+
+/* Domintell products http://www.domintell.com */
+#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */
+#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */
+
+/*
+ * The following are the values for the Perle Systems
+ * UltraPort USB serial converters
+ */
+#define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */
+
+/* Sprog II (Andrew Crosland's SprogII DCC interface) */
+#define FTDI_SPROG_II 0xF0C8
+
+/* an infrared receiver for user access control with IR tags */
+#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */
+
+/* ACT Solutions HomePro ZWave interface
+ (http://www.act-solutions.com/HomePro-Product-Matrix.html) */
+#define FTDI_ACTZWAVE_PID 0xF2D0
+
+/*
+ * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485,
+ * USB-TTY aktiv, USB-TTY passiv. Some PIDs are used by several devices
+ * and I'm not entirely sure which are used by which.
+ */
+#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0
+#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1
+#define FTDI_4N_GALAXY_DE_3_PID 0xF3C2
+
+/*
+ * Linx Technologies product ids
+ */
+#define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */
+#define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */
+#define LINX_FUTURE_0_PID 0xF44A /* Linx future device */
+#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */
+#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */
+
+/*
+ * Oceanic product ids
+ */
+#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */
+
+/*
+ * SUUNTO product ids
+ */
+#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */
+
+/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */
+/* http://www.usbuirt.com/ */
+#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */
+
+/* CCS Inc. ICDU/ICDU40 product ID -
+ * the FT232BM is used in an in-circuit-debugger unit for PIC16's/PIC18's */
+#define FTDI_CCSICDU20_0_PID 0xF9D0
+#define FTDI_CCSICDU40_1_PID 0xF9D1
+#define FTDI_CCSMACHX_2_PID 0xF9D2
+#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3
+#define FTDI_CCSICDU64_4_PID 0xF9D4
+#define FTDI_CCSPRIME8_5_PID 0xF9D5
+
+/*
+ * The following are the values for the Matrix Orbital LCD displays,
+ * which are the FT232BM ( similar to the 8U232AM )
+ */
+#define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */
+#define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */
+#define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */
+#define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */
+#define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */
+#define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */
+#define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */
+
+/*
+ * Home Electronics (www.home-electro.com) USB gadgets
+ */
+#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */
+
+/* Inside Accesso contactless reader (http://www.insidecontactless.com/) */
+#define INSIDE_ACCESSO 0xFAD0
+
+/*
+ * ThorLabs USB motor drivers
+ */
+#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */
+
+/*
+ * Protego product ids
+ */
+#define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */
+#define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */
+#define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */
+#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */
+
+/*
+ * Sony Ericsson product ids
+ */
+#define FTDI_DSS20_PID 0xFC82 /* DSS-20 Sync Station for Sony Ericsson P800 */
+#define FTDI_URBAN_0_PID 0xFC8A /* Sony Ericsson Urban, uart #0 */
+#define FTDI_URBAN_1_PID 0xFC8B /* Sony Ericsson Urban, uart #1 */
+
+/* www.irtrans.de device */
+#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */
+
+/*
+ * RM Michaelides CANview USB (http://www.rmcan.com) (FTDI_VID)
+ * CAN fieldbus interface adapter, added by port GmbH www.port.de)
+ * Ian Abbott changed the macro names for consistency.
+ */
+#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */
+/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */
+#define FTDI_TTUSB_PID 0xFF20 /* Product Id */
+
+#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 (FTDI_VID) */
+
+#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */
+
+/*
+ * PCDJ use ftdi based dj-controllers. The following PID is
+ * for their DAC-2 device http://www.pcdjhardware.com/DAC2.asp
+ * (the VID is the standard ftdi vid (FTDI_VID), PID sent by Wouter Paesen)
+ */
+#define FTDI_PCDJ_DAC2_PID 0xFA88
+
+#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG (FTDI_VID) */
+
+/*
+ * DIEBOLD BCS SE923 (FTDI_VID)
+ */
+#define DIEBOLD_BCS_SE923_PID 0xfb99
+
+/* www.crystalfontz.com devices
+ * - thanx for providing free devices for evaluation !
+ * they use the ftdi chipset for the USB interface
+ * and the vendor id is the same
+ */
+#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */
+#define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */
+#define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */
+#define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */
+#define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */
+#define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */
+#define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */
+#define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */
+
+/*
+ * Video Networks Limited / Homechoice in the UK use an ftdi-based device
+ * for their 1Mb broadband internet service. The following PID is exhibited
+ * by the usb device supplied (the VID is the standard ftdi vid (FTDI_VID)
+ */
+#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */
+
+/* AlphaMicro Components AMC-232USB01 device (FTDI_VID) */
+#define FTDI_AMC232_PID 0xFF00 /* Product Id */
+
+/*
+ * IBS elektronik product ids (FTDI_VID)
+ * Submitted by Thomas Schleusener
+ */
+#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */
+#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */
+#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */
+#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */
+#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */
+#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */
+#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */
+#define FTDI_IBS_PROD_PID 0xff3f /* future device */
+/* www.canusb.com Lawicel CANUSB device (FTDI_VID) */
+#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */
+
+/*
+ * TavIR AVR product ids (FTDI_VID)
+ */
+#define FTDI_TAVIR_STK500_PID 0xFA33 /* STK500 AVR programmer */
+
+/*
+ * TIAO product ids (FTDI_VID)
+ * http://www.tiaowiki.com/w/Main_Page
+ */
+#define FTDI_TIAO_UMPA_PID 0x8a98 /* TIAO/DIYGADGET USB Multi-Protocol Adapter */
+
+
+/********************************/
+/** third-party VID/PID combos **/
+/********************************/
+
+
+
+/*
+ * Atmel STK541
+ */
+#define ATMEL_VID 0x03eb /* Vendor ID */
+#define STK541_PID 0x2109 /* Zigbee Controller */
+
+/*
+ * Blackfin gnICE JTAG
+ * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice
+ */
+#define ADI_VID 0x0456
+#define ADI_GNICE_PID 0xF000
+#define ADI_GNICEPLUS_PID 0xF001
+
+/*
+ * Microchip Technology, Inc.
+ *
+ * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are
+ * used by single function CDC ACM class based firmware demo
+ * applications. The VID/PID has also been used in firmware
+ * emulating FTDI serial chips by:
+ * Hornby Elite - Digital Command Control Console
+ * http://www.hornby.com/hornby-dcc/controllers/
+ */
+#define MICROCHIP_VID 0x04D8
+#define MICROCHIP_USB_BOARD_PID 0x000A /* CDC RS-232 Emulation Demo */
+
+/*
+ * RATOC REX-USB60F
+ */
+#define RATOC_VENDOR_ID 0x0584
+#define RATOC_PRODUCT_ID_USB60F 0xb020
+
+/*
+ * Acton Research Corp.
+ */
+#define ACTON_VID 0x0647 /* Vendor ID */
+#define ACTON_SPECTRAPRO_PID 0x0100
+
+/*
+ * Contec products (http://www.contec.com)
+ * Submitted by Daniel Sangorrin
+ */
+#define CONTEC_VID 0x06CE /* Vendor ID */
+#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */
+
+/*
+ * Definitions for B&B Electronics products.
+ */
+#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */
+#define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */
+#define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */
+#define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */
+#define BANDB_USOPTL4_PID 0xAC11
+#define BANDB_USPTL4_PID 0xAC12
+#define BANDB_USO9ML2DR_2_PID 0xAC16
+#define BANDB_USO9ML2DR_PID 0xAC17
+#define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */
+#define BANDB_USOPTL4DR_PID 0xAC19
+#define BANDB_485USB9F_2W_PID 0xAC25
+#define BANDB_485USB9F_4W_PID 0xAC26
+#define BANDB_232USB9M_PID 0xAC27
+#define BANDB_485USBTB_2W_PID 0xAC33
+#define BANDB_485USBTB_4W_PID 0xAC34
+#define BANDB_TTL5USB9M_PID 0xAC49
+#define BANDB_TTL3USB9M_PID 0xAC50
+#define BANDB_ZZ_PROG1_USB_PID 0xBA02
+
+/*
+ * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI
+ */
+#define INTREPID_VID 0x093C
+#define INTREPID_VALUECAN_PID 0x0601
+#define INTREPID_NEOVI_PID 0x0701
+
+/*
+ * Definitions for ID TECH (www.idt-net.com) devices
+ */
+#define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */
+#define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */
+
+/*
+ * Definitions for Omnidirectional Control Technology, Inc. devices
+ */
+#define OCT_VID 0x0B39 /* OCT vendor ID */
+/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */
+/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */
+/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */
+#define OCT_DK201_PID 0x0103 /* OCT DK201 USB docking station */
+#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */
+
+/*
+ * Definitions for Icom Inc. devices
+ */
+#define ICOM_VID 0x0C26 /* Icom vendor ID */
+/* Note: ID-1 is a communications tranceiver for HAM-radio operators */
+#define ICOM_ID_1_PID 0x0004 /* ID-1 USB to RS-232 */
+/* Note: OPC is an Optional cable to connect an Icom Tranceiver */
+#define ICOM_OPC_U_UC_PID 0x0018 /* OPC-478UC, OPC-1122U cloning cable */
+/* Note: ID-RP* devices are Icom Repeater Devices for HAM-radio */
+#define ICOM_ID_RP2C1_PID 0x0009 /* ID-RP2C Asset 1 to RS-232 */
+#define ICOM_ID_RP2C2_PID 0x000A /* ID-RP2C Asset 2 to RS-232 */
+#define ICOM_ID_RP2D_PID 0x000B /* ID-RP2D configuration port*/
+#define ICOM_ID_RP2VT_PID 0x000C /* ID-RP2V Transmit config port */
+#define ICOM_ID_RP2VR_PID 0x000D /* ID-RP2V Receive config port */
+#define ICOM_ID_RP4KVT_PID 0x0010 /* ID-RP4000V Transmit config port */
+#define ICOM_ID_RP4KVR_PID 0x0011 /* ID-RP4000V Receive config port */
+#define ICOM_ID_RP2KVT_PID 0x0012 /* ID-RP2000V Transmit config port */
+#define ICOM_ID_RP2KVR_PID 0x0013 /* ID-RP2000V Receive config port */
+
+/*
+ * GN Otometrics (http://www.otometrics.com)
+ * Submitted by Ville Sundberg.
+ */
+#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */
+#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */
+
+/*
+ * The following are the values for the Sealevel SeaLINK+ adapters.
+ * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and
+ * removed some PIDs that don't seem to match any existing products.)
+ */
+#define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */
+#define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */
+#define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */
+#define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */
+#define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */
+#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */
+#define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */
+#define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */
+#define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */
+#define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */
+#define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */
+#define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */
+#define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */
+#define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */
+#define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */
+#define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */
+#define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */
+#define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */
+#define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */
+#define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */
+#define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */
+#define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */
+#define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */
+#define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */
+#define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */
+#define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */
+#define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */
+#define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */
+#define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */
+#define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */
+#define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */
+#define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */
+#define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */
+#define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */
+#define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */
+#define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */
+#define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */
+#define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */
+#define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */
+#define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */
+#define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */
+#define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */
+#define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */
+#define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */
+#define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */
+#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */
+#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */
+#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */
+#define SEALEVEL_2803R_1_PID 0Xa02a /* SeaLINK+8 (2803-ROHS) Port 1+2 */
+#define SEALEVEL_2803R_2_PID 0Xa02b /* SeaLINK+8 (2803-ROHS) Port 3+4 */
+#define SEALEVEL_2803R_3_PID 0Xa02c /* SeaLINK+8 (2803-ROHS) Port 5+6 */
+#define SEALEVEL_2803R_4_PID 0Xa02d /* SeaLINK+8 (2803-ROHS) Port 7+8 */
+
+/*
+ * JETI SPECTROMETER SPECBOS 1201
+ * http://www.jeti.com/cms/index.php/instruments/other-instruments/specbos-2101
+ */
+#define JETI_VID 0x0c6c
+#define JETI_SPC1201_PID 0x04b2
+
+/*
+ * FTDI USB UART chips used in construction projects from the
+ * Elektor Electronics magazine (http://www.elektor.com/)
+ */
+#define ELEKTOR_VID 0x0C7D
+#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */
+
+/*
+ * Posiflex inc retail equipment (http://www.posiflex.com.tw)
+ */
+#define POSIFLEX_VID 0x0d3a /* Vendor ID */
+#define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */
+
+/*
+ * The following are the values for two KOBIL chipcard terminals.
+ */
+#define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */
+#define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */
+#define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */
+
+#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */
+#define FTDI_NF_RIC_PID 0x0001 /* Product Id */
+
+/*
+ * Falcom Wireless Communications GmbH
+ */
+#define FALCOM_VID 0x0F94 /* Vendor Id */
+#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */
+#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */
+
+/* Larsen and Brusgaard AltiTrack/USBtrack */
+#define LARSENBRUSGAARD_VID 0x0FD8
+#define LB_ALTITRACK_PID 0x0001
+
+/*
+ * TTi (Thurlby Thandar Instruments)
+ */
+#define TTI_VID 0x103E /* Vendor Id */
+#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */
+
+/* Interbiometrics USB I/O Board */
+/* Developed for Interbiometrics by Rudolf Gugler */
+#define INTERBIOMETRICS_VID 0x1209
+#define INTERBIOMETRICS_IOBOARD_PID 0x1002
+#define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006
+
+/*
+ * Testo products (http://www.testo.com/)
+ * Submitted by Colin Leroy
+ */
+#define TESTO_VID 0x128D
+#define TESTO_USB_INTERFACE_PID 0x0001
+
+/*
+ * Mobility Electronics products.
+ */
+#define MOBILITY_VID 0x1342
+#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */
+
+/*
+ * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3
+ * Submitted by Harald Welte <laforge@openmoko.org>
+ */
+#define FIC_VID 0x1457
+#define FIC_NEO1973_DEBUG_PID 0x5118
+
+/* Olimex */
+#define OLIMEX_VID 0x15BA
+#define OLIMEX_ARM_USB_OCD_PID 0x0003
+#define OLIMEX_ARM_USB_OCD_H_PID 0x002b
+
+/*
+ * Telldus Technologies
+ */
+#define TELLDUS_VID 0x1781 /* Vendor ID */
+#define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */
+
+/*
+ * RT Systems programming cables for various ham radios
+ */
+#define RTSYSTEMS_VID 0x2100 /* Vendor ID */
+#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */
+#define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */
+#define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */
+
+
+/*
+ * Physik Instrumente
+ * http://www.physikinstrumente.com/en/products/
+ */
+/* These two devices use the VID of FTDI */
+#define PI_C865_PID 0xe0a0 /* PI C-865 Piezomotor Controller */
+#define PI_C857_PID 0xe0a1 /* PI Encoder Trigger Box */
+
+#define PI_VID 0x1a72 /* Vendor ID */
+#define PI_C866_PID 0x1000 /* PI C-866 Piezomotor Controller */
+#define PI_C663_PID 0x1001 /* PI C-663 Mercury-Step */
+#define PI_C725_PID 0x1002 /* PI C-725 Piezomotor Controller */
+#define PI_E517_PID 0x1005 /* PI E-517 Digital Piezo Controller Operation Module */
+#define PI_C863_PID 0x1007 /* PI C-863 */
+#define PI_E861_PID 0x1008 /* PI E-861 Piezomotor Controller */
+#define PI_C867_PID 0x1009 /* PI C-867 Piezomotor Controller */
+#define PI_E609_PID 0x100D /* PI E-609 Digital Piezo Controller */
+#define PI_E709_PID 0x100E /* PI E-709 Digital Piezo Controller */
+#define PI_100F_PID 0x100F /* PI Digital Piezo Controller */
+#define PI_1011_PID 0x1011 /* PI Digital Piezo Controller */
+#define PI_1012_PID 0x1012 /* PI Motion Controller */
+#define PI_1013_PID 0x1013 /* PI Motion Controller */
+#define PI_1014_PID 0x1014 /* PI Device */
+#define PI_1015_PID 0x1015 /* PI Device */
+#define PI_1016_PID 0x1016 /* PI Digital Servo Module */
+
+/*
+ * Kondo Kagaku Co.Ltd.
+ * http://www.kondo-robot.com/EN
+ */
+#define KONDO_VID 0x165c
+#define KONDO_USB_SERIAL_PID 0x0002
+
+/*
+ * Bayer Ascensia Contour blood glucose meter USB-converter cable.
+ * http://winglucofacts.com/cables/
+ */
+#define BAYER_VID 0x1A79
+#define BAYER_CONTOUR_CABLE_PID 0x6001
+
+/*
+ * The following are the values for the Matrix Orbital FTDI Range
+ * Anything in this range will use an FT232RL.
+ */
+#define MTXORB_VID 0x1B3D
+#define MTXORB_FTDI_RANGE_0100_PID 0x0100
+#define MTXORB_FTDI_RANGE_0101_PID 0x0101
+#define MTXORB_FTDI_RANGE_0102_PID 0x0102
+#define MTXORB_FTDI_RANGE_0103_PID 0x0103
+#define MTXORB_FTDI_RANGE_0104_PID 0x0104
+#define MTXORB_FTDI_RANGE_0105_PID 0x0105
+#define MTXORB_FTDI_RANGE_0106_PID 0x0106
+#define MTXORB_FTDI_RANGE_0107_PID 0x0107
+#define MTXORB_FTDI_RANGE_0108_PID 0x0108
+#define MTXORB_FTDI_RANGE_0109_PID 0x0109
+#define MTXORB_FTDI_RANGE_010A_PID 0x010A
+#define MTXORB_FTDI_RANGE_010B_PID 0x010B
+#define MTXORB_FTDI_RANGE_010C_PID 0x010C
+#define MTXORB_FTDI_RANGE_010D_PID 0x010D
+#define MTXORB_FTDI_RANGE_010E_PID 0x010E
+#define MTXORB_FTDI_RANGE_010F_PID 0x010F
+#define MTXORB_FTDI_RANGE_0110_PID 0x0110
+#define MTXORB_FTDI_RANGE_0111_PID 0x0111
+#define MTXORB_FTDI_RANGE_0112_PID 0x0112
+#define MTXORB_FTDI_RANGE_0113_PID 0x0113
+#define MTXORB_FTDI_RANGE_0114_PID 0x0114
+#define MTXORB_FTDI_RANGE_0115_PID 0x0115
+#define MTXORB_FTDI_RANGE_0116_PID 0x0116
+#define MTXORB_FTDI_RANGE_0117_PID 0x0117
+#define MTXORB_FTDI_RANGE_0118_PID 0x0118
+#define MTXORB_FTDI_RANGE_0119_PID 0x0119
+#define MTXORB_FTDI_RANGE_011A_PID 0x011A
+#define MTXORB_FTDI_RANGE_011B_PID 0x011B
+#define MTXORB_FTDI_RANGE_011C_PID 0x011C
+#define MTXORB_FTDI_RANGE_011D_PID 0x011D
+#define MTXORB_FTDI_RANGE_011E_PID 0x011E
+#define MTXORB_FTDI_RANGE_011F_PID 0x011F
+#define MTXORB_FTDI_RANGE_0120_PID 0x0120
+#define MTXORB_FTDI_RANGE_0121_PID 0x0121
+#define MTXORB_FTDI_RANGE_0122_PID 0x0122
+#define MTXORB_FTDI_RANGE_0123_PID 0x0123
+#define MTXORB_FTDI_RANGE_0124_PID 0x0124
+#define MTXORB_FTDI_RANGE_0125_PID 0x0125
+#define MTXORB_FTDI_RANGE_0126_PID 0x0126
+#define MTXORB_FTDI_RANGE_0127_PID 0x0127
+#define MTXORB_FTDI_RANGE_0128_PID 0x0128
+#define MTXORB_FTDI_RANGE_0129_PID 0x0129
+#define MTXORB_FTDI_RANGE_012A_PID 0x012A
+#define MTXORB_FTDI_RANGE_012B_PID 0x012B
+#define MTXORB_FTDI_RANGE_012C_PID 0x012C
+#define MTXORB_FTDI_RANGE_012D_PID 0x012D
+#define MTXORB_FTDI_RANGE_012E_PID 0x012E
+#define MTXORB_FTDI_RANGE_012F_PID 0x012F
+#define MTXORB_FTDI_RANGE_0130_PID 0x0130
+#define MTXORB_FTDI_RANGE_0131_PID 0x0131
+#define MTXORB_FTDI_RANGE_0132_PID 0x0132
+#define MTXORB_FTDI_RANGE_0133_PID 0x0133
+#define MTXORB_FTDI_RANGE_0134_PID 0x0134
+#define MTXORB_FTDI_RANGE_0135_PID 0x0135
+#define MTXORB_FTDI_RANGE_0136_PID 0x0136
+#define MTXORB_FTDI_RANGE_0137_PID 0x0137
+#define MTXORB_FTDI_RANGE_0138_PID 0x0138
+#define MTXORB_FTDI_RANGE_0139_PID 0x0139
+#define MTXORB_FTDI_RANGE_013A_PID 0x013A
+#define MTXORB_FTDI_RANGE_013B_PID 0x013B
+#define MTXORB_FTDI_RANGE_013C_PID 0x013C
+#define MTXORB_FTDI_RANGE_013D_PID 0x013D
+#define MTXORB_FTDI_RANGE_013E_PID 0x013E
+#define MTXORB_FTDI_RANGE_013F_PID 0x013F
+#define MTXORB_FTDI_RANGE_0140_PID 0x0140
+#define MTXORB_FTDI_RANGE_0141_PID 0x0141
+#define MTXORB_FTDI_RANGE_0142_PID 0x0142
+#define MTXORB_FTDI_RANGE_0143_PID 0x0143
+#define MTXORB_FTDI_RANGE_0144_PID 0x0144
+#define MTXORB_FTDI_RANGE_0145_PID 0x0145
+#define MTXORB_FTDI_RANGE_0146_PID 0x0146
+#define MTXORB_FTDI_RANGE_0147_PID 0x0147
+#define MTXORB_FTDI_RANGE_0148_PID 0x0148
+#define MTXORB_FTDI_RANGE_0149_PID 0x0149
+#define MTXORB_FTDI_RANGE_014A_PID 0x014A
+#define MTXORB_FTDI_RANGE_014B_PID 0x014B
+#define MTXORB_FTDI_RANGE_014C_PID 0x014C
+#define MTXORB_FTDI_RANGE_014D_PID 0x014D
+#define MTXORB_FTDI_RANGE_014E_PID 0x014E
+#define MTXORB_FTDI_RANGE_014F_PID 0x014F
+#define MTXORB_FTDI_RANGE_0150_PID 0x0150
+#define MTXORB_FTDI_RANGE_0151_PID 0x0151
+#define MTXORB_FTDI_RANGE_0152_PID 0x0152
+#define MTXORB_FTDI_RANGE_0153_PID 0x0153
+#define MTXORB_FTDI_RANGE_0154_PID 0x0154
+#define MTXORB_FTDI_RANGE_0155_PID 0x0155
+#define MTXORB_FTDI_RANGE_0156_PID 0x0156
+#define MTXORB_FTDI_RANGE_0157_PID 0x0157
+#define MTXORB_FTDI_RANGE_0158_PID 0x0158
+#define MTXORB_FTDI_RANGE_0159_PID 0x0159
+#define MTXORB_FTDI_RANGE_015A_PID 0x015A
+#define MTXORB_FTDI_RANGE_015B_PID 0x015B
+#define MTXORB_FTDI_RANGE_015C_PID 0x015C
+#define MTXORB_FTDI_RANGE_015D_PID 0x015D
+#define MTXORB_FTDI_RANGE_015E_PID 0x015E
+#define MTXORB_FTDI_RANGE_015F_PID 0x015F
+#define MTXORB_FTDI_RANGE_0160_PID 0x0160
+#define MTXORB_FTDI_RANGE_0161_PID 0x0161
+#define MTXORB_FTDI_RANGE_0162_PID 0x0162
+#define MTXORB_FTDI_RANGE_0163_PID 0x0163
+#define MTXORB_FTDI_RANGE_0164_PID 0x0164
+#define MTXORB_FTDI_RANGE_0165_PID 0x0165
+#define MTXORB_FTDI_RANGE_0166_PID 0x0166
+#define MTXORB_FTDI_RANGE_0167_PID 0x0167
+#define MTXORB_FTDI_RANGE_0168_PID 0x0168
+#define MTXORB_FTDI_RANGE_0169_PID 0x0169
+#define MTXORB_FTDI_RANGE_016A_PID 0x016A
+#define MTXORB_FTDI_RANGE_016B_PID 0x016B
+#define MTXORB_FTDI_RANGE_016C_PID 0x016C
+#define MTXORB_FTDI_RANGE_016D_PID 0x016D
+#define MTXORB_FTDI_RANGE_016E_PID 0x016E
+#define MTXORB_FTDI_RANGE_016F_PID 0x016F
+#define MTXORB_FTDI_RANGE_0170_PID 0x0170
+#define MTXORB_FTDI_RANGE_0171_PID 0x0171
+#define MTXORB_FTDI_RANGE_0172_PID 0x0172
+#define MTXORB_FTDI_RANGE_0173_PID 0x0173
+#define MTXORB_FTDI_RANGE_0174_PID 0x0174
+#define MTXORB_FTDI_RANGE_0175_PID 0x0175
+#define MTXORB_FTDI_RANGE_0176_PID 0x0176
+#define MTXORB_FTDI_RANGE_0177_PID 0x0177
+#define MTXORB_FTDI_RANGE_0178_PID 0x0178
+#define MTXORB_FTDI_RANGE_0179_PID 0x0179
+#define MTXORB_FTDI_RANGE_017A_PID 0x017A
+#define MTXORB_FTDI_RANGE_017B_PID 0x017B
+#define MTXORB_FTDI_RANGE_017C_PID 0x017C
+#define MTXORB_FTDI_RANGE_017D_PID 0x017D
+#define MTXORB_FTDI_RANGE_017E_PID 0x017E
+#define MTXORB_FTDI_RANGE_017F_PID 0x017F
+#define MTXORB_FTDI_RANGE_0180_PID 0x0180
+#define MTXORB_FTDI_RANGE_0181_PID 0x0181
+#define MTXORB_FTDI_RANGE_0182_PID 0x0182
+#define MTXORB_FTDI_RANGE_0183_PID 0x0183
+#define MTXORB_FTDI_RANGE_0184_PID 0x0184
+#define MTXORB_FTDI_RANGE_0185_PID 0x0185
+#define MTXORB_FTDI_RANGE_0186_PID 0x0186
+#define MTXORB_FTDI_RANGE_0187_PID 0x0187
+#define MTXORB_FTDI_RANGE_0188_PID 0x0188
+#define MTXORB_FTDI_RANGE_0189_PID 0x0189
+#define MTXORB_FTDI_RANGE_018A_PID 0x018A
+#define MTXORB_FTDI_RANGE_018B_PID 0x018B
+#define MTXORB_FTDI_RANGE_018C_PID 0x018C
+#define MTXORB_FTDI_RANGE_018D_PID 0x018D
+#define MTXORB_FTDI_RANGE_018E_PID 0x018E
+#define MTXORB_FTDI_RANGE_018F_PID 0x018F
+#define MTXORB_FTDI_RANGE_0190_PID 0x0190
+#define MTXORB_FTDI_RANGE_0191_PID 0x0191
+#define MTXORB_FTDI_RANGE_0192_PID 0x0192
+#define MTXORB_FTDI_RANGE_0193_PID 0x0193
+#define MTXORB_FTDI_RANGE_0194_PID 0x0194
+#define MTXORB_FTDI_RANGE_0195_PID 0x0195
+#define MTXORB_FTDI_RANGE_0196_PID 0x0196
+#define MTXORB_FTDI_RANGE_0197_PID 0x0197
+#define MTXORB_FTDI_RANGE_0198_PID 0x0198
+#define MTXORB_FTDI_RANGE_0199_PID 0x0199
+#define MTXORB_FTDI_RANGE_019A_PID 0x019A
+#define MTXORB_FTDI_RANGE_019B_PID 0x019B
+#define MTXORB_FTDI_RANGE_019C_PID 0x019C
+#define MTXORB_FTDI_RANGE_019D_PID 0x019D
+#define MTXORB_FTDI_RANGE_019E_PID 0x019E
+#define MTXORB_FTDI_RANGE_019F_PID 0x019F
+#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0
+#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1
+#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2
+#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3
+#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4
+#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5
+#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6
+#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7
+#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8
+#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9
+#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA
+#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB
+#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC
+#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD
+#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE
+#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF
+#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0
+#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1
+#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2
+#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3
+#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4
+#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5
+#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6
+#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7
+#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8
+#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9
+#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA
+#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB
+#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC
+#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD
+#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE
+#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF
+#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0
+#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1
+#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2
+#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3
+#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4
+#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5
+#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6
+#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7
+#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8
+#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9
+#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA
+#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB
+#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC
+#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD
+#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE
+#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF
+#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0
+#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1
+#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2
+#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3
+#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4
+#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5
+#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6
+#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7
+#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8
+#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9
+#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA
+#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB
+#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC
+#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD
+#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE
+#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF
+#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0
+#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1
+#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2
+#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3
+#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4
+#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5
+#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6
+#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7
+#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8
+#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9
+#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA
+#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB
+#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC
+#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED
+#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE
+#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF
+#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0
+#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1
+#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2
+#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3
+#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4
+#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5
+#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6
+#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7
+#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8
+#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9
+#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA
+#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB
+#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC
+#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD
+#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE
+#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF
+
+
+
+/*
+ * The Mobility Lab (TML)
+ * Submitted by Pierre Castella
+ */
+#define TML_VID 0x1B91 /* Vendor ID */
+#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */
+
+/* Alti-2 products http://www.alti-2.com */
+#define ALTI2_VID 0x1BC9
+#define ALTI2_N3_PID 0x6001 /* Neptune 3 */
+
+/*
+ * Ionics PlugComputer
+ */
+#define IONICS_VID 0x1c0c
+#define IONICS_PLUGCOMPUTER_PID 0x0102
+
+/*
+ * Dresden Elektronik Sensor Terminal Board
+ */
+#define DE_VID 0x1cf1 /* Vendor ID */
+#define STB_PID 0x0001 /* Sensor Terminal Board */
+#define WHT_PID 0x0004 /* Wireless Handheld Terminal */
+
+/*
+ * STMicroelectonics
+ */
+#define ST_VID 0x0483
+#define ST_STMCLT1030_PID 0x3747 /* ST Micro Connect Lite STMCLT1030 */
+
+/*
+ * Papouch products (http://www.papouch.com/)
+ * Submitted by Folkert van Heusden
+ */
+
+#define PAPOUCH_VID 0x5050 /* Vendor ID */
+#define PAPOUCH_SB485_PID 0x0100 /* Papouch SB485 USB-485/422 Converter */
+#define PAPOUCH_AP485_PID 0x0101 /* AP485 USB-RS485 Converter */
+#define PAPOUCH_SB422_PID 0x0102 /* Papouch SB422 USB-RS422 Converter */
+#define PAPOUCH_SB485_2_PID 0x0103 /* Papouch SB485 USB-485/422 Converter */
+#define PAPOUCH_AP485_2_PID 0x0104 /* AP485 USB-RS485 Converter */
+#define PAPOUCH_SB422_2_PID 0x0105 /* Papouch SB422 USB-RS422 Converter */
+#define PAPOUCH_SB485S_PID 0x0106 /* Papouch SB485S USB-485/422 Converter */
+#define PAPOUCH_SB485C_PID 0x0107 /* Papouch SB485C USB-485/422 Converter */
+#define PAPOUCH_LEC_PID 0x0300 /* LEC USB Converter */
+#define PAPOUCH_SB232_PID 0x0301 /* Papouch SB232 USB-RS232 Converter */
+#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */
+#define PAPOUCH_IRAMP_PID 0x0500 /* Papouch IRAmp Duplex */
+#define PAPOUCH_DRAK5_PID 0x0700 /* Papouch DRAK5 */
+#define PAPOUCH_QUIDO8x8_PID 0x0800 /* Papouch Quido 8/8 Module */
+#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Papouch Quido 4/4 Module */
+#define PAPOUCH_QUIDO2x2_PID 0x0a00 /* Papouch Quido 2/2 Module */
+#define PAPOUCH_QUIDO10x1_PID 0x0b00 /* Papouch Quido 10/1 Module */
+#define PAPOUCH_QUIDO30x3_PID 0x0c00 /* Papouch Quido 30/3 Module */
+#define PAPOUCH_QUIDO60x3_PID 0x0d00 /* Papouch Quido 60(100)/3 Module */
+#define PAPOUCH_QUIDO2x16_PID 0x0e00 /* Papouch Quido 2/16 Module */
+#define PAPOUCH_QUIDO3x32_PID 0x0f00 /* Papouch Quido 3/32 Module */
+#define PAPOUCH_DRAK6_PID 0x1000 /* Papouch DRAK6 */
+#define PAPOUCH_UPSUSB_PID 0x8000 /* Papouch UPS-USB adapter */
+#define PAPOUCH_MU_PID 0x8001 /* MU controller */
+#define PAPOUCH_SIMUKEY_PID 0x8002 /* Papouch SimuKey */
+#define PAPOUCH_AD4USB_PID 0x8003 /* AD4USB Measurement Module */
+#define PAPOUCH_GMUX_PID 0x8004 /* Papouch GOLIATH MUX */
+#define PAPOUCH_GMSR_PID 0x8005 /* Papouch GOLIATH MSR */
+
+/*
+ * Marvell SheevaPlug
+ */
+#define MARVELL_VID 0x9e88
+#define MARVELL_SHEEVAPLUG_PID 0x9e8f
+
+/*
+ * Evolution Robotics products (http://www.evolution.com/).
+ * Submitted by Shawn M. Lavelle.
+ */
+#define EVOLUTION_VID 0xDEEE /* Vendor ID */
+#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */
+#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/
+#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/
+#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */
+
+/*
+ * MJS Gadgets HD Radio / XM Radio / Sirius Radio interfaces (using VID 0x0403)
+ */
+#define MJSG_GENERIC_PID 0x9378
+#define MJSG_SR_RADIO_PID 0x9379
+#define MJSG_XM_RADIO_PID 0x937A
+#define MJSG_HD_RADIO_PID 0x937C
+
+/*
+ * D.O.Tec products (http://www.directout.eu)
+ */
+#define FTDI_DOTEC_PID 0x9868
+
+/*
+ * Xverve Signalyzer tools (http://www.signalyzer.com/)
+ */
+#define XVERVE_SIGNALYZER_ST_PID 0xBCA0
+#define XVERVE_SIGNALYZER_SLITE_PID 0xBCA1
+#define XVERVE_SIGNALYZER_SH2_PID 0xBCA2
+#define XVERVE_SIGNALYZER_SH4_PID 0xBCA4
+
+/*
+ * Segway Robotic Mobility Platform USB interface (using VID 0x0403)
+ * Submitted by John G. Rogers
+ */
+#define SEGWAY_RMP200_PID 0xe729
+
+
+/*
+ * Accesio USB Data Acquisition products (http://www.accesio.com/)
+ */
+#define ACCESIO_COM4SM_PID 0xD578
+
+/* www.sciencescope.co.uk educational dataloggers */
+#define FTDI_SCIENCESCOPE_LOGBOOKML_PID 0xFF18
+#define FTDI_SCIENCESCOPE_LS_LOGBOOK_PID 0xFF1C
+#define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID 0xFF1D
+
+/*
+ * Milkymist One JTAG/Serial
+ */
+#define QIHARDWARE_VID 0x20B7
+#define MILKYMISTONE_JTAGSERIAL_PID 0x0713
+
+/*
+ * CTI GmbH RS485 Converter http://www.cti-lean.com/
+ */
+/* USB-485-Mini*/
+#define FTDI_CTI_MINI_PID 0xF608
+/* USB-Nano-485*/
+#define FTDI_CTI_NANO_PID 0xF60B
+
+/*
+ * ZeitControl cardsystems GmbH rfid-readers http://zeitconrol.de
+ */
+/* TagTracer MIFARE*/
+#define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0
+
+/*
+ * Rainforest Automation
+ */
+/* ZigBee controller */
+#define FTDI_RF_R106 0x8A28
+
+/*
+ * Product: HCP HIT GPRS modem
+ * Manufacturer: HCP d.o.o.
+ * ATI command output: Cinterion MC55i
+ */
+#define FTDI_CINTERION_MC55I_PID 0xA951
diff --git a/hw/usb/quirks-pl2303-ids.h b/hw/usb/quirks-pl2303-ids.h
new file mode 100644
index 0000000000..8dbdb46ffe
--- /dev/null
+++ b/hw/usb/quirks-pl2303-ids.h
@@ -0,0 +1,150 @@
+/*
+ * Prolific PL2303 USB to serial adaptor driver header file
+ *
+ * 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.
+ *
+ */
+
+#define BENQ_VENDOR_ID 0x04a5
+#define BENQ_PRODUCT_ID_S81 0x4027
+
+#define PL2303_VENDOR_ID 0x067b
+#define PL2303_PRODUCT_ID 0x2303
+#define PL2303_PRODUCT_ID_RSAQ2 0x04bb
+#define PL2303_PRODUCT_ID_DCU11 0x1234
+#define PL2303_PRODUCT_ID_PHAROS 0xaaa0
+#define PL2303_PRODUCT_ID_RSAQ3 0xaaa2
+#define PL2303_PRODUCT_ID_ALDIGA 0x0611
+#define PL2303_PRODUCT_ID_MMX 0x0612
+#define PL2303_PRODUCT_ID_GPRS 0x0609
+#define PL2303_PRODUCT_ID_HCR331 0x331a
+#define PL2303_PRODUCT_ID_MOTOROLA 0x0307
+
+#define ATEN_VENDOR_ID 0x0557
+#define ATEN_VENDOR_ID2 0x0547
+#define ATEN_PRODUCT_ID 0x2008
+
+#define IODATA_VENDOR_ID 0x04bb
+#define IODATA_PRODUCT_ID 0x0a03
+#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e
+
+#define ELCOM_VENDOR_ID 0x056e
+#define ELCOM_PRODUCT_ID 0x5003
+#define ELCOM_PRODUCT_ID_UCSGT 0x5004
+
+#define ITEGNO_VENDOR_ID 0x0eba
+#define ITEGNO_PRODUCT_ID 0x1080
+#define ITEGNO_PRODUCT_ID_2080 0x2080
+
+#define MA620_VENDOR_ID 0x0df7
+#define MA620_PRODUCT_ID 0x0620
+
+#define RATOC_VENDOR_ID 0x0584
+#define RATOC_PRODUCT_ID 0xb000
+
+#define TRIPP_VENDOR_ID 0x2478
+#define TRIPP_PRODUCT_ID 0x2008
+
+#define RADIOSHACK_VENDOR_ID 0x1453
+#define RADIOSHACK_PRODUCT_ID 0x4026
+
+#define DCU10_VENDOR_ID 0x0731
+#define DCU10_PRODUCT_ID 0x0528
+
+#define SITECOM_VENDOR_ID 0x6189
+#define SITECOM_PRODUCT_ID 0x2068
+
+/* Alcatel OT535/735 USB cable */
+#define ALCATEL_VENDOR_ID 0x11f7
+#define ALCATEL_PRODUCT_ID 0x02df
+
+/* Samsung I330 phone cradle */
+#define SAMSUNG_VENDOR_ID 0x04e8
+#define SAMSUNG_PRODUCT_ID 0x8001
+
+#define SIEMENS_VENDOR_ID 0x11f5
+#define SIEMENS_PRODUCT_ID_SX1 0x0001
+#define SIEMENS_PRODUCT_ID_X65 0x0003
+#define SIEMENS_PRODUCT_ID_X75 0x0004
+#define SIEMENS_PRODUCT_ID_EF81 0x0005
+
+#define SYNTECH_VENDOR_ID 0x0745
+#define SYNTECH_PRODUCT_ID 0x0001
+
+/* Nokia CA-42 Cable */
+#define NOKIA_CA42_VENDOR_ID 0x078b
+#define NOKIA_CA42_PRODUCT_ID 0x1234
+
+/* CA-42 CLONE Cable www.ca-42.com chipset: Prolific Technology Inc */
+#define CA_42_CA42_VENDOR_ID 0x10b5
+#define CA_42_CA42_PRODUCT_ID 0xac70
+
+#define SAGEM_VENDOR_ID 0x079b
+#define SAGEM_PRODUCT_ID 0x0027
+
+/* Leadtek GPS 9531 (ID 0413:2101) */
+#define LEADTEK_VENDOR_ID 0x0413
+#define LEADTEK_9531_PRODUCT_ID 0x2101
+
+/* USB GSM cable from Speed Dragon Multimedia, Ltd */
+#define SPEEDDRAGON_VENDOR_ID 0x0e55
+#define SPEEDDRAGON_PRODUCT_ID 0x110b
+
+/* DATAPILOT Universal-2 Phone Cable */
+#define DATAPILOT_U2_VENDOR_ID 0x0731
+#define DATAPILOT_U2_PRODUCT_ID 0x2003
+
+/* Belkin "F5U257" Serial Adapter */
+#define BELKIN_VENDOR_ID 0x050d
+#define BELKIN_PRODUCT_ID 0x0257
+
+/* Alcor Micro Corp. USB 2.0 TO RS-232 */
+#define ALCOR_VENDOR_ID 0x058F
+#define ALCOR_PRODUCT_ID 0x9720
+
+/* Willcom WS002IN Data Driver (by NetIndex Inc.) */
+#define WS002IN_VENDOR_ID 0x11f6
+#define WS002IN_PRODUCT_ID 0x2001
+
+/* Corega CG-USBRS232R Serial Adapter */
+#define COREGA_VENDOR_ID 0x07aa
+#define COREGA_PRODUCT_ID 0x002a
+
+/* Y.C. Cable U.S.A., Inc - USB to RS-232 */
+#define YCCABLE_VENDOR_ID 0x05ad
+#define YCCABLE_PRODUCT_ID 0x0fba
+
+/* "Superial" USB - Serial */
+#define SUPERIAL_VENDOR_ID 0x5372
+#define SUPERIAL_PRODUCT_ID 0x2303
+
+/* Hewlett-Packard LD220-HP POS Pole Display */
+#define HP_VENDOR_ID 0x03f0
+#define HP_LD220_PRODUCT_ID 0x3524
+
+/* Cressi Edy (diving computer) PC interface */
+#define CRESSI_VENDOR_ID 0x04b8
+#define CRESSI_EDY_PRODUCT_ID 0x0521
+
+/* Zeagle dive computer interface */
+#define ZEAGLE_VENDOR_ID 0x04b8
+#define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522
+
+/* Sony, USB data cable for CMD-Jxx mobile phones */
+#define SONY_VENDOR_ID 0x054c
+#define SONY_QN3USB_PRODUCT_ID 0x0437
+
+/* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
+#define SANWA_VENDOR_ID 0x11ad
+#define SANWA_PRODUCT_ID 0x0001
+
+/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
+#define ADLINK_VENDOR_ID 0x0b63
+#define ADLINK_ND6530_PRODUCT_ID 0x6530
+
+/* SMART USB Serial Adapter */
+#define SMART_VENDOR_ID 0x0b8c
+#define SMART_PRODUCT_ID 0x2303
diff --git a/hw/usb/quirks.c b/hw/usb/quirks.c
new file mode 100644
index 0000000000..a761a96032
--- /dev/null
+++ b/hw/usb/quirks.c
@@ -0,0 +1,53 @@
+/*
+ * USB quirk handling
+ *
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * Red Hat Authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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.
+ */
+
+#include "quirks.h"
+#include "hw/usb.h"
+
+static bool usb_id_match(const struct usb_device_id *ids,
+ uint16_t vendor_id, uint16_t product_id,
+ uint8_t interface_class, uint8_t interface_subclass,
+ uint8_t interface_protocol) {
+ int i;
+
+ for (i = 0; ids[i].vendor_id != -1; i++) {
+ if (ids[i].vendor_id == vendor_id &&
+ ids[i].product_id == product_id &&
+ (ids[i].interface_class == -1 ||
+ (ids[i].interface_class == interface_class &&
+ ids[i].interface_subclass == interface_subclass &&
+ ids[i].interface_protocol == interface_protocol))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+int usb_get_quirks(uint16_t vendor_id, uint16_t product_id,
+ uint8_t interface_class, uint8_t interface_subclass,
+ uint8_t interface_protocol)
+{
+ int quirks = 0;
+
+ if (usb_id_match(usbredir_raw_serial_ids, vendor_id, product_id,
+ interface_class, interface_subclass, interface_protocol)) {
+ quirks |= USB_QUIRK_BUFFER_BULK_IN;
+ }
+ if (usb_id_match(usbredir_ftdi_serial_ids, vendor_id, product_id,
+ interface_class, interface_subclass, interface_protocol)) {
+ quirks |= USB_QUIRK_BUFFER_BULK_IN | USB_QUIRK_IS_FTDI;
+ }
+
+ return quirks;
+}
diff --git a/hw/usb/quirks.h b/hw/usb/quirks.h
new file mode 100644
index 0000000000..8dc6065527
--- /dev/null
+++ b/hw/usb/quirks.h
@@ -0,0 +1,910 @@
+/*
+ * USB quirk handling
+ *
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * Red Hat Authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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.
+ */
+
+/* 1 on 1 copy of linux/drivers/usb/serial/ftdi_sio_ids.h */
+#include "quirks-ftdi-ids.h"
+/* 1 on 1 copy of linux/drivers/usb/serial/pl2303.h */
+#include "quirks-pl2303-ids.h"
+
+struct usb_device_id {
+ int vendor_id;
+ int product_id;
+ int interface_class;
+ int interface_subclass;
+ int interface_protocol;
+};
+
+#define USB_DEVICE(vendor, product) \
+ .vendor_id = vendor, .product_id = product, .interface_class = -1,
+
+#define USB_DEVICE_AND_INTERFACE_INFO(vend, prod, iclass, isubclass, iproto) \
+ .vendor_id = vend, .product_id = prod, .interface_class = iclass, \
+ .interface_subclass = isubclass, .interface_protocol = iproto
+
+static const struct usb_device_id usbredir_raw_serial_ids[] = {
+ /*
+ * Silicon Laboratories CP210x USB to RS232 serial adapter ids
+ * copied from linux/drivers/usb/serial/cp210x.c
+ *
+ * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk)
+ */
+ { USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */
+ { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
+ { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
+ { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
+ { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
+ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
+ { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
+ { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */
+ { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */
+ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
+ { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */
+ { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */
+ { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
+ { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
+ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
+ { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */
+ { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */
+ { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */
+ { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
+ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
+ { USB_DEVICE(0x10C4, 0x8044) }, /* Cygnal Debug Adapter */
+ { USB_DEVICE(0x10C4, 0x804E) }, /* Software Bisque Paramount ME build-in converter */
+ { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
+ { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */
+ { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
+ { USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */
+ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
+ { USB_DEVICE(0x10C4, 0x80C4) }, /* Cygnal Integrated Products, Inc., Optris infrared thermometer */
+ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
+ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */
+ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
+ { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
+ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
+ { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
+ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
+ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
+ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
+ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+ { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
+ { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
+ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
+ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
+ { USB_DEVICE(0x10C4, 0x81A9) }, /* Multiplex RC Interface */
+ { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
+ { USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
+ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
+ { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
+ { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
+ { USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */
+ { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */
+ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
+ { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
+ { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
+ { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
+ { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
+ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
+ { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
+ { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
+ { USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */
+ { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
+ { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */
+ { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
+ { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
+ { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */
+ { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
+ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
+ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
+ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
+ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
+ { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
+ { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
+ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
+ { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
+ { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
+ { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
+ { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
+ { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */
+ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
+ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */
+ { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */
+ { USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */
+ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
+ { USB_DEVICE(0x166A, 0x0304) }, /* Clipsal 5000CT2 C-Bus Black and White Touchscreen */
+ { USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */
+ { USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */
+ { USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */
+ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
+ { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */
+ { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
+ { USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */
+ { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
+ { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
+ { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
+ { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
+ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
+ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
+ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
+ { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
+ { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
+ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
+ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
+ { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
+ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
+
+ /*
+ * Prolific pl2303 USB to RS232 serial adapter ids
+ * copied from linux/drivers/usb/serial/pl2303.c
+ *
+ * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2003 IBM Corp.
+ */
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) },
+ { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
+ { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
+ { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
+ { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
+ { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
+ { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) },
+ { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
+ { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },
+ { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
+ { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
+ { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
+ { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) },
+ { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) },
+ { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) },
+ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) },
+ { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) },
+ { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) },
+ { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
+ { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },
+ { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) },
+ { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_ID_S81) }, /* Benq/Siemens S81 */
+ { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
+ { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) },
+ { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) },
+ { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) },
+ { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) },
+ { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
+ { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
+ { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
+ { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
+ { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
+ { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
+ { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
+ { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+ { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
+ { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
+ { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
+ { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
+ { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
+
+ { USB_DEVICE(-1, -1) } /* Terminating Entry */
+};
+
+static const struct usb_device_id usbredir_ftdi_serial_ids[] = {
+ /*
+ * FTDI USB to RS232 serial adapter ids
+ * copied from linux/drivers/usb/serial/ftdi_sio.c
+ *
+ * Copyright (C) 2009 - 2010
+ * Johan Hovold (jhovold@gmail.com)
+ * Copyright (C) 1999 - 2001
+ * Greg Kroah-Hartman (greg@kroah.com)
+ * Bill Ryder (bryder@sgi.com)
+ * Copyright (C) 2002
+ * Kuba Ober (kuba@mareimbrium.org)
+ */
+ { USB_DEVICE(FTDI_VID, FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_3_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_4_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_5_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_6_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_7_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_USINT_CAT_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_USINT_WKEY_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_USINT_RS232_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IPLUS2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) },
+ { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_232H_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_FTX_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_SNIFFER_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) },
+ { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
+ { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
+ { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_XF_633_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_XF_631_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_XF_635_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_URBAN_0_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_URBAN_1_PID) },
+ { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_3_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
+ { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0103_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0104_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0105_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0106_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0107_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0108_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0109_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0110_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0111_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0112_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0113_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0114_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0115_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0116_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0117_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0118_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0119_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0120_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0121_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0122_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0123_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0124_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0125_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0126_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0127_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0128_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0129_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0130_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0131_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0132_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0133_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0134_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0135_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0136_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0137_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0138_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0139_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0140_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0141_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0142_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0143_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0144_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0145_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0146_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0147_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0148_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0149_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0150_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0151_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0152_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0153_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0154_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0155_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0156_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0157_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0158_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0159_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0160_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0161_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0162_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0163_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0164_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0165_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0166_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0167_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0168_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0169_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0170_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0171_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0172_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0173_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0174_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0175_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0176_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0177_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0178_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0179_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0180_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0181_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0182_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0183_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0184_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0185_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0186_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0187_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0188_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0189_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0190_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0191_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0192_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0193_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0194_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0195_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0196_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0197_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0198_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0199_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01ED_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_USBX_707_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2104_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2106_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2203_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2203_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_3_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_4_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_3_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_4_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_3_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_4_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_3_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_4_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_5_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_6_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_7_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_8_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_3_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_4_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_5_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_6_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_7_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_8_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_3_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_4_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_5_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_6_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_7_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_1_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_2_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_3_PID) },
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_4_PID) },
+ { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) },
+ { USB_DEVICE(OCT_VID, OCT_US101_PID) },
+ { USB_DEVICE(OCT_VID, OCT_DK201_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
+ { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) },
+ { USB_DEVICE(FTDI_VID, PROTEGO_R2X0) },
+ { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) },
+ { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E808_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E809_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80A_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80B_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80C_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80D_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80E_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80F_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E888_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E889_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88A_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88B_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88C_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88D_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88E_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_US485_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_PICPRO_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_PCMCIA_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_PK1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_RS232MON_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_APP70_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID) },
+ /*
+ * ELV devices:
+ */
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS550_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_EC3000_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS888_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_TWS550_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_FEM_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UTP8_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS444PC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UMS100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) },
+ { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
+ { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
+ { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
+ { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
+ { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) },
+ { USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
+ { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) },
+ { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USOPTL4_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USPTL4_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_2_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR2_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_485USB9F_2W_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_485USB9F_4W_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_232USB9M_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_485USBTB_2W_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_485USBTB_4W_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_TTL5USB9M_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_TTL3USB9M_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_ZZ_PROG1_USB_PID) },
+ { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
+ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_3_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_1_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_2_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_3_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_4_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) },
+ { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MHAM_YS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MHAM_IC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MHAM_DB9_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MHAM_RS232_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y9_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) },
+ { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
+ { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
+ { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16IC_PID) },
+ { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
+ { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
+ { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ECLO_COM_1WIRE_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C2_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP2D_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VT_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VR_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVT_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVR_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVT_PID) },
+ { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVR_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
+ { USB_DEVICE(TESTO_VID, TESTO_USB_INTERFACE_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GAMMA_SCOUT_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
+ { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID) },
+ { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
+ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
+ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
+ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
+ { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
+ { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID) },
+ { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID) },
+ { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID) },
+ { USB_DEVICE(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID) },
+ { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID) },
+ { USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID) },
+ { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
+ { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
+
+ /* Papouch devices based on FTDI chip */
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_2_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_2_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_2_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485S_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485C_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_LEC_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB232_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_IRAMP_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK5_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO8x8_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x2_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO10x1_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO30x3_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO60x3_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x16_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO3x32_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK6_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_UPSUSB_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_MU_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SIMUKEY_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AD4USB_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMUX_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMSR_PID) },
+
+ { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
+ { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
+ { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
+ { USB_DEVICE(ATMEL_VID, STK541_PID) },
+ { USB_DEVICE(DE_VID, STB_PID) },
+ { USB_DEVICE(DE_VID, WHT_PID) },
+ { USB_DEVICE(ADI_VID, ADI_GNICE_PID) },
+ { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID) },
+ { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID,
+ 0xff, 0xff, 0x00) },
+ { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
+ { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID) },
+ { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },
+ { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) },
+ { USB_DEVICE(FTDI_VID, PI_C865_PID) },
+ { USB_DEVICE(FTDI_VID, PI_C857_PID) },
+ { USB_DEVICE(PI_VID, PI_C866_PID) },
+ { USB_DEVICE(PI_VID, PI_C663_PID) },
+ { USB_DEVICE(PI_VID, PI_C725_PID) },
+ { USB_DEVICE(PI_VID, PI_E517_PID) },
+ { USB_DEVICE(PI_VID, PI_C863_PID) },
+ { USB_DEVICE(PI_VID, PI_E861_PID) },
+ { USB_DEVICE(PI_VID, PI_C867_PID) },
+ { USB_DEVICE(PI_VID, PI_E609_PID) },
+ { USB_DEVICE(PI_VID, PI_E709_PID) },
+ { USB_DEVICE(PI_VID, PI_100F_PID) },
+ { USB_DEVICE(PI_VID, PI_1011_PID) },
+ { USB_DEVICE(PI_VID, PI_1012_PID) },
+ { USB_DEVICE(PI_VID, PI_1013_PID) },
+ { USB_DEVICE(PI_VID, PI_1014_PID) },
+ { USB_DEVICE(PI_VID, PI_1015_PID) },
+ { USB_DEVICE(PI_VID, PI_1016_PID) },
+ { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) },
+ { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
+ { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID) },
+ { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID) },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) },
+ { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) },
+ { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) },
+ { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) },
+ { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) },
+ { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_ST_PID) },
+ { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID) },
+ { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID) },
+ { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID) },
+ { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) },
+ { USB_DEVICE(FTDI_VID, ACCESIO_COM4SM_PID) },
+ { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_PC_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_USB_DMX_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MIDI_TIMECODE_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MINI_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MAXI_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MEDIA_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
+ { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID) },
+ { USB_DEVICE(ST_VID, ST_STMCLT1030_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
+ { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) },
+
+ { USB_DEVICE(-1, -1) } /* Terminating Entry */
+};
+
+#undef USB_DEVICE
+#undef USB_DEVICE_AND_INTERFACE_INFO
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 0abe1ff4d1..8c0ead07c5 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -44,18 +44,26 @@
#define NO_INTERFACE_INFO 255 /* Valid interface_count always <= 32 */
#define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
+#define USBEP2I(usb_ep) (((usb_ep)->pid == USB_TOKEN_IN) ? \
+ ((usb_ep)->nr | 0x10) : ((usb_ep)->nr))
+#define I2USBEP(d, i) (usb_ep_get(&(d)->dev, \
+ ((i) & 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT, \
+ (i) & 0x0f))
typedef struct USBRedirDevice USBRedirDevice;
-/* Struct to hold buffered packets (iso or int input packets) */
+/* Struct to hold buffered packets */
struct buf_packet {
uint8_t *data;
- int len;
- int status;
+ void *free_on_destroy;
+ uint16_t len;
+ uint16_t offset;
+ uint8_t status;
QTAILQ_ENTRY(buf_packet)next;
};
struct endp_data {
+ USBRedirDevice *dev;
uint8_t type;
uint8_t interval;
uint8_t interface; /* bInterfaceNumber this ep belongs to */
@@ -64,11 +72,14 @@ struct endp_data {
uint8_t iso_error; /* For reporting iso errors to the HC */
uint8_t interrupt_started;
uint8_t interrupt_error;
+ uint8_t bulk_receiving_enabled;
+ uint8_t bulk_receiving_started;
uint8_t bufpq_prefilled;
uint8_t bufpq_dropping_packets;
QTAILQ_HEAD(, buf_packet) bufpq;
int32_t bufpq_size;
int32_t bufpq_target_size;
+ USBPacket *pending_async_packet;
};
struct PacketIdQueueEntry {
@@ -102,6 +113,7 @@ struct USBRedirDevice {
struct endp_data endpoint[MAX_ENDPOINTS];
struct PacketIdQueue cancelled;
struct PacketIdQueue already_in_flight;
+ void (*buffered_bulk_in_complete)(USBRedirDevice *, USBPacket *, uint8_t);
/* Data for device filtering */
struct usb_redir_device_connect_header device_info;
struct usb_redir_interface_info_header interface_info;
@@ -129,6 +141,8 @@ static void usbredir_interrupt_receiving_status(void *priv, uint64_t id,
*interrupt_receiving_status);
static void usbredir_bulk_streams_status(void *priv, uint64_t id,
struct usb_redir_bulk_streams_status_header *bulk_streams_status);
+static void usbredir_bulk_receiving_status(void *priv, uint64_t id,
+ struct usb_redir_bulk_receiving_status_header *bulk_receiving_status);
static void usbredir_control_packet(void *priv, uint64_t id,
struct usb_redir_control_packet_header *control_packet,
uint8_t *data, int data_len);
@@ -141,6 +155,9 @@ static void usbredir_iso_packet(void *priv, uint64_t id,
static void usbredir_interrupt_packet(void *priv, uint64_t id,
struct usb_redir_interrupt_packet_header *interrupt_header,
uint8_t *data, int data_len);
+static void usbredir_buffered_bulk_packet(void *priv, uint64_t id,
+ struct usb_redir_buffered_bulk_packet_header *buffered_bulk_packet,
+ uint8_t *data, int data_len);
static void usbredir_handle_status(USBRedirDevice *dev, USBPacket *p,
int status);
@@ -314,12 +331,19 @@ static void packet_id_queue_empty(struct PacketIdQueue *q)
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
{
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+ int i = USBEP2I(p->ep);
if (p->combined) {
usb_combined_packet_cancel(udev, p);
return;
}
+ if (dev->endpoint[i].pending_async_packet) {
+ assert(dev->endpoint[i].pending_async_packet == p);
+ dev->endpoint[i].pending_async_packet = NULL;
+ return;
+ }
+
packet_id_queue_add(&dev->cancelled, p->id);
usbredirparser_send_cancel_data_packet(dev->parser, p->id);
usbredirparser_do_write(dev->parser);
@@ -338,6 +362,11 @@ static void usbredir_fill_already_in_flight_from_ep(USBRedirDevice *dev,
{
static USBPacket *p;
+ /* async handled packets for bulk receiving eps do not count as inflight */
+ if (dev->endpoint[USBEP2I(ep)].bulk_receiving_started) {
+ return;
+ }
+
QTAILQ_FOREACH(p, &ep->queue, queue) {
/* Skip combined packets, except for the first */
if (p->combined && p != p->combined->first) {
@@ -385,8 +414,8 @@ static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
return p;
}
-static void bufp_alloc(USBRedirDevice *dev,
- uint8_t *data, int len, int status, uint8_t ep)
+static void bufp_alloc(USBRedirDevice *dev, uint8_t *data, uint16_t len,
+ uint8_t status, uint8_t ep, void *free_on_destroy)
{
struct buf_packet *bufp;
@@ -410,7 +439,9 @@ static void bufp_alloc(USBRedirDevice *dev,
bufp = g_malloc(sizeof(struct buf_packet));
bufp->data = data;
bufp->len = len;
+ bufp->offset = 0;
bufp->status = status;
+ bufp->free_on_destroy = free_on_destroy;
QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
dev->endpoint[EP2I(ep)].bufpq_size++;
}
@@ -420,7 +451,7 @@ static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
{
QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
dev->endpoint[EP2I(ep)].bufpq_size--;
- free(bufp->data);
+ free(bufp->free_on_destroy);
g_free(bufp);
}
@@ -571,19 +602,162 @@ static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
usbredir_free_bufpq(dev, ep);
}
+/*
+ * The usb-host may poll the endpoint faster then our guest, resulting in lots
+ * of smaller bulkp-s. The below buffered_bulk_in_complete* functions combine
+ * data from multiple bulkp-s into a single packet, avoiding bufpq overflows.
+ */
+static void usbredir_buffered_bulk_add_data_to_packet(USBRedirDevice *dev,
+ struct buf_packet *bulkp, int count, USBPacket *p, uint8_t ep)
+{
+ usb_packet_copy(p, bulkp->data + bulkp->offset, count);
+ bulkp->offset += count;
+ if (bulkp->offset == bulkp->len) {
+ /* Store status in the last packet with data from this bulkp */
+ usbredir_handle_status(dev, p, bulkp->status);
+ bufp_free(dev, bulkp, ep);
+ }
+}
+
+static void usbredir_buffered_bulk_in_complete_raw(USBRedirDevice *dev,
+ USBPacket *p, uint8_t ep)
+{
+ struct buf_packet *bulkp;
+ int count;
+
+ while ((bulkp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq)) &&
+ p->actual_length < p->iov.size && p->status == USB_RET_SUCCESS) {
+ count = bulkp->len - bulkp->offset;
+ if (count > (p->iov.size - p->actual_length)) {
+ count = p->iov.size - p->actual_length;
+ }
+ usbredir_buffered_bulk_add_data_to_packet(dev, bulkp, count, p, ep);
+ }
+}
+
+static void usbredir_buffered_bulk_in_complete_ftdi(USBRedirDevice *dev,
+ USBPacket *p, uint8_t ep)
+{
+ const int maxp = dev->endpoint[EP2I(ep)].max_packet_size;
+ uint8_t header[2] = { 0, 0 };
+ struct buf_packet *bulkp;
+ int count;
+
+ while ((bulkp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq)) &&
+ p->actual_length < p->iov.size && p->status == USB_RET_SUCCESS) {
+ if (bulkp->len < 2) {
+ WARNING("malformed ftdi bulk in packet\n");
+ bufp_free(dev, bulkp, ep);
+ continue;
+ }
+
+ if ((p->actual_length % maxp) == 0) {
+ usb_packet_copy(p, bulkp->data, 2);
+ memcpy(header, bulkp->data, 2);
+ } else {
+ if (bulkp->data[0] != header[0] || bulkp->data[1] != header[1]) {
+ break; /* Different header, add to next packet */
+ }
+ }
+
+ if (bulkp->offset == 0) {
+ bulkp->offset = 2; /* Skip header */
+ }
+ count = bulkp->len - bulkp->offset;
+ /* Must repeat the header at maxp interval */
+ if (count > (maxp - (p->actual_length % maxp))) {
+ count = maxp - (p->actual_length % maxp);
+ }
+ usbredir_buffered_bulk_add_data_to_packet(dev, bulkp, count, p, ep);
+ }
+}
+
+static void usbredir_buffered_bulk_in_complete(USBRedirDevice *dev,
+ USBPacket *p, uint8_t ep)
+{
+ p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
+ dev->buffered_bulk_in_complete(dev, p, ep);
+ DPRINTF("bulk-token-in ep %02X status %d len %d id %"PRIu64"\n",
+ ep, p->status, p->actual_length, p->id);
+}
+
+static void usbredir_handle_buffered_bulk_in_data(USBRedirDevice *dev,
+ USBPacket *p, uint8_t ep)
+{
+ /* Input bulk endpoint, buffered packet input */
+ if (!dev->endpoint[EP2I(ep)].bulk_receiving_started) {
+ int bpt;
+ struct usb_redir_start_bulk_receiving_header start = {
+ .endpoint = ep,
+ .stream_id = 0,
+ .no_transfers = 5,
+ };
+ /* Round bytes_per_transfer up to a multiple of max_packet_size */
+ bpt = 512 + dev->endpoint[EP2I(ep)].max_packet_size - 1;
+ bpt /= dev->endpoint[EP2I(ep)].max_packet_size;
+ bpt *= dev->endpoint[EP2I(ep)].max_packet_size;
+ start.bytes_per_transfer = bpt;
+ /* No id, we look at the ep when receiving a status back */
+ usbredirparser_send_start_bulk_receiving(dev->parser, 0, &start);
+ usbredirparser_do_write(dev->parser);
+ DPRINTF("bulk receiving started bytes/transfer %u count %d ep %02X\n",
+ start.bytes_per_transfer, start.no_transfers, ep);
+ dev->endpoint[EP2I(ep)].bulk_receiving_started = 1;
+ /* We don't really want to drop bulk packets ever, but
+ having some upper limit to how much we buffer is good. */
+ dev->endpoint[EP2I(ep)].bufpq_target_size = 5000;
+ dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
+ }
+
+ if (QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq)) {
+ DPRINTF("bulk-token-in ep %02X, no bulkp\n", ep);
+ assert(dev->endpoint[EP2I(ep)].pending_async_packet == NULL);
+ dev->endpoint[EP2I(ep)].pending_async_packet = p;
+ p->status = USB_RET_ASYNC;
+ return;
+ }
+ usbredir_buffered_bulk_in_complete(dev, p, ep);
+}
+
+static void usbredir_stop_bulk_receiving(USBRedirDevice *dev, uint8_t ep)
+{
+ struct usb_redir_stop_bulk_receiving_header stop_bulk = {
+ .endpoint = ep,
+ .stream_id = 0,
+ };
+ if (dev->endpoint[EP2I(ep)].bulk_receiving_started) {
+ usbredirparser_send_stop_bulk_receiving(dev->parser, 0, &stop_bulk);
+ DPRINTF("bulk receiving stopped ep %02X\n", ep);
+ dev->endpoint[EP2I(ep)].bulk_receiving_started = 0;
+ }
+ usbredir_free_bufpq(dev, ep);
+}
+
static void usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
uint8_t ep)
{
struct usb_redir_bulk_packet_header bulk_packet;
size_t size = (p->combined) ? p->combined->iov.size : p->iov.size;
-
- DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, size, p->id);
+ const int maxp = dev->endpoint[EP2I(ep)].max_packet_size;
if (usbredir_already_in_flight(dev, p->id)) {
p->status = USB_RET_ASYNC;
return;
}
+ if (dev->endpoint[EP2I(ep)].bulk_receiving_enabled) {
+ if (size != 0 && (size % maxp) == 0) {
+ usbredir_handle_buffered_bulk_in_data(dev, p, ep);
+ return;
+ }
+ WARNING("bulk recv invalid size %zd ep %02x, disabling\n", size, ep);
+ assert(dev->endpoint[EP2I(ep)].pending_async_packet == NULL);
+ usbredir_stop_bulk_receiving(dev, ep);
+ dev->endpoint[EP2I(ep)].bulk_receiving_enabled = 0;
+ }
+
+ DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, size, p->id);
+
bulk_packet.endpoint = ep;
bulk_packet.length = size;
bulk_packet.stream_id = 0;
@@ -720,9 +894,6 @@ static void usbredir_handle_data(USBDevice *udev, USBPacket *p)
ERROR("handle_data called for control transfer on ep %02X\n", ep);
p->status = USB_RET_NAK;
break;
- case USB_ENDPOINT_XFER_ISOC:
- usbredir_handle_iso_data(dev, p, ep);
- break;
case USB_ENDPOINT_XFER_BULK:
if (p->state == USB_PACKET_SETUP && p->pid == USB_TOKEN_IN &&
p->ep->pipeline) {
@@ -731,6 +902,9 @@ static void usbredir_handle_data(USBDevice *udev, USBPacket *p)
}
usbredir_handle_bulk_data(dev, p, ep);
break;
+ case USB_ENDPOINT_XFER_ISOC:
+ usbredir_handle_iso_data(dev, p, ep);
+ break;
case USB_ENDPOINT_XFER_INT:
if (ep & USB_DIR_IN) {
usbredir_handle_interrupt_in_data(dev, p, ep);
@@ -752,6 +926,36 @@ static void usbredir_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
}
}
+static void usbredir_stop_ep(USBRedirDevice *dev, int i)
+{
+ uint8_t ep = I2EP(i);
+
+ switch (dev->endpoint[i].type) {
+ case USB_ENDPOINT_XFER_BULK:
+ if (ep & USB_DIR_IN) {
+ usbredir_stop_bulk_receiving(dev, ep);
+ }
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ usbredir_stop_iso_stream(dev, ep);
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ if (ep & USB_DIR_IN) {
+ usbredir_stop_interrupt_receiving(dev, ep);
+ }
+ break;
+ }
+ usbredir_free_bufpq(dev, ep);
+}
+
+static void usbredir_ep_stopped(USBDevice *udev, USBEndpoint *uep)
+{
+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+
+ usbredir_stop_ep(dev, USBEP2I(uep));
+ usbredirparser_do_write(dev->parser);
+}
+
static void usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
int config)
{
@@ -761,17 +965,7 @@ static void usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
DPRINTF("set config %d id %"PRIu64"\n", config, p->id);
for (i = 0; i < MAX_ENDPOINTS; i++) {
- switch (dev->endpoint[i].type) {
- case USB_ENDPOINT_XFER_ISOC:
- usbredir_stop_iso_stream(dev, I2EP(i));
- break;
- case USB_ENDPOINT_XFER_INT:
- if (i & 0x10) {
- usbredir_stop_interrupt_receiving(dev, I2EP(i));
- }
- break;
- }
- usbredir_free_bufpq(dev, I2EP(i));
+ usbredir_stop_ep(dev, i);
}
set_config.configuration = config;
@@ -799,17 +993,7 @@ static void usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
for (i = 0; i < MAX_ENDPOINTS; i++) {
if (dev->endpoint[i].interface == interface) {
- switch (dev->endpoint[i].type) {
- case USB_ENDPOINT_XFER_ISOC:
- usbredir_stop_iso_stream(dev, I2EP(i));
- break;
- case USB_ENDPOINT_XFER_INT:
- if (i & 0x10) {
- usbredir_stop_interrupt_receiving(dev, I2EP(i));
- }
- break;
- }
- usbredir_free_bufpq(dev, I2EP(i));
+ usbredir_stop_ep(dev, i);
}
}
@@ -931,10 +1115,12 @@ static void usbredir_create_parser(USBRedirDevice *dev)
dev->parser->interrupt_receiving_status_func =
usbredir_interrupt_receiving_status;
dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
+ dev->parser->bulk_receiving_status_func = usbredir_bulk_receiving_status;
dev->parser->control_packet_func = usbredir_control_packet;
dev->parser->bulk_packet_func = usbredir_bulk_packet;
dev->parser->iso_packet_func = usbredir_iso_packet;
dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
+ dev->parser->buffered_bulk_packet_func = usbredir_buffered_bulk_packet;
dev->read_buf = NULL;
dev->read_buf_size = 0;
@@ -943,6 +1129,7 @@ static void usbredir_create_parser(USBRedirDevice *dev)
usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving);
if (runstate_check(RUN_STATE_INMIGRATE)) {
flags |= usbredirparser_fl_no_hello;
@@ -970,6 +1157,8 @@ static void usbredir_do_attach(void *opaque)
usbredirparser_peer_has_cap(dev->parser,
usb_redir_cap_ep_info_max_packet_size) &&
usbredirparser_peer_has_cap(dev->parser,
+ usb_redir_cap_32bits_bulk_length) &&
+ usbredirparser_peer_has_cap(dev->parser,
usb_redir_cap_64bits_ids))) {
ERROR("usb-redir-host lacks capabilities needed for use with XHCI\n");
usbredir_reject_device(dev);
@@ -1051,6 +1240,18 @@ static void usbredir_vm_state_change(void *priv, int running, RunState state)
}
}
+static void usbredir_init_endpoints(USBRedirDevice *dev)
+{
+ int i;
+
+ usb_ep_init(&dev->dev);
+ memset(dev->endpoint, 0, sizeof(dev->endpoint));
+ for (i = 0; i < MAX_ENDPOINTS; i++) {
+ dev->endpoint[i].dev = dev;
+ QTAILQ_INIT(&dev->endpoint[i].bufpq);
+ }
+}
+
static int usbredir_initfn(USBDevice *udev)
{
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
@@ -1077,9 +1278,7 @@ static int usbredir_initfn(USBDevice *udev)
packet_id_queue_init(&dev->cancelled, dev, "cancelled");
packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight");
- for (i = 0; i < MAX_ENDPOINTS; i++) {
- QTAILQ_INIT(&dev->endpoint[i].bufpq);
- }
+ usbredir_init_endpoints(dev);
/* We'll do the attach once we receive the speed from the usb-host */
udev->auto_attach = 0;
@@ -1169,6 +1368,52 @@ error:
return -1;
}
+static void usbredir_check_bulk_receiving(USBRedirDevice *dev)
+{
+ int i, j, quirks;
+
+ if (!usbredirparser_peer_has_cap(dev->parser,
+ usb_redir_cap_bulk_receiving)) {
+ return;
+ }
+
+ for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) {
+ dev->endpoint[i].bulk_receiving_enabled = 0;
+ }
+ for (i = 0; i < dev->interface_info.interface_count; i++) {
+ quirks = usb_get_quirks(dev->device_info.vendor_id,
+ dev->device_info.product_id,
+ dev->interface_info.interface_class[i],
+ dev->interface_info.interface_subclass[i],
+ dev->interface_info.interface_protocol[i]);
+ if (!(quirks & USB_QUIRK_BUFFER_BULK_IN)) {
+ continue;
+ }
+ if (quirks & USB_QUIRK_IS_FTDI) {
+ dev->buffered_bulk_in_complete =
+ usbredir_buffered_bulk_in_complete_ftdi;
+ } else {
+ dev->buffered_bulk_in_complete =
+ usbredir_buffered_bulk_in_complete_raw;
+ }
+
+ for (j = EP2I(USB_DIR_IN); j < MAX_ENDPOINTS; j++) {
+ if (dev->endpoint[j].interface ==
+ dev->interface_info.interface[i] &&
+ dev->endpoint[j].type == USB_ENDPOINT_XFER_BULK &&
+ dev->endpoint[j].max_packet_size != 0) {
+ dev->endpoint[j].bulk_receiving_enabled = 1;
+ /*
+ * With buffering pipelining is not necessary. Also packet
+ * combining and bulk in buffering don't play nice together!
+ */
+ I2USBEP(dev, j)->pipeline = false;
+ break; /* Only buffer for the first ep of each intf */
+ }
+ }
+ }
+}
+
/*
* usbredirparser packet complete callbacks
*/
@@ -1277,13 +1522,13 @@ static void usbredir_device_connect(void *priv,
return;
}
+ usbredir_check_bulk_receiving(dev);
qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
}
static void usbredir_device_disconnect(void *priv)
{
USBRedirDevice *dev = priv;
- int i;
/* Stop any pending attaches */
qemu_del_timer(dev->attach_timer);
@@ -1300,11 +1545,7 @@ static void usbredir_device_disconnect(void *priv)
/* Reset state so that the next dev connected starts with a clean slate */
usbredir_cleanup_device_queues(dev);
- memset(dev->endpoint, 0, sizeof(dev->endpoint));
- for (i = 0; i < MAX_ENDPOINTS; i++) {
- QTAILQ_INIT(&dev->endpoint[i].bufpq);
- }
- usb_ep_init(&dev->dev);
+ usbredir_init_endpoints(dev);
dev->interface_info.interface_count = NO_INTERFACE_INFO;
dev->dev.addr = 0;
dev->dev.speed = 0;
@@ -1320,9 +1561,10 @@ static void usbredir_interface_info(void *priv,
/*
* If we receive interface info after the device has already been
- * connected (ie on a set_config), re-check the filter.
+ * connected (ie on a set_config), re-check interface dependent things.
*/
if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
+ usbredir_check_bulk_receiving(dev);
if (usbredir_check_filter(dev)) {
ERROR("Device no longer matches filter after interface info "
"change, disconnecting!\n");
@@ -1354,11 +1596,10 @@ static void usbredir_set_pipeline(USBRedirDevice *dev, struct USBEndpoint *uep)
static void usbredir_setup_usb_eps(USBRedirDevice *dev)
{
struct USBEndpoint *usb_ep;
- int i, pid;
+ int i;
for (i = 0; i < MAX_ENDPOINTS; i++) {
- pid = (i & 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT;
- usb_ep = usb_ep_get(&dev->dev, pid, i & 0x0f);
+ usb_ep = I2USBEP(dev, i);
usb_ep->type = dev->endpoint[i].type;
usb_ep->ifnum = dev->endpoint[i].interface;
usb_ep->max_packet_size = dev->endpoint[i].max_packet_size;
@@ -1424,6 +1665,7 @@ static void usbredir_ep_info(void *priv,
return;
}
usbredir_setup_usb_eps(dev);
+ usbredir_check_bulk_receiving(dev);
}
static void usbredir_configuration_status(void *priv, uint64_t id,
@@ -1514,6 +1756,25 @@ static void usbredir_bulk_streams_status(void *priv, uint64_t id,
{
}
+static void usbredir_bulk_receiving_status(void *priv, uint64_t id,
+ struct usb_redir_bulk_receiving_status_header *bulk_receiving_status)
+{
+ USBRedirDevice *dev = priv;
+ uint8_t ep = bulk_receiving_status->endpoint;
+
+ DPRINTF("bulk recv status %d ep %02X id %"PRIu64"\n",
+ bulk_receiving_status->status, ep, id);
+
+ if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].bulk_receiving_started) {
+ return;
+ }
+
+ if (bulk_receiving_status->status == usb_redir_stall) {
+ DPRINTF("bulk receiving stopped by peer ep %02X\n", ep);
+ dev->endpoint[EP2I(ep)].bulk_receiving_started = 0;
+ }
+}
+
static void usbredir_control_packet(void *priv, uint64_t id,
struct usb_redir_control_packet_header *control_packet,
uint8_t *data, int data_len)
@@ -1619,7 +1880,7 @@ static void usbredir_iso_packet(void *priv, uint64_t id,
}
/* bufp_alloc also adds the packet to the ep queue */
- bufp_alloc(dev, data, data_len, iso_packet->status, ep);
+ bufp_alloc(dev, data, data_len, iso_packet->status, ep, data);
}
static void usbredir_interrupt_packet(void *priv, uint64_t id,
@@ -1650,7 +1911,7 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
}
/* bufp_alloc also adds the packet to the ep queue */
- bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
+ bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data);
} else {
/*
* We report output interrupt packets as completed directly upon
@@ -1663,6 +1924,52 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
}
}
+static void usbredir_buffered_bulk_packet(void *priv, uint64_t id,
+ struct usb_redir_buffered_bulk_packet_header *buffered_bulk_packet,
+ uint8_t *data, int data_len)
+{
+ USBRedirDevice *dev = priv;
+ uint8_t status, ep = buffered_bulk_packet->endpoint;
+ void *free_on_destroy;
+ int i, len;
+
+ DPRINTF("buffered-bulk-in status %d ep %02X len %d id %"PRIu64"\n",
+ buffered_bulk_packet->status, ep, data_len, id);
+
+ if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_BULK) {
+ ERROR("received buffered-bulk packet for non bulk ep %02X\n", ep);
+ free(data);
+ return;
+ }
+
+ if (dev->endpoint[EP2I(ep)].bulk_receiving_started == 0) {
+ DPRINTF("received buffered-bulk packet on not started ep %02X\n", ep);
+ free(data);
+ return;
+ }
+
+ /* Data must be in maxp chunks for buffered_bulk_add_*_data_to_packet */
+ len = dev->endpoint[EP2I(ep)].max_packet_size;
+ status = usb_redir_success;
+ free_on_destroy = NULL;
+ for (i = 0; i < data_len; i += len) {
+ if (len >= (data_len - i)) {
+ len = data_len - i;
+ status = buffered_bulk_packet->status;
+ free_on_destroy = data;
+ }
+ /* bufp_alloc also adds the packet to the ep queue */
+ bufp_alloc(dev, data + i, len, status, ep, free_on_destroy);
+ }
+
+ if (dev->endpoint[EP2I(ep)].pending_async_packet) {
+ USBPacket *p = dev->endpoint[EP2I(ep)].pending_async_packet;
+ dev->endpoint[EP2I(ep)].pending_async_packet = NULL;
+ usbredir_buffered_bulk_in_complete(dev, p, ep);
+ usb_packet_complete(&dev->dev, p);
+ }
+}
+
/*
* Migration code
*/
@@ -1697,6 +2004,7 @@ static int usbredir_post_load(void *priv, int version_id)
dev->dev.speedmask = (1 << dev->dev.speed);
usbredir_setup_usb_eps(dev);
+ usbredir_check_bulk_receiving(dev);
return 0;
}
@@ -1768,22 +2076,27 @@ static const VMStateInfo usbredir_parser_vmstate_info = {
static void usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused)
{
struct endp_data *endp = priv;
+ USBRedirDevice *dev = endp->dev;
struct buf_packet *bufp;
- int remain = endp->bufpq_size;
+ int len, i = 0;
qemu_put_be32(f, endp->bufpq_size);
QTAILQ_FOREACH(bufp, &endp->bufpq, next) {
- qemu_put_be32(f, bufp->len);
+ len = bufp->len - bufp->offset;
+ DPRINTF("put_bufpq %d/%d len %d status %d\n", i + 1, endp->bufpq_size,
+ len, bufp->status);
+ qemu_put_be32(f, len);
qemu_put_be32(f, bufp->status);
- qemu_put_buffer(f, bufp->data, bufp->len);
- remain--;
+ qemu_put_buffer(f, bufp->data + bufp->offset, len);
+ i++;
}
- assert(remain == 0);
+ assert(i == endp->bufpq_size);
}
static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused)
{
struct endp_data *endp = priv;
+ USBRedirDevice *dev = endp->dev;
struct buf_packet *bufp;
int i;
@@ -1792,9 +2105,13 @@ static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused)
bufp = g_malloc(sizeof(struct buf_packet));
bufp->len = qemu_get_be32(f);
bufp->status = qemu_get_be32(f);
+ bufp->offset = 0;
bufp->data = qemu_oom_check(malloc(bufp->len)); /* regular malloc! */
+ bufp->free_on_destroy = bufp->data;
qemu_get_buffer(f, bufp->data, bufp->len);
QTAILQ_INSERT_TAIL(&endp->bufpq, bufp, next);
+ DPRINTF("get_bufpq %d/%d len %d status %d\n", i + 1, endp->bufpq_size,
+ bufp->len, bufp->status);
}
return 0;
}
@@ -1807,6 +2124,23 @@ static const VMStateInfo usbredir_ep_bufpq_vmstate_info = {
/* For endp_data migration */
+static const VMStateDescription usbredir_bulk_receiving_vmstate = {
+ .name = "usb-redir-ep/bulk-receiving",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(bulk_receiving_started, struct endp_data),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static bool usbredir_bulk_receiving_needed(void *priv)
+{
+ struct endp_data *endp = priv;
+
+ return endp->bulk_receiving_started;
+}
+
static const VMStateDescription usbredir_ep_vmstate = {
.name = "usb-redir-ep",
.version_id = 1,
@@ -1833,6 +2167,14 @@ static const VMStateDescription usbredir_ep_vmstate = {
},
VMSTATE_INT32(bufpq_target_size, struct endp_data),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (VMStateSubsection[]) {
+ {
+ .vmsd = &usbredir_bulk_receiving_vmstate,
+ .needed = usbredir_bulk_receiving_needed,
+ }, {
+ /* empty */
+ }
}
};
@@ -1994,11 +2336,12 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
uc->handle_data = usbredir_handle_data;
uc->handle_control = usbredir_handle_control;
uc->flush_ep_queue = usbredir_flush_ep_queue;
+ uc->ep_stopped = usbredir_ep_stopped;
dc->vmsd = &usbredir_vmstate;
dc->props = usbredir_properties;
}
-static TypeInfo usbredir_dev_info = {
+static const TypeInfo usbredir_dev_info = {
.name = "usb-redir",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBRedirDevice),
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 1f4d66934c..9d991599cf 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -119,7 +119,7 @@ static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_PROCESSOR_CO;
}
-static TypeInfo versatile_pci_host_info = {
+static const TypeInfo versatile_pci_host_info = {
.name = "versatile_pci_host",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -133,7 +133,7 @@ static void pci_vpb_class_init(ObjectClass *klass, void *data)
sdc->init = pci_vpb_init;
}
-static TypeInfo pci_vpb_info = {
+static const TypeInfo pci_vpb_info = {
.name = "versatile_pci",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PCIVPBState),
@@ -147,7 +147,7 @@ static void pci_realview_class_init(ObjectClass *klass, void *data)
sdc->init = pci_realview_init;
}
-static TypeInfo pci_realview_info = {
+static const TypeInfo pci_realview_info = {
.name = "realview_pci",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PCIVPBState),
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 5e89e747a2..bf72ebb305 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -386,7 +386,7 @@ static void vpb_sic_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_vpb_sic;
}
-static TypeInfo vpb_sic_info = {
+static const TypeInfo vpb_sic_info = {
.name = "versatilepb_sic",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(vpb_sic_state),
diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 28c83031d0..c51ae6761b 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -562,8 +562,8 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
return ret;
}
-static int vfio_msix_vector_use(PCIDevice *pdev,
- unsigned int nr, MSIMessage msg)
+static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
+ MSIMessage *msg, IOHandler *handler)
{
VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
VFIOMSIVector *vector;
@@ -587,7 +587,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
* Attempt to enable route through KVM irqchip,
* default to userspace handling if unavailable.
*/
- vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg);
+ vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
if (vector->virq < 0 ||
kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
vector->virq) < 0) {
@@ -596,7 +596,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
vector->virq = -1;
}
qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
- vfio_msi_interrupt, NULL, vector);
+ handler, NULL, vector);
}
/*
@@ -639,6 +639,12 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
return 0;
}
+static int vfio_msix_vector_use(PCIDevice *pdev,
+ unsigned int nr, MSIMessage msg)
+{
+ return vfio_msix_vector_do_use(pdev, nr, &msg, vfio_msi_interrupt);
+}
+
static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
{
VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
@@ -697,6 +703,22 @@ static void vfio_enable_msix(VFIODevice *vdev)
vdev->interrupt = VFIO_INT_MSIX;
+ /*
+ * Some communication channels between VF & PF or PF & fw rely on the
+ * physical state of the device and expect that enabling MSI-X from the
+ * guest enables the same on the host. When our guest is Linux, the
+ * guest driver call to pci_enable_msix() sets the enabling bit in the
+ * MSI-X capability, but leaves the vector table masked. We therefore
+ * can't rely on a vector_use callback (from request_irq() in the guest)
+ * to switch the physical device into MSI-X mode because that may come a
+ * long time after pci_enable_msix(). This code enables vector 0 with
+ * triggering to userspace, then immediately release the vector, leaving
+ * the physical device with no vectors enabled, but MSI-X enabled, just
+ * like the guest view.
+ */
+ vfio_msix_vector_do_use(&vdev->pdev, 0, NULL, NULL);
+ vfio_msix_vector_release(&vdev->pdev, 0);
+
if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
vfio_msix_vector_release, NULL)) {
error_report("vfio: msix_set_vector_notifiers failed\n");
@@ -1815,13 +1837,13 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
error_report("Warning, device %s does not support reset\n", name);
}
- if (dev_info.num_regions != VFIO_PCI_NUM_REGIONS) {
+ if (dev_info.num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
error_report("vfio: unexpected number of io regions %u\n",
dev_info.num_regions);
goto error;
}
- if (dev_info.num_irqs != VFIO_PCI_NUM_IRQS) {
+ if (dev_info.num_irqs < VFIO_PCI_MSIX_IRQ_INDEX + 1) {
error_report("vfio: unexpected number of irqs %u\n", dev_info.num_irqs);
goto error;
}
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index cbe7b05a7e..762e45aaeb 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -86,7 +86,7 @@ static void vga_class_initfn(ObjectClass *klass, void *data)
dc->props = vga_isa_properties;
}
-static TypeInfo vga_info = {
+static const TypeInfo vga_info = {
.name = "isa-vga",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISAVGAState),
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 87c7c0648d..c491af20e4 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -200,7 +200,7 @@ static void vga_class_init(ObjectClass *klass, void *data)
dc->props = vga_pci_properties;
}
-static TypeInfo vga_info = {
+static const TypeInfo vga_info = {
.name = "VGA",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIVGAState),
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 002b028b99..46072a086f 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -142,7 +142,7 @@ static void virtconsole_class_init(ObjectClass *klass, void *data)
dc->props = virtconsole_properties;
}
-static TypeInfo virtconsole_info = {
+static const TypeInfo virtconsole_info = {
.name = "virtconsole",
.parent = TYPE_VIRTIO_SERIAL_PORT,
.instance_size = sizeof(VirtConsole),
@@ -166,7 +166,7 @@ static void virtserialport_class_init(ObjectClass *klass, void *data)
dc->props = virtserialport_properties;
}
-static TypeInfo virtserialport_info = {
+static const TypeInfo virtserialport_info = {
.name = "virtserialport",
.parent = TYPE_VIRTIO_SERIAL_PORT,
.instance_size = sizeof(VirtConsole),
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 1f35922f65..0b49739946 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -1110,7 +1110,7 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
dc->props = virtio_blk_properties;
}
-static TypeInfo virtio_blk_info = {
+static const TypeInfo virtio_blk_info = {
.name = "virtio-blk-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VirtIOPCIProxy),
@@ -1144,7 +1144,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
dc->props = virtio_net_properties;
}
-static TypeInfo virtio_net_info = {
+static const TypeInfo virtio_net_info = {
.name = "virtio-net-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VirtIOPCIProxy),
@@ -1175,7 +1175,7 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
dc->props = virtio_serial_properties;
}
-static TypeInfo virtio_serial_info = {
+static const TypeInfo virtio_serial_info = {
.name = "virtio-serial-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VirtIOPCIProxy),
@@ -1203,7 +1203,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
dc->props = virtio_balloon_properties;
}
-static TypeInfo virtio_balloon_info = {
+static const TypeInfo virtio_balloon_info = {
.name = "virtio-balloon-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VirtIOPCIProxy),
@@ -1246,7 +1246,7 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
dc->props = virtio_rng_properties;
}
-static TypeInfo virtio_rng_info = {
+static const TypeInfo virtio_rng_info = {
.name = "virtio-rng-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VirtIOPCIProxy),
@@ -1304,7 +1304,7 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
dc->props = virtio_scsi_properties;
}
-static TypeInfo virtio_scsi_info = {
+static const TypeInfo virtio_scsi_info = {
.name = "virtio-scsi-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VirtIOPCIProxy),
diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index bfe1860505..0715865489 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -565,6 +565,10 @@ static void virtio_scsi_reset(VirtIODevice *vdev)
{
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
+ s->resetting++;
+ qbus_reset_all(&s->bus.qbus);
+ s->resetting--;
+
s->sense_size = VIRTIO_SCSI_SENSE_SIZE;
s->cdb_size = VIRTIO_SCSI_CDB_SIZE;
s->events_dropped = false;
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 7272bfd5fe..aa7d0d7fc7 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -1058,7 +1058,7 @@ static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
k->props = virtser_props;
}
-static TypeInfo virtio_serial_port_type_info = {
+static const TypeInfo virtio_serial_port_type_info = {
.name = TYPE_VIRTIO_SERIAL_PORT,
.parent = TYPE_DEVICE,
.instance_size = sizeof(VirtIOSerialPort),
diff --git a/hw/vmmouse.c b/hw/vmmouse.c
index 004d09851c..b9afc2c4e8 100644
--- a/hw/vmmouse.c
+++ b/hw/vmmouse.c
@@ -286,7 +286,7 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data)
dc->props = vmmouse_properties;
}
-static TypeInfo vmmouse_info = {
+static const TypeInfo vmmouse_info = {
.name = "vmmouse",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(VMMouseState),
diff --git a/hw/vmport.c b/hw/vmport.c
index 7d425237ac..faead3a955 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -155,7 +155,7 @@ static void vmport_class_initfn(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo vmport_info = {
+static const TypeInfo vmport_info = {
.name = "vmport",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(VMPortState),
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index b0e772f863..62771bb7b5 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1244,7 +1244,7 @@ static void vmsvga_class_init(ObjectClass *klass, void *data)
dc->props = vga_vmware_properties;
}
-static TypeInfo vmsvga_info = {
+static const TypeInfo vmsvga_info = {
.name = "vmware-svga",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(struct pci_vmsvga_state_s),
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index d3469d49f1..2d8e3988db 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -284,7 +284,7 @@ static void via_ac97_class_init(ObjectClass *klass, void *data)
dc->desc = "AC97";
}
-static TypeInfo via_ac97_info = {
+static const TypeInfo via_ac97_info = {
.name = "VT82C686B_AC97",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VT686AC97State),
@@ -325,7 +325,7 @@ static void via_mc97_class_init(ObjectClass *klass, void *data)
dc->desc = "MC97";
}
-static TypeInfo via_mc97_info = {
+static const TypeInfo via_mc97_info = {
.name = "VT82C686B_MC97",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VT686MC97State),
@@ -404,7 +404,7 @@ static void via_pm_class_init(ObjectClass *klass, void *data)
dc->props = via_pm_properties;
}
-static TypeInfo via_pm_info = {
+static const TypeInfo via_pm_info = {
.name = "VT82C686B_PM",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VT686PMState),
@@ -471,7 +471,7 @@ static void via_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_via;
}
-static TypeInfo via_info = {
+static const TypeInfo via_info = {
.name = "VT82C686B",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VT82C686BState),
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 54f0665135..37ce362811 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -439,7 +439,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_i6300esb;
}
-static TypeInfo i6300esb_info = {
+static const TypeInfo i6300esb_info = {
.name = "i6300esb",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(I6300State),
diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c
index 4475f7b862..599a86f5f6 100644
--- a/hw/wdt_ib700.c
+++ b/hw/wdt_ib700.c
@@ -129,7 +129,7 @@ static void wdt_ib700_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ib700;
}
-static TypeInfo wdt_ib700_info = {
+static const TypeInfo wdt_ib700_info = {
.name = "ib700",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(IB700State),
diff --git a/hw/wm8750.c b/hw/wm8750.c
index 44f138fd51..bb85064c9b 100644
--- a/hw/wm8750.c
+++ b/hw/wm8750.c
@@ -701,7 +701,7 @@ static void wm8750_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_wm8750;
}
-static TypeInfo wm8750_info = {
+static const TypeInfo wm8750_info = {
.name = "wm8750",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(WM8750State),
diff --git a/hw/xen_apic.c b/hw/xen_apic.c
index a6632fe798..1d1d15c289 100644
--- a/hw/xen_apic.c
+++ b/hw/xen_apic.c
@@ -80,7 +80,7 @@ static void xen_apic_class_init(ObjectClass *klass, void *data)
k->external_nmi = xen_apic_external_nmi;
}
-static TypeInfo xen_apic_info = {
+static const TypeInfo xen_apic_info = {
.name = "xen-apic",
.parent = TYPE_APIC_COMMON,
.instance_size = sizeof(APICCommonState),
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index e7611bb353..ca66047d82 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -420,7 +420,7 @@ static void xen_platform_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_xen_platform;
}
-static TypeInfo xen_platform_info = {
+static const TypeInfo xen_platform_info = {
.name = "xen-platform",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIXenPlatformState),
diff --git a/hw/xen_pt.c b/hw/xen_pt.c
index 6fd8433a2d..9db5f6e964 100644
--- a/hw/xen_pt.c
+++ b/hw/xen_pt.c
@@ -829,7 +829,7 @@ static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data)
dc->props = xen_pci_passthrough_properties;
};
-static TypeInfo xen_pci_passthrough_info = {
+static const TypeInfo xen_pci_passthrough_info = {
.name = "xen-pci-passthrough",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(XenPCIPassthroughState),
diff --git a/hw/xgmac.c b/hw/xgmac.c
index 9639b6141b..00dae7789c 100644
--- a/hw/xgmac.c
+++ b/hw/xgmac.c
@@ -418,7 +418,7 @@ static void xgmac_enet_class_init(ObjectClass *klass, void *data)
dc->props = xgmac_properties;
}
-static TypeInfo xgmac_enet_info = {
+static const TypeInfo xgmac_enet_info = {
.name = "xgmac",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct XgmacState),
diff --git a/hw/xilinx_axidma.c b/hw/xilinx_axidma.c
index ce02764b3f..d0ee566a28 100644
--- a/hw/xilinx_axidma.c
+++ b/hw/xilinx_axidma.c
@@ -503,7 +503,7 @@ static void axidma_class_init(ObjectClass *klass, void *data)
ssc->push = axidma_push;
}
-static TypeInfo axidma_info = {
+static const TypeInfo axidma_info = {
.name = "xlnx.axi-dma",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct XilinxAXIDMA),
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index 09e49b0aee..51c2896e44 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -893,7 +893,7 @@ static void xilinx_enet_class_init(ObjectClass *klass, void *data)
ssc->push = axienet_stream_push;
}
-static TypeInfo xilinx_enet_info = {
+static const TypeInfo xilinx_enet_info = {
.name = "xlnx.axi-ethernet",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct XilinxAXIEnet),
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index 4de4a53a0b..2254851f0a 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -243,7 +243,7 @@ static void xilinx_ethlite_class_init(ObjectClass *klass, void *data)
dc->props = xilinx_ethlite_properties;
}
-static TypeInfo xilinx_ethlite_info = {
+static const TypeInfo xilinx_ethlite_info = {
.name = "xlnx.xps-ethernetlite",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct xlx_ethlite),
diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c
index 7765079802..0c34149c27 100644
--- a/hw/xilinx_intc.c
+++ b/hw/xilinx_intc.c
@@ -175,7 +175,7 @@ static void xilinx_intc_class_init(ObjectClass *klass, void *data)
dc->props = xilinx_intc_properties;
}
-static TypeInfo xilinx_intc_info = {
+static const TypeInfo xilinx_intc_info = {
.name = "xlnx.xps-intc",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct xlx_pic),
diff --git a/hw/xilinx_spi.c b/hw/xilinx_spi.c
index 77f9178008..be581c2ac5 100644
--- a/hw/xilinx_spi.c
+++ b/hw/xilinx_spi.c
@@ -370,7 +370,7 @@ static void xilinx_spi_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_xilinx_spi;
}
-static TypeInfo xilinx_spi_info = {
+static const TypeInfo xilinx_spi_info = {
.name = "xlnx.xps-spi",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(XilinxSPI),
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index 69294bb83c..aa162efaad 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -240,7 +240,7 @@ static void xilinx_timer_class_init(ObjectClass *klass, void *data)
dc->props = xilinx_timer_properties;
}
-static TypeInfo xilinx_timer_info = {
+static const TypeInfo xilinx_timer_info = {
.name = "xlnx.xps-timer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct timerblock),
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index abd256ae00..9963982ef6 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -216,7 +216,7 @@ static void xilinx_uartlite_class_init(ObjectClass *klass, void *data)
sdc->init = xilinx_uartlite_init;
}
-static TypeInfo xilinx_uartlite_info = {
+static const TypeInfo xilinx_uartlite_info = {
.name = "xlnx.xps-uartlite",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof (struct xlx_uartlite),
diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
index 2dcd46bff1..7f00bc8256 100644
--- a/hw/xio3130_downstream.c
+++ b/hw/xio3130_downstream.c
@@ -193,7 +193,7 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
dc->props = xio3130_downstream_properties;
}
-static TypeInfo xio3130_downstream_info = {
+static const TypeInfo xio3130_downstream_info = {
.name = "xio3130-downstream",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIESlot),
diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
index 713caf2dda..70b15d37c8 100644
--- a/hw/xio3130_upstream.c
+++ b/hw/xio3130_upstream.c
@@ -167,7 +167,7 @@ static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
dc->props = xio3130_upstream_properties;
}
-static TypeInfo xio3130_upstream_info = {
+static const TypeInfo xio3130_upstream_info = {
.name = "x3130-upstream",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIEPort),
diff --git a/hw/z2.c b/hw/z2.c
index 09b03687d1..496e47df6c 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -185,7 +185,7 @@ static void zipit_lcd_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_zipit_lcd_state;
}
-static TypeInfo zipit_lcd_info = {
+static const TypeInfo zipit_lcd_info = {
.name = "zipit-lcd",
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ZipitLCD),
@@ -288,7 +288,7 @@ static void aer915_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_aer915_state;
}
-static TypeInfo aer915_info = {
+static const TypeInfo aer915_info = {
.name = "aer915",
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(AER915State),
diff --git a/hw/zaurus.c b/hw/zaurus.c
index d77b34ecce..2defe3b48d 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -236,7 +236,7 @@ static void scoop_sysbus_class_init(ObjectClass *klass, void *data)
dc->props = scoop_sysbus_properties;
}
-static TypeInfo scoop_sysbus_info = {
+static const TypeInfo scoop_sysbus_info = {
.name = "scoop",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(ScoopInfo),
diff --git a/hw/zynq_slcr.c b/hw/zynq_slcr.c
index 143a7cf436..4d6f8d9001 100644
--- a/hw/zynq_slcr.c
+++ b/hw/zynq_slcr.c
@@ -521,7 +521,7 @@ static void zynq_slcr_class_init(ObjectClass *klass, void *data)
dc->reset = zynq_slcr_reset;
}
-static TypeInfo zynq_slcr_info = {
+static const TypeInfo zynq_slcr_info = {
.class_init = zynq_slcr_class_init,
.name = "xilinx,zynq_slcr",
.parent = TYPE_SYS_BUS_DEVICE,