From patchwork Tue Feb 5 01:08:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuo-Jung Su X-Patchwork-Id: 218133 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D2C7F2C02B9 for ; Tue, 5 Feb 2013 13:01:28 +1100 (EST) Received: from localhost ([::1]:34109 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U2Xqg-0001Oc-JN for incoming@patchwork.ozlabs.org; Mon, 04 Feb 2013 21:01:26 -0500 Received: from eggs.gnu.org ([208.118.235.92]:36919) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U2XqX-0001OJ-B9 for qemu-devel@nongnu.org; Mon, 04 Feb 2013 21:01:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U2XqT-0004Mn-PK for qemu-devel@nongnu.org; Mon, 04 Feb 2013 21:01:17 -0500 Received: from mail-ia0-x234.google.com ([2607:f8b0:4001:c02::234]:40928) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U2XqT-0004M5-It for qemu-devel@nongnu.org; Mon, 04 Feb 2013 21:01:13 -0500 Received: by mail-ia0-f180.google.com with SMTP id f27so8726885iae.25 for ; Mon, 04 Feb 2013 18:01:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer; bh=UkhzUBku2VyezGo56DSM9bkV6+xmU9G9Sf299D7hCco=; b=DeEtKSbIeCGVOZAtREwjKwAcn2U4aCsEpnUZ2i3gwL7eI0It+ztVBZpR0gCvUrm0YR Md35iULqOGrOWpSm3qZx9XS5xRYvpUEx0vOrRfl7nmqQ88/reK6LgDc7V8eijX/XDgwT bbeNMf1z3eJCrxz6DG4fFrSuoS61x+5Qr4nRO5l/hYlQUygAhTTa4+OxAU9Ka+eNep/s rol29a9gRUTVDkxvA+KgYHyCJX6Bgx6HCnAaPIFhfuRpdtX/2K3RsAFc0hLaziGPEesY uFdGk7YarA7kzFPBUApYncrzEV1EJ4wvjKeYcqixkh3ML99UdAGwAMheHznpE2k3Z9LE gtIw== X-Received: by 10.42.18.138 with SMTP id x10mr19478009ica.22.1360026548846; Mon, 04 Feb 2013 17:09:08 -0800 (PST) Received: from localhost.localdomain ([220.132.37.35]) by mx.google.com with ESMTPS id xn10sm17964541igb.4.2013.02.04.17.09.06 (version=TLSv1 cipher=DES-CBC3-SHA bits=168/168); Mon, 04 Feb 2013 17:09:08 -0800 (PST) From: Kuo-Jung Su To: qemu-devel@nongnu.org Date: Tue, 5 Feb 2013 09:08:26 +0800 Message-Id: <1360026506-5462-1-git-send-email-dantesu@gmail.com> X-Mailer: git-send-email 1.7.9.5 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c02::234 Cc: Peter Crosthwaite , Gerd Hoffmann , Kuo-Jung Su , Andreas Subject: [Qemu-devel] [PATCH v2] usb-ehci: Replace PORTSC macros with variables X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Kuo-Jung Su 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 Cc: Gerd Hoffmann Cc: Andreas Cc: Peter Crosthwaite --- 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(-) 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