From 08f4c90b2887a4499a2f199cf9410308f8ed298c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 6 Jun 2013 15:41:09 +0200 Subject: usb/hcd-ehci-sysbus: Convert to QOM realize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SysBus qdev initfn merely calls SysBusDeviceClass::init, so we can replace it with a realizefn already. This avoids getting into any initfn ambiguity with the upcoming Faraday EHCI implementation. Rename internal usb_ehci_initfn() to usb_ehci_realize() to allow to return Errors from common initialization code as well. Signed-off-by: Andreas Färber Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-ehci-pci.c | 2 +- hw/usb/hcd-ehci-sysbus.c | 13 ++++++------- hw/usb/hcd-ehci.c | 2 +- hw/usb/hcd-ehci.h | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c index f1b5f5d29c..b352f73301 100644 --- a/hw/usb/hcd-ehci-pci.c +++ b/hw/usb/hcd-ehci-pci.c @@ -68,7 +68,7 @@ static int usb_ehci_pci_initfn(PCIDevice *dev) s->capsbase = 0x00; s->opregbase = 0x20; - usb_ehci_initfn(s, DEVICE(dev)); + usb_ehci_realize(s, DEVICE(dev), NULL); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem); return 0; diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c index f9e4fd3474..3179e6fe55 100644 --- a/hw/usb/hcd-ehci-sysbus.c +++ b/hw/usb/hcd-ehci-sysbus.c @@ -32,8 +32,9 @@ static Property ehci_sysbus_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static int usb_ehci_sysbus_initfn(SysBusDevice *dev) +static void usb_ehci_sysbus_realize(DeviceState *dev, Error **errp) { + SysBusDevice *d = SYS_BUS_DEVICE(dev); EHCISysBusState *i = SYS_BUS_EHCI(dev); SysBusEHCIClass *sec = SYS_BUS_EHCI_GET_CLASS(dev); EHCIState *s = &i->ehci; @@ -42,18 +43,16 @@ static int usb_ehci_sysbus_initfn(SysBusDevice *dev) s->opregbase = sec->opregbase; s->as = &address_space_memory; - usb_ehci_initfn(s, DEVICE(dev)); - sysbus_init_irq(dev, &s->irq); - sysbus_init_mmio(dev, &s->mem); - return 0; + usb_ehci_realize(s, dev, errp); + sysbus_init_irq(d, &s->irq); + sysbus_init_mmio(d, &s->mem); } static void ehci_sysbus_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = usb_ehci_sysbus_initfn; + dc->realize = usb_ehci_sysbus_realize; dc->vmsd = &vmstate_ehci_sysbus; dc->props = ehci_sysbus_properties; } diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 1ad215931e..ea0379b0d2 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -2508,7 +2508,7 @@ const VMStateDescription vmstate_ehci = { } }; -void usb_ehci_initfn(EHCIState *s, DeviceState *dev) +void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) { int i; diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 2fcb92f12b..15c76304d3 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -322,7 +322,7 @@ struct EHCIState { extern const VMStateDescription vmstate_ehci; -void usb_ehci_initfn(EHCIState *s, DeviceState *dev); +void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp); #define TYPE_PCI_EHCI "pci-ehci-usb" #define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI) -- cgit v1.2.3 From d4614cc3121b3c6375a63d01947779e36149c68c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 6 Jun 2013 15:41:10 +0200 Subject: usb/hcd-ehci: Split off instance_init from realize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the mem MemoryRegion available to derived instance_inits. Keep the bus in realize for now since naming breaks in instance_init. Signed-off-by: Andreas Färber Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-ehci-pci.c | 19 ++++++++++++++----- hw/usb/hcd-ehci-sysbus.c | 16 +++++++++++++--- hw/usb/hcd-ehci.c | 28 ++++++++++++++++------------ hw/usb/hcd-ehci.h | 1 + 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c index b352f73301..509867d1e2 100644 --- a/hw/usb/hcd-ehci-pci.c +++ b/hw/usb/hcd-ehci-pci.c @@ -60,20 +60,28 @@ static int usb_ehci_pci_initfn(PCIDevice *dev) pci_conf[0x6e] = 0x00; pci_conf[0x6f] = 0xc0; /* USBLEFCTLSTS */ - s->caps[0x09] = 0x68; /* EECP */ - s->irq = dev->irq[3]; s->as = pci_get_address_space(dev); - s->capsbase = 0x00; - s->opregbase = 0x20; - usb_ehci_realize(s, DEVICE(dev), NULL); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem); return 0; } +static void usb_ehci_pci_init(Object *obj) +{ + EHCIPCIState *i = PCI_EHCI(obj); + EHCIState *s = &i->ehci; + + s->caps[0x09] = 0x68; /* EECP */ + + s->capsbase = 0x00; + s->opregbase = 0x20; + + usb_ehci_init(s, DEVICE(obj)); +} + static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int l) { @@ -122,6 +130,7 @@ static const TypeInfo ehci_pci_type_info = { .name = TYPE_PCI_EHCI, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(EHCIPCIState), + .instance_init = usb_ehci_pci_init, .abstract = true, .class_init = ehci_class_init, }; diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c index 3179e6fe55..e450137c20 100644 --- a/hw/usb/hcd-ehci-sysbus.c +++ b/hw/usb/hcd-ehci-sysbus.c @@ -36,15 +36,24 @@ static void usb_ehci_sysbus_realize(DeviceState *dev, Error **errp) { SysBusDevice *d = SYS_BUS_DEVICE(dev); EHCISysBusState *i = SYS_BUS_EHCI(dev); - SysBusEHCIClass *sec = SYS_BUS_EHCI_GET_CLASS(dev); + EHCIState *s = &i->ehci; + + usb_ehci_realize(s, dev, errp); + sysbus_init_irq(d, &s->irq); +} + +static void ehci_sysbus_init(Object *obj) +{ + SysBusDevice *d = SYS_BUS_DEVICE(obj); + EHCISysBusState *i = SYS_BUS_EHCI(obj); + SysBusEHCIClass *sec = SYS_BUS_EHCI_GET_CLASS(obj); EHCIState *s = &i->ehci; s->capsbase = sec->capsbase; s->opregbase = sec->opregbase; s->as = &address_space_memory; - usb_ehci_realize(s, dev, errp); - sysbus_init_irq(d, &s->irq); + usb_ehci_init(s, DEVICE(obj)); sysbus_init_mmio(d, &s->mem); } @@ -61,6 +70,7 @@ static const TypeInfo ehci_type_info = { .name = TYPE_SYS_BUS_EHCI, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(EHCISysBusState), + .instance_init = ehci_sysbus_init, .abstract = true, .class_init = ehci_sysbus_class_init, .class_size = sizeof(SysBusEHCIClass), diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index ea0379b0d2..546032a2a6 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -2512,6 +2512,22 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) { int i; + usb_bus_new(&s->bus, &ehci_bus_ops, dev); + for (i = 0; i < NB_PORTS; i++) { + usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops, + USB_SPEED_MASK_HIGH); + s->ports[i].dev = 0; + } + + s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s); + s->async_bh = qemu_bh_new(ehci_frame_timer, s); + + qemu_register_reset(ehci_reset, s); + qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); +} + +void usb_ehci_init(EHCIState *s, DeviceState *dev) +{ /* 2.2 host controller interface version */ s->caps[0x00] = (uint8_t)(s->opregbase - s->capsbase); s->caps[0x01] = 0x00; @@ -2525,22 +2541,10 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) s->caps[0x0a] = 0x00; s->caps[0x0b] = 0x00; - usb_bus_new(&s->bus, &ehci_bus_ops, dev); - for(i = 0; i < NB_PORTS; i++) { - usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops, - USB_SPEED_MASK_HIGH); - s->ports[i].dev = 0; - } - - s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s); - s->async_bh = qemu_bh_new(ehci_frame_timer, s); QTAILQ_INIT(&s->aqueues); QTAILQ_INIT(&s->pqueues); usb_packet_init(&s->ipacket); - qemu_register_reset(ehci_reset, s); - qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); - memory_region_init(&s->mem, "ehci", MMIO_SIZE); memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s, "capabilities", CAPA_SIZE); diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 15c76304d3..7a9395701e 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -322,6 +322,7 @@ struct EHCIState { extern const VMStateDescription vmstate_ehci; +void usb_ehci_init(EHCIState *s, DeviceState *dev); void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp); #define TYPE_PCI_EHCI "pci-ehci-usb" -- cgit v1.2.3 From 20c570432e995313874eaeabc3d0251dab40e16f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 6 Jun 2013 15:41:11 +0200 Subject: usb/hcd-ehci: Add Tegra2 SysBus EHCI device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prepares an EHCI device for the Nvidia Tegra2 SoC family. Values based on patch by Vincent Palatin and verified against TRM v01p. Cc: Vincent Palatin Signed-off-by: Andreas Färber Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-ehci-sysbus.c | 15 +++++++++++++++ hw/usb/hcd-ehci.h | 1 + 2 files changed, 16 insertions(+) diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c index e450137c20..68667b5929 100644 --- a/hw/usb/hcd-ehci-sysbus.c +++ b/hw/usb/hcd-ehci-sysbus.c @@ -104,11 +104,26 @@ static const TypeInfo ehci_exynos4210_type_info = { .class_init = ehci_exynos4210_class_init, }; +static void ehci_tegra2_class_init(ObjectClass *oc, void *data) +{ + SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); + + sec->capsbase = 0x100; + sec->opregbase = 0x140; +} + +static const TypeInfo ehci_tegra2_type_info = { + .name = TYPE_TEGRA2_EHCI, + .parent = TYPE_SYS_BUS_EHCI, + .class_init = ehci_tegra2_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_register_static(&ehci_tegra2_type_info); } type_init(ehci_sysbus_register_types) diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 7a9395701e..2c03e8ff2c 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -339,6 +339,7 @@ typedef struct EHCIPCIState { #define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb" #define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb" +#define TYPE_TEGRA2_EHCI "tegra2-ehci-usb" #define SYS_BUS_EHCI(obj) \ OBJECT_CHECK(EHCISysBusState, (obj), TYPE_SYS_BUS_EHCI) -- cgit v1.2.3 From cc8d6a8481e64ec53d06245f249235bcaaa73b27 Mon Sep 17 00:00:00 2001 From: Kuo-Jung Su Date: Thu, 6 Jun 2013 15:41:12 +0200 Subject: usb/hcd-ehci: Replace PORTSC macros with variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace PORTSC macros with variables which could then be configured in ehci_xxxx_class_init(...) Signed-off-by: Kuo-Jung Su Signed-off-by: Andreas Färber Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-ehci-pci.c | 2 ++ hw/usb/hcd-ehci-sysbus.c | 6 ++++++ hw/usb/hcd-ehci.c | 22 ++++++++++++++-------- hw/usb/hcd-ehci.h | 12 ++++++------ 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c index 509867d1e2..5d229bc792 100644 --- a/hw/usb/hcd-ehci-pci.c +++ b/hw/usb/hcd-ehci-pci.c @@ -78,6 +78,8 @@ static void usb_ehci_pci_init(Object *obj) s->capsbase = 0x00; s->opregbase = 0x20; + s->portscbase = 0x44; + s->portnr = NB_PORTS; usb_ehci_init(s, DEVICE(obj)); } diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c index 68667b5929..bad9ca61bf 100644 --- a/hw/usb/hcd-ehci-sysbus.c +++ b/hw/usb/hcd-ehci-sysbus.c @@ -51,6 +51,8 @@ static void ehci_sysbus_init(Object *obj) s->capsbase = sec->capsbase; s->opregbase = sec->opregbase; + s->portscbase = sec->portscbase; + s->portnr = sec->portnr; s->as = &address_space_memory; usb_ehci_init(s, DEVICE(obj)); @@ -60,6 +62,10 @@ static void ehci_sysbus_init(Object *obj) static void ehci_sysbus_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass); + + sec->portscbase = 0x44; + sec->portnr = NB_PORTS; dc->realize = usb_ehci_sysbus_realize; dc->vmsd = &vmstate_ehci_sysbus; diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 546032a2a6..16d6356fa9 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -995,7 +995,7 @@ static uint64_t ehci_port_read(void *ptr, hwaddr addr, uint32_t val; val = s->portsc[addr >> 2]; - trace_usb_ehci_portsc_read(addr + PORTSC_BEGIN, addr >> 2, val); + trace_usb_ehci_portsc_read(addr + s->portscbase, addr >> 2, val); return val; } @@ -1036,7 +1036,7 @@ static void ehci_port_write(void *ptr, hwaddr addr, uint32_t old = *portsc; USBDevice *dev = s->ports[port].dev; - trace_usb_ehci_portsc_write(addr + PORTSC_BEGIN, addr >> 2, val); + trace_usb_ehci_portsc_write(addr + s->portscbase, addr >> 2, val); /* Clear rwc bits */ *portsc &= ~(val & PORTSC_RWC_MASK); @@ -1069,7 +1069,7 @@ static void ehci_port_write(void *ptr, hwaddr addr, *portsc &= ~PORTSC_RO_MASK; *portsc |= val; - trace_usb_ehci_portsc_change(addr + PORTSC_BEGIN, addr >> 2, *portsc, old); + trace_usb_ehci_portsc_change(addr + s->portscbase, addr >> 2, *portsc, old); } static void ehci_opreg_write(void *ptr, hwaddr addr, @@ -2512,8 +2512,14 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) { int i; + if (s->portnr > NB_PORTS) { + error_setg(errp, "Too many ports! Max. port number is %d.", + NB_PORTS); + return; + } + usb_bus_new(&s->bus, &ehci_bus_ops, dev); - for (i = 0; i < NB_PORTS; i++) { + for (i = 0; i < s->portnr; i++) { usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops, USB_SPEED_MASK_HIGH); s->ports[i].dev = 0; @@ -2533,7 +2539,7 @@ void usb_ehci_init(EHCIState *s, DeviceState *dev) s->caps[0x01] = 0x00; s->caps[0x02] = 0x00; s->caps[0x03] = 0x01; /* HC version */ - s->caps[0x04] = NB_PORTS; /* Number of downstream ports */ + s->caps[0x04] = s->portnr; /* Number of downstream ports */ s->caps[0x05] = 0x00; /* No companion ports at present */ s->caps[0x06] = 0x00; s->caps[0x07] = 0x00; @@ -2549,13 +2555,13 @@ void usb_ehci_init(EHCIState *s, DeviceState *dev) memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s, "capabilities", CAPA_SIZE); memory_region_init_io(&s->mem_opreg, &ehci_mmio_opreg_ops, s, - "operational", PORTSC_BEGIN); + "operational", s->portscbase); memory_region_init_io(&s->mem_ports, &ehci_mmio_port_ops, s, - "ports", PORTSC_END - PORTSC_BEGIN); + "ports", 4 * s->portnr); memory_region_add_subregion(&s->mem, s->capsbase, &s->mem_caps); memory_region_add_subregion(&s->mem, s->opregbase, &s->mem_opreg); - memory_region_add_subregion(&s->mem, s->opregbase + PORTSC_BEGIN, + memory_region_add_subregion(&s->mem, s->opregbase + s->portscbase, &s->mem_ports); } diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 2c03e8ff2c..1fb948395c 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -40,11 +40,7 @@ #define MMIO_SIZE 0x1000 #define CAPA_SIZE 0x10 -#define PORTSC 0x0044 -#define PORTSC_BEGIN PORTSC -#define PORTSC_END (PORTSC + 4 * NB_PORTS) - -#define NB_PORTS 6 /* Number of downstream ports */ +#define NB_PORTS 6 /* Max. Number of downstream ports */ typedef struct EHCIPacket EHCIPacket; typedef struct EHCIQueue EHCIQueue; @@ -268,6 +264,8 @@ struct EHCIState { int companion_count; uint16_t capsbase; uint16_t opregbase; + uint16_t portscbase; + uint16_t portnr; /* properties */ uint32_t maxframes; @@ -278,7 +276,7 @@ struct EHCIState { */ uint8_t caps[CAPA_SIZE]; union { - uint32_t opreg[PORTSC_BEGIN/sizeof(uint32_t)]; + uint32_t opreg[0x44/sizeof(uint32_t)]; struct { uint32_t usbcmd; uint32_t usbsts; @@ -363,6 +361,8 @@ typedef struct SysBusEHCIClass { uint16_t capsbase; uint16_t opregbase; + uint16_t portscbase; + uint16_t portnr; } SysBusEHCIClass; #endif -- cgit v1.2.3 From 4e3d8b4b37b67ff6896ec77975eecbaabf7968a4 Mon Sep 17 00:00:00 2001 From: Kuo-Jung Su Date: Thu, 6 Jun 2013 15:41:13 +0200 Subject: usb/hcd-ehci: Add Faraday FUSBH200 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Faraday FUSBH200 support, which is slightly different from EHCI spec. (Or maybe simply a bad/wrong implementation...) Signed-off-by: Kuo-Jung Su Signed-off-by: Andreas Färber Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-ehci-sysbus.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/usb/hcd-ehci.h | 12 ++++++++ 2 files changed, 87 insertions(+) diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c index bad9ca61bf..e7d4f74b82 100644 --- a/hw/usb/hcd-ehci-sysbus.c +++ b/hw/usb/hcd-ehci-sysbus.c @@ -124,12 +124,87 @@ static const TypeInfo ehci_tegra2_type_info = { .class_init = ehci_tegra2_class_init, }; +/* + * Faraday FUSBH200 USB 2.0 EHCI + */ + +/** + * FUSBH200EHCIRegs: + * @FUSBH200_REG_EOF_ASTR: EOF/Async. Sleep Timer Register + * @FUSBH200_REG_BMCSR: Bus Monitor Control/Status Register + */ +enum FUSBH200EHCIRegs { + FUSBH200_REG_EOF_ASTR = 0x34, + FUSBH200_REG_BMCSR = 0x40, +}; + +static uint64_t fusbh200_ehci_read(void *opaque, hwaddr addr, unsigned size) +{ + EHCIState *s = opaque; + hwaddr off = s->opregbase + s->portscbase + 4 * s->portnr + addr; + + switch (off) { + case FUSBH200_REG_EOF_ASTR: + return 0x00000041; + case FUSBH200_REG_BMCSR: + /* High-Speed, VBUS valid, interrupt level-high active */ + return (2 << 9) | (1 << 8) | (1 << 3); + } + + return 0; +} + +static void fusbh200_ehci_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ +} + +static const MemoryRegionOps fusbh200_ehci_mmio_ops = { + .read = fusbh200_ehci_read, + .write = fusbh200_ehci_write, + .valid.min_access_size = 4, + .valid.max_access_size = 4, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void fusbh200_ehci_init(Object *obj) +{ + EHCISysBusState *i = SYS_BUS_EHCI(obj); + FUSBH200EHCIState *f = FUSBH200_EHCI(obj); + EHCIState *s = &i->ehci; + + memory_region_init_io(&f->mem_vendor, &fusbh200_ehci_mmio_ops, s, + "fusbh200", 0x4c); + memory_region_add_subregion(&s->mem, + s->opregbase + s->portscbase + 4 * s->portnr, + &f->mem_vendor); +} + +static void fusbh200_ehci_class_init(ObjectClass *oc, void *data) +{ + SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); + + sec->capsbase = 0x0; + sec->opregbase = 0x10; + sec->portscbase = 0x20; + sec->portnr = 1; +} + +static const TypeInfo ehci_fusbh200_type_info = { + .name = TYPE_FUSBH200_EHCI, + .parent = TYPE_SYS_BUS_EHCI, + .instance_size = sizeof(FUSBH200EHCIState), + .instance_init = fusbh200_ehci_init, + .class_init = fusbh200_ehci_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_register_static(&ehci_tegra2_type_info); + type_register_static(&ehci_fusbh200_type_info); } type_init(ehci_sysbus_register_types) diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 1fb948395c..15a28e8b31 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -338,6 +338,7 @@ typedef struct EHCIPCIState { #define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb" #define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb" #define TYPE_TEGRA2_EHCI "tegra2-ehci-usb" +#define TYPE_FUSBH200_EHCI "fusbh200-ehci-usb" #define SYS_BUS_EHCI(obj) \ OBJECT_CHECK(EHCISysBusState, (obj), TYPE_SYS_BUS_EHCI) @@ -365,4 +366,15 @@ typedef struct SysBusEHCIClass { uint16_t portnr; } SysBusEHCIClass; +#define FUSBH200_EHCI(obj) \ + OBJECT_CHECK(FUSBH200EHCIState, (obj), TYPE_FUSBH200_EHCI) + +typedef struct FUSBH200EHCIState { + /*< private >*/ + EHCISysBusState parent_obj; + /*< public >*/ + + MemoryRegion mem_vendor; +} FUSBH200EHCIState; + #endif -- cgit v1.2.3 From bc45de8c21dfc3bc3896a78b33d5a6d9e710dfff Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 6 Jun 2013 16:39:34 +0200 Subject: usb/host-libusb: Fix building with libusb git master code The next libusb release will deprecate libusb_get_port_path, and since we compile with -Werror, this breaks the build. Signed-off-by: Hans de Goede Signed-off-by: Gerd Hoffmann --- hw/usb/host-libusb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index 3a582c526d..0c12b0fddd 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -241,7 +241,11 @@ static int usb_host_get_port(libusb_device *dev, char *port, size_t len) size_t off; int rc, i; +#if LIBUSBX_API_VERSION >= 0x01000102 + rc = libusb_get_port_numbers(dev, path, 7); +#else rc = libusb_get_port_path(ctx, dev, path, 7); +#endif if (rc < 0) { return 0; } -- cgit v1.2.3 From 628e54857a82a3cb65ef96c12640c30d6307a064 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 12 Jun 2013 13:17:02 +0200 Subject: usb-host-libusb: set USB_DEV_FLAG_IS_HOST ... like host-{linux,bsd}.c do. Cc: qemu-stable@nongnu.org Signed-off-by: Gerd Hoffmann --- hw/usb/host-libusb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index 0c12b0fddd..e2f3cc8ade 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -895,6 +895,7 @@ static int usb_host_initfn(USBDevice *udev) USBHostDevice *s = USB_HOST_DEVICE(udev); loglevel = s->loglevel; + udev->flags |= (1 << USB_DEV_FLAG_IS_HOST); udev->auto_attach = 0; QTAILQ_INIT(&s->requests); QTAILQ_INIT(&s->isorings); -- cgit v1.2.3 From 71938a09d2b9fd4007515fec6c395916cb08f868 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 12 Jun 2013 13:01:49 +0200 Subject: usb: add serial bus property This patch adds a serial property for all usb devices, which can be used to set the serial number of a usb device (as listed by lsusb -v) to a specific value. Applies to emulated devices only. Signed-off-by: Gerd Hoffmann --- hw/usb/bus.c | 1 + hw/usb/desc.c | 6 ++++++ hw/usb/dev-hid.c | 3 +++ hw/usb/dev-storage.c | 13 +++---------- include/hw/usb.h | 1 + 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index d1827be101..f83d1de6cd 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -13,6 +13,7 @@ static int usb_qdev_exit(DeviceState *qdev); static Property usb_props[] = { DEFINE_PROP_STRING("port", USBDevice, port_path), + DEFINE_PROP_STRING("serial", USBDevice, serial), DEFINE_PROP_BIT("full-path", USBDevice, flags, USB_DEV_FLAG_FULL_PATH, true), DEFINE_PROP_END_OF_LIST() diff --git a/hw/usb/desc.c b/hw/usb/desc.c index fce303e9c8..bf6c522682 100644 --- a/hw/usb/desc.c +++ b/hw/usb/desc.c @@ -566,6 +566,12 @@ void usb_desc_create_serial(USBDevice *dev) char *path; int dst; + if (dev->serial) { + /* 'serial' usb bus property has priority if present */ + usb_desc_set_string(dev, index, dev->serial); + return; + } + assert(index != 0 && desc->str[index] != NULL); dst = snprintf(serial, sizeof(serial), "%s", desc->str[index]); path = qdev_get_dev_path(hcd); diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c index b48899d500..31f3cdef42 100644 --- a/hw/usb/dev-hid.c +++ b/hw/usb/dev-hid.c @@ -560,6 +560,9 @@ static int usb_hid_initfn(USBDevice *dev, int kind) { USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + if (dev->serial) { + usb_desc_set_string(dev, STR_SERIALNUMBER, dev->serial); + } usb_desc_init(dev); us->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); hid_init(&us->hid, kind, usb_hid_changed); diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 1073901af1..fe914ab005 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -58,7 +58,6 @@ typedef struct { USBPacket *packet; /* usb-storage only */ BlockConf conf; - char *serial; uint32_t removable; } MSDState; @@ -602,7 +601,7 @@ static int usb_msd_initfn_storage(USBDevice *dev) return -1; } - blkconf_serial(&s->conf, &s->serial); + blkconf_serial(&s->conf, &dev->serial); /* * Hack alert: this pretends to be a block device, but it's really @@ -616,16 +615,11 @@ static int usb_msd_initfn_storage(USBDevice *dev) bdrv_detach_dev(bs, &s->dev.qdev); s->conf.bs = NULL; - if (s->serial) { - usb_desc_set_string(dev, STR_SERIALNUMBER, s->serial); - } else { - usb_desc_create_serial(dev); - } - + usb_desc_create_serial(dev); usb_desc_init(dev); scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_storage, NULL); scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable, - s->conf.bootindex, s->serial); + s->conf.bootindex, dev->serial); if (!scsi_dev) { return -1; } @@ -734,7 +728,6 @@ static const VMStateDescription vmstate_usb_msd = { static Property msd_properties[] = { DEFINE_BLOCK_PROPERTIES(MSDState, conf), - DEFINE_PROP_STRING("serial", MSDState, serial), DEFINE_PROP_BIT("removable", MSDState, removable, 0, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/usb.h b/include/hw/usb.h index 4d9d05e9bc..901b0da8b0 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -205,6 +205,7 @@ struct USBDevice { DeviceState qdev; USBPort *port; char *port_path; + char *serial; void *opaque; uint32_t flags; -- cgit v1.2.3 From 93c8e4dc386a243d7d417567d81dc1f1698478a4 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 12 Jun 2013 13:08:45 +0200 Subject: usb: fix serial number for hid devices commit 7b074a22dab4bdda9864b933f1bc811a3db42845 changed the serial number of hid devices. Add compat properties to keep the old serial number for qemu 0.12 and older. Signed-off-by: Gerd Hoffmann --- hw/i386/pc_piix.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 97362f2c26..7972443374 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -622,6 +622,18 @@ static QEMUMachine pc_machine_v0_13 = { .driver = "virtio-serial-pci",\ .property = "vectors",\ .value = stringify(0),\ + },{\ + .driver = "usb-mouse",\ + .property = "serial",\ + .value = "1",\ + },{\ + .driver = "usb-tablet",\ + .property = "serial",\ + .value = "1",\ + },{\ + .driver = "usb-kbd",\ + .property = "serial",\ + .value = "1",\ } static QEMUMachine pc_machine_v0_12 = { -- cgit v1.2.3