Patchwork [v2] usb-ehci: Replace PORTSC macros with variables

login
register
mail settings
Submitter Kuo-Jung Su
Date Feb. 5, 2013, 1:08 a.m.
Message ID <1360026506-5462-1-git-send-email-dantesu@gmail.com>
Download mbox | patch
Permalink /patch/218133/
State New
Headers show

Comments

Kuo-Jung Su - Feb. 5, 2013, 1:08 a.m.
From: Kuo-Jung Su <dantesu@faraday-tech.com>

Replace PORTSC macros with variables which could then be
configured in ehci_xxxx_class_init(...) to support some
non-standard EHCI controllers.

Signed-off-by: Kuo-Jung Su <dantesu@faraday-tech.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Andreas <afaerber@suse.de>
Cc: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
 Changes for V2:
   - add missing port init to usb_ehci_pci_initfn()

 hw/usb/hcd-ehci-pci.c    |    2 ++
 hw/usb/hcd-ehci-sysbus.c |    6 ++++++
 hw/usb/hcd-ehci.c        |   21 +++++++++++++--------
 hw/usb/hcd-ehci.h        |   12 ++++++------
 4 files changed, 27 insertions(+), 14 deletions(-)

Patch

diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
index 0eb7826..bd56347 100644
--- a/hw/usb/hcd-ehci-pci.c
+++ b/hw/usb/hcd-ehci-pci.c
@@ -67,6 +67,8 @@  static int usb_ehci_pci_initfn(PCIDevice *dev)
 
     s->capsbase = 0x00;
     s->opregbase = 0x20;
+    s->portscbase = 0x44;
+    s->portnr = NB_PORTS;
 
     usb_ehci_initfn(s, DEVICE(dev));
     pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index b68a66a..126ddd8 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -40,6 +40,8 @@  static int usb_ehci_sysbus_initfn(SysBusDevice *dev)
 
     s->capsbase = sec->capsbase;
     s->opregbase = sec->opregbase;
+    s->portscbase = sec->portscbase;
+    s->portnr = sec->portnr;
     s->dma = &dma_context_memory;
 
     usb_ehci_initfn(s, DEVICE(dev));
@@ -73,6 +75,8 @@  static void ehci_xlnx_class_init(ObjectClass *oc, void *data)
 
     sec->capsbase = 0x100;
     sec->opregbase = 0x140;
+    sec->portscbase = 0x44;
+    sec->portnr = NB_PORTS;
 }
 
 static const TypeInfo ehci_xlnx_type_info = {
@@ -87,6 +91,8 @@  static void ehci_exynos4210_class_init(ObjectClass *oc, void *data)
 
     sec->capsbase = 0x0;
     sec->opregbase = 0x10;
+    sec->portscbase = 0x44;
+    sec->portnr = NB_PORTS;
 }
 
 static const TypeInfo ehci_exynos4210_type_info = {
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 7040659..a3e869a 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -988,7 +988,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;
 }
 
@@ -1029,7 +1029,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);
@@ -1062,7 +1062,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,
@@ -2510,7 +2510,7 @@  void usb_ehci_initfn(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;
@@ -2518,8 +2518,13 @@  void usb_ehci_initfn(EHCIState *s, DeviceState *dev)
     s->caps[0x0a] = 0x00;
     s->caps[0x0b] = 0x00;
 
+    if (s->portnr > NB_PORTS) {
+        hw_error("hcd-ehci: Too many ports! Max. port number=%d\n", NB_PORTS);
+        exit(1);
+    }
+
     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;
@@ -2538,13 +2543,13 @@  void usb_ehci_initfn(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 e95bb7e..9e62a04 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;
@@ -361,6 +359,8 @@  typedef struct SysBusEHCIClass {
 
     uint16_t capsbase;
     uint16_t opregbase;
+    uint16_t portscbase;
+    uint16_t portnr;
 } SysBusEHCIClass;
 
 #endif