bc092b
From 058df7b5a9cc7aaa9872eaa916b715544a8f9840 Mon Sep 17 00:00:00 2001
bc092b
From: Vladimir Serbinenko <phcoder@gmail.com>
bc092b
Date: Mon, 8 May 2017 22:10:26 +0200
31cddd
Subject: [PATCH] ehci: Split core  code from PCI part.
bc092b
bc092b
On ARM often EHCI is present without PCI and just declared in device
bc092b
tree. So splitcore from PCI part.
bc092b
---
bc092b
 grub-core/Makefile.core.def  |   1 +
bc092b
 grub-core/bus/usb/ehci-pci.c | 208 +++++++++++++++++++++++++++++++++++++++++++
bc092b
 grub-core/bus/usb/ehci.c     | 201 +++--------------------------------------
bc092b
 3 files changed, 223 insertions(+), 187 deletions(-)
bc092b
 create mode 100644 grub-core/bus/usb/ehci-pci.c
bc092b
bc092b
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
ec4acb
index e4f253a205e..4745eb4d93e 100644
bc092b
--- a/grub-core/Makefile.core.def
bc092b
+++ b/grub-core/Makefile.core.def
bc092b
@@ -593,6 +593,7 @@ module = {
bc092b
 module = {
bc092b
   name = ehci;
bc092b
   common = bus/usb/ehci.c;
bc092b
+  pci = bus/usb/ehci-pci.c;
bc092b
   enable = pci;
bc092b
 };
bc092b
 
bc092b
diff --git a/grub-core/bus/usb/ehci-pci.c b/grub-core/bus/usb/ehci-pci.c
bc092b
new file mode 100644
ec4acb
index 00000000000..65e6cb57438
bc092b
--- /dev/null
bc092b
+++ b/grub-core/bus/usb/ehci-pci.c
bc092b
@@ -0,0 +1,208 @@
bc092b
+/* ehci.c - EHCI Support.  */
bc092b
+/*
bc092b
+ *  GRUB  --  GRand Unified Bootloader
bc092b
+ *  Copyright (C) 2011  Free Software Foundation, Inc.
bc092b
+ *
bc092b
+ *  GRUB is free software: you can redistribute it and/or modify
bc092b
+ *  it under the terms of the GNU General Public License as published by
bc092b
+ *  the Free Software Foundation, either version 3 of the License, or
bc092b
+ *  (at your option) any later version.
bc092b
+ *
bc092b
+ *  GRUB is distributed in the hope that it will be useful,
bc092b
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
bc092b
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
bc092b
+ *  GNU General Public License for more details.
bc092b
+ *
bc092b
+ *  You should have received a copy of the GNU General Public License
bc092b
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
bc092b
+ */
bc092b
+
bc092b
+#include <grub/pci.h>
bc092b
+#include <grub/cpu/pci.h>
bc092b
+#include <grub/cs5536.h>
bc092b
+#include <grub/misc.h>
bc092b
+#include <grub/mm.h>
bc092b
+#include <grub/time.h>
bc092b
+#include <grub/usb.h>
bc092b
+
bc092b
+#define GRUB_EHCI_PCI_SBRN_REG  0x60
bc092b
+#define GRUB_EHCI_ADDR_MEM_MASK	(~0xff)
bc092b
+
bc092b
+/* USBLEGSUP bits and related OS OWNED byte offset */
bc092b
+enum
bc092b
+{
bc092b
+  GRUB_EHCI_BIOS_OWNED = (1 << 16),
bc092b
+  GRUB_EHCI_OS_OWNED = (1 << 24)
bc092b
+};
bc092b
+
bc092b
+/* PCI iteration function... */
bc092b
+static int
bc092b
+grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
bc092b
+		    void *data __attribute__ ((unused)))
bc092b
+{
bc092b
+  volatile grub_uint32_t *regs;
bc092b
+  grub_uint32_t base, base_h;
bc092b
+  grub_uint32_t eecp_offset;
bc092b
+  grub_uint32_t usblegsup = 0;
bc092b
+  grub_uint64_t maxtime;
bc092b
+  grub_uint32_t interf;
bc092b
+  grub_uint32_t subclass;
bc092b
+  grub_uint32_t class;
bc092b
+  grub_uint8_t release;
bc092b
+  grub_uint32_t class_code;
bc092b
+
bc092b
+  grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n");
bc092b
+
bc092b
+  if (pciid == GRUB_CS5536_PCIID)
bc092b
+    {
bc092b
+      grub_uint64_t basereg;
bc092b
+
bc092b
+      basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE);
bc092b
+      if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE))
bc092b
+	{
bc092b
+	  /* Shouldn't happen.  */
bc092b
+	  grub_dprintf ("ehci", "No EHCI address is assigned\n");
bc092b
+	  return 0;
bc092b
+	}
bc092b
+      base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK);
bc092b
+      basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER;
bc092b
+      basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED;
bc092b
+      basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS;
bc092b
+      basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE;
bc092b
+      grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg);
bc092b
+    }
bc092b
+  else
bc092b
+    {
bc092b
+      grub_pci_address_t addr;
bc092b
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
bc092b
+      class_code = grub_pci_read (addr) >> 8;
bc092b
+      interf = class_code & 0xFF;
bc092b
+      subclass = (class_code >> 8) & 0xFF;
bc092b
+      class = class_code >> 16;
bc092b
+
bc092b
+      /* If this is not an EHCI controller, just return.  */
bc092b
+      if (class != 0x0c || subclass != 0x03 || interf != 0x20)
bc092b
+	return 0;
bc092b
+
bc092b
+      grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n");
bc092b
+
bc092b
+      /* Check Serial Bus Release Number */
bc092b
+      addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG);
bc092b
+      release = grub_pci_read_byte (addr);
bc092b
+      if (release != 0x20)
bc092b
+	{
bc092b
+	  grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n",
bc092b
+			release);
bc092b
+	  return 0;
bc092b
+	}
bc092b
+      grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n");
bc092b
+  
bc092b
+      /* Determine EHCI EHCC registers base address.  */
bc092b
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
bc092b
+      base = grub_pci_read (addr);
bc092b
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
bc092b
+      base_h = grub_pci_read (addr);
bc092b
+      /* Stop if registers are mapped above 4G - GRUB does not currently
bc092b
+       * work with registers mapped above 4G */
bc092b
+      if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32)
bc092b
+	  && (base_h != 0))
bc092b
+	{
bc092b
+	  grub_dprintf ("ehci",
bc092b
+			"EHCI grub_ehci_pci_iter: registers above 4G are not supported\n");
bc092b
+	  return 0;
bc092b
+	}
bc092b
+      base &= GRUB_PCI_ADDR_MEM_MASK;
bc092b
+      if (!base)
bc092b
+	{
bc092b
+	  grub_dprintf ("ehci",
bc092b
+			"EHCI: EHCI is not mapped\n");
bc092b
+	  return 0;
bc092b
+	}
bc092b
+
bc092b
+      /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
bc092b
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
bc092b
+      grub_pci_write_word(addr,
bc092b
+			  GRUB_PCI_COMMAND_MEM_ENABLED
bc092b
+			  | GRUB_PCI_COMMAND_BUS_MASTER
bc092b
+			  | grub_pci_read_word(addr));
bc092b
+      
bc092b
+      grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n");
bc092b
+    }
bc092b
+
bc092b
+  grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n",
bc092b
+		(base & GRUB_EHCI_ADDR_MEM_MASK));
bc092b
+
bc092b
+  regs = grub_pci_device_map_range (dev,
bc092b
+				    (base & GRUB_EHCI_ADDR_MEM_MASK),
bc092b
+				    0x100);
bc092b
+
bc092b
+  /* Is there EECP ? */
bc092b
+  eecp_offset = (grub_le_to_cpu32 (regs[2]) >> 8) & 0xff;
bc092b
+
bc092b
+    /* Determine and change ownership. */
bc092b
+  /* EECP offset valid in HCCPARAMS */
bc092b
+  /* Ownership can be changed via EECP only */
bc092b
+  if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40)	
bc092b
+    {
bc092b
+      grub_pci_address_t pciaddr_eecp;
bc092b
+      pciaddr_eecp = grub_pci_make_address (dev, eecp_offset);
bc092b
+
bc092b
+      usblegsup = grub_pci_read (pciaddr_eecp);
bc092b
+      if (usblegsup & GRUB_EHCI_BIOS_OWNED)
bc092b
+	{
bc092b
+	  grub_boot_time ("Taking ownership of EHCI controller");
bc092b
+	  grub_dprintf ("ehci",
bc092b
+			"EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n");
bc092b
+	  /* Ownership change - set OS_OWNED bit */
bc092b
+	  grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED);
bc092b
+	  /* Ensure PCI register is written */
bc092b
+	  grub_pci_read (pciaddr_eecp);
bc092b
+
bc092b
+	  /* Wait for finish of ownership change, EHCI specification
bc092b
+	   * doesn't say how long it can take... */
bc092b
+	  maxtime = grub_get_time_ms () + 1000;
bc092b
+	  while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
bc092b
+		 && (grub_get_time_ms () < maxtime));
bc092b
+	  if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
bc092b
+	    {
bc092b
+	      grub_dprintf ("ehci",
bc092b
+			    "EHCI grub_ehci_pci_iter: EHCI change ownership timeout");
bc092b
+	      /* Change ownership in "hard way" - reset BIOS ownership */
bc092b
+	      grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
bc092b
+	      /* Ensure PCI register is written */
bc092b
+	      grub_pci_read (pciaddr_eecp);
bc092b
+	    }
bc092b
+	}
bc092b
+      else if (usblegsup & GRUB_EHCI_OS_OWNED)
bc092b
+	/* XXX: What to do in this case - nothing ? Can it happen ? */
bc092b
+	grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n");
bc092b
+      else
bc092b
+	{
bc092b
+	  grub_dprintf ("ehci",
bc092b
+			"EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n");
bc092b
+	  /* XXX: What to do in this case ? Can it happen ?
bc092b
+	   * Is code below correct ? */
bc092b
+	  /* Ownership change - set OS_OWNED bit */
bc092b
+	  grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
bc092b
+	  /* Ensure PCI register is written */
bc092b
+	  grub_pci_read (pciaddr_eecp);
bc092b
+	}
bc092b
+
bc092b
+      /* Disable SMI, just to be sure.  */
bc092b
+      pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4);
bc092b
+      grub_pci_write (pciaddr_eecp, 0);
bc092b
+      /* Ensure PCI register is written */
bc092b
+      grub_pci_read (pciaddr_eecp);
bc092b
+    }
bc092b
+
bc092b
+  grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n");
bc092b
+
bc092b
+  grub_ehci_init_device (regs);
bc092b
+  return 0;
bc092b
+}
bc092b
+
bc092b
+void
bc092b
+grub_ehci_pci_scan (void)
bc092b
+{
bc092b
+  grub_pci_iterate (grub_ehci_pci_iter, NULL);
bc092b
+}
bc092b
diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c
ec4acb
index 5f4297bb21e..c772e76546e 100644
bc092b
--- a/grub-core/bus/usb/ehci.c
bc092b
+++ b/grub-core/bus/usb/ehci.c
bc092b
@@ -22,13 +22,10 @@
bc092b
 #include <grub/usb.h>
bc092b
 #include <grub/usbtrans.h>
bc092b
 #include <grub/misc.h>
bc092b
-#include <grub/pci.h>
bc092b
-#include <grub/cpu/pci.h>
bc092b
-#include <grub/cpu/io.h>
bc092b
 #include <grub/time.h>
bc092b
 #include <grub/loader.h>
bc092b
-#include <grub/cs5536.h>
bc092b
 #include <grub/disk.h>
bc092b
+#include <grub/dma.h>
bc092b
 #include <grub/cache.h>
bc092b
 
bc092b
 GRUB_MOD_LICENSE ("GPLv3+");
bc092b
@@ -39,8 +36,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
bc092b
  *      - is not supporting interrupt transfers
bc092b
  */
bc092b
 
bc092b
-#define GRUB_EHCI_PCI_SBRN_REG  0x60
bc092b
-
bc092b
 /* Capability registers offsets */
bc092b
 enum
bc092b
 {
bc092b
@@ -54,7 +49,6 @@ enum
bc092b
 #define GRUB_EHCI_EECP_MASK     (0xff << 8)
bc092b
 #define GRUB_EHCI_EECP_SHIFT    8
bc092b
 
bc092b
-#define GRUB_EHCI_ADDR_MEM_MASK	(~0xff)
bc092b
 #define GRUB_EHCI_POINTER_MASK	(~0x1f)
bc092b
 
bc092b
 /* Capability register SPARAMS bits */
bc092b
@@ -85,13 +79,6 @@ enum
bc092b
 
bc092b
 #define GRUB_EHCI_QH_EMPTY 1
bc092b
 
bc092b
-/* USBLEGSUP bits and related OS OWNED byte offset */
bc092b
-enum
bc092b
-{
bc092b
-  GRUB_EHCI_BIOS_OWNED = (1 << 16),
bc092b
-  GRUB_EHCI_OS_OWNED = (1 << 24)
bc092b
-};
bc092b
-
bc092b
 /* Operational registers offsets */
bc092b
 enum
bc092b
 {
bc092b
@@ -455,9 +442,10 @@ grub_ehci_reset (struct grub_ehci *e)
bc092b
 
bc092b
   sync_all_caches (e);
bc092b
 
bc092b
+  grub_dprintf ("ehci", "reset\n");
bc092b
+
bc092b
   grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
bc092b
-			  GRUB_EHCI_CMD_HC_RESET
bc092b
-			  | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
bc092b
+			  GRUB_EHCI_CMD_HC_RESET);
bc092b
   /* Ensure command is written */
bc092b
   grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
bc092b
   /* XXX: How long time could take reset of HC ? */
bc092b
@@ -473,116 +461,24 @@ grub_ehci_reset (struct grub_ehci *e)
bc092b
 }
bc092b
 
bc092b
 /* PCI iteration function... */
bc092b
-static int
bc092b
-grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
bc092b
-		    void *data __attribute__ ((unused)))
bc092b
+void
bc092b
+grub_ehci_init_device (volatile void *regs)
bc092b
 {
bc092b
-  grub_uint8_t release;
bc092b
-  grub_uint32_t class_code;
bc092b
-  grub_uint32_t interf;
bc092b
-  grub_uint32_t subclass;
bc092b
-  grub_uint32_t class;
bc092b
-  grub_uint32_t base, base_h;
bc092b
   struct grub_ehci *e;
bc092b
-  grub_uint32_t eecp_offset;
bc092b
   grub_uint32_t fp;
bc092b
   int i;
bc092b
-  grub_uint32_t usblegsup = 0;
bc092b
-  grub_uint64_t maxtime;
bc092b
   grub_uint32_t n_ports;
bc092b
   grub_uint8_t caplen;
bc092b
 
bc092b
-  grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n");
bc092b
-
bc092b
-  if (pciid == GRUB_CS5536_PCIID)
bc092b
-    {
bc092b
-      grub_uint64_t basereg;
bc092b
-
bc092b
-      basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE);
bc092b
-      if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE))
bc092b
-	{
bc092b
-	  /* Shouldn't happen.  */
bc092b
-	  grub_dprintf ("ehci", "No EHCI address is assigned\n");
bc092b
-	  return 0;
bc092b
-	}
bc092b
-      base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK);
bc092b
-      basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER;
bc092b
-      basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED;
bc092b
-      basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS;
bc092b
-      basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE;
bc092b
-      grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg);
bc092b
-    }
bc092b
-  else
bc092b
-    {
bc092b
-      grub_pci_address_t addr;
bc092b
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
bc092b
-      class_code = grub_pci_read (addr) >> 8;
bc092b
-      interf = class_code & 0xFF;
bc092b
-      subclass = (class_code >> 8) & 0xFF;
bc092b
-      class = class_code >> 16;
bc092b
-
bc092b
-      /* If this is not an EHCI controller, just return.  */
bc092b
-      if (class != 0x0c || subclass != 0x03 || interf != 0x20)
bc092b
-	return 0;
bc092b
-
bc092b
-      grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n");
bc092b
-
bc092b
-      /* Check Serial Bus Release Number */
bc092b
-      addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG);
bc092b
-      release = grub_pci_read_byte (addr);
bc092b
-      if (release != 0x20)
bc092b
-	{
bc092b
-	  grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n",
bc092b
-			release);
bc092b
-	  return 0;
bc092b
-	}
bc092b
-      grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n");
bc092b
-  
bc092b
-      /* Determine EHCI EHCC registers base address.  */
bc092b
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
bc092b
-      base = grub_pci_read (addr);
bc092b
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
bc092b
-      base_h = grub_pci_read (addr);
bc092b
-      /* Stop if registers are mapped above 4G - GRUB does not currently
bc092b
-       * work with registers mapped above 4G */
bc092b
-      if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32)
bc092b
-	  && (base_h != 0))
bc092b
-	{
bc092b
-	  grub_dprintf ("ehci",
bc092b
-			"EHCI grub_ehci_pci_iter: registers above 4G are not supported\n");
bc092b
-	  return 0;
bc092b
-	}
bc092b
-      base &= GRUB_PCI_ADDR_MEM_MASK;
bc092b
-      if (!base)
bc092b
-	{
bc092b
-	  grub_dprintf ("ehci",
bc092b
-			"EHCI: EHCI is not mapped\n");
bc092b
-	  return 0;
bc092b
-	}
bc092b
-
bc092b
-      /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
bc092b
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
bc092b
-      grub_pci_write_word(addr,
bc092b
-			  GRUB_PCI_COMMAND_MEM_ENABLED
bc092b
-			  | GRUB_PCI_COMMAND_BUS_MASTER
bc092b
-			  | grub_pci_read_word(addr));
bc092b
-      
bc092b
-      grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n");
bc092b
-    }
bc092b
-
bc092b
   /* Allocate memory for the controller and fill basic values. */
bc092b
   e = grub_zalloc (sizeof (*e));
bc092b
   if (!e)
bc092b
-    return 1;
bc092b
+    return;
bc092b
   e->framelist_chunk = NULL;
bc092b
   e->td_chunk = NULL;
bc092b
   e->qh_chunk = NULL;
bc092b
-  e->iobase_ehcc = grub_pci_device_map_range (dev,
bc092b
-					      (base & GRUB_EHCI_ADDR_MEM_MASK),
bc092b
-					      0x100);
bc092b
+  e->iobase_ehcc = regs;
bc092b
 
bc092b
-  grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n",
bc092b
-		(base & GRUB_EHCI_ADDR_MEM_MASK));
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CAPLEN: %02x\n",
bc092b
 		grub_ehci_ehcc_read8 (e, GRUB_EHCI_EHCC_CAPLEN));
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: VERSION: %04x\n",
bc092b
@@ -598,7 +494,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
bc092b
   if (caplen & (sizeof (grub_uint32_t) - 1))
bc092b
     {
bc092b
       grub_dprintf ("ehci", "Unaligned caplen\n");
bc092b
-      return 0;
bc092b
+      return;
bc092b
     }
bc092b
   e->iobase = ((volatile grub_uint32_t *) e->iobase_ehcc
bc092b
 	       + (caplen / sizeof (grub_uint32_t)));
bc092b
@@ -609,7 +505,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
bc092b
 
bc092b
   grub_dprintf ("ehci",
bc092b
 		"EHCI grub_ehci_pci_iter: iobase of oper. regs: %08x\n",
bc092b
-		(base & GRUB_EHCI_ADDR_MEM_MASK) + caplen);
bc092b
+		(grub_addr_t) e->iobase_ehcc + caplen);
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n",
bc092b
 		grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n",
bc092b
@@ -625,10 +521,6 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n",
bc092b
 		grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG));
bc092b
 
bc092b
-  /* Is there EECP ? */
bc092b
-  eecp_offset = (grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_CPARAMS)
bc092b
-		 & GRUB_EHCI_EECP_MASK) >> GRUB_EHCI_EECP_SHIFT;
bc092b
-
bc092b
   /* Check format of data structures requested by EHCI */
bc092b
   /* XXX: In fact it is not used at any place, it is prepared for future
bc092b
    * This implementation uses 32-bits pointers only */
bc092b
@@ -732,65 +624,6 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
bc092b
 
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH/TD init. OK\n");
bc092b
 
bc092b
-  /* Determine and change ownership. */
bc092b
-  /* EECP offset valid in HCCPARAMS */
bc092b
-  /* Ownership can be changed via EECP only */
bc092b
-  if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40)	
bc092b
-    {
bc092b
-      grub_pci_address_t pciaddr_eecp;
bc092b
-      pciaddr_eecp = grub_pci_make_address (dev, eecp_offset);
bc092b
-
bc092b
-      usblegsup = grub_pci_read (pciaddr_eecp);
bc092b
-      if (usblegsup & GRUB_EHCI_BIOS_OWNED)
bc092b
-	{
bc092b
-	  grub_boot_time ("Taking ownership of EHCI controller");
bc092b
-	  grub_dprintf ("ehci",
bc092b
-			"EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n");
bc092b
-	  /* Ownership change - set OS_OWNED bit */
bc092b
-	  grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED);
bc092b
-	  /* Ensure PCI register is written */
bc092b
-	  grub_pci_read (pciaddr_eecp);
bc092b
-
bc092b
-	  /* Wait for finish of ownership change, EHCI specification
bc092b
-	   * doesn't say how long it can take... */
bc092b
-	  maxtime = grub_get_time_ms () + 1000;
bc092b
-	  while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
bc092b
-		 && (grub_get_time_ms () < maxtime));
bc092b
-	  if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
bc092b
-	    {
bc092b
-	      grub_dprintf ("ehci",
bc092b
-			    "EHCI grub_ehci_pci_iter: EHCI change ownership timeout");
bc092b
-	      /* Change ownership in "hard way" - reset BIOS ownership */
bc092b
-	      grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
bc092b
-	      /* Ensure PCI register is written */
bc092b
-	      grub_pci_read (pciaddr_eecp);
bc092b
-	    }
bc092b
-	}
bc092b
-      else if (usblegsup & GRUB_EHCI_OS_OWNED)
bc092b
-	/* XXX: What to do in this case - nothing ? Can it happen ? */
bc092b
-	grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n");
bc092b
-      else
bc092b
-	{
bc092b
-	  grub_dprintf ("ehci",
bc092b
-			"EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n");
bc092b
-	  /* XXX: What to do in this case ? Can it happen ?
bc092b
-	   * Is code below correct ? */
bc092b
-	  /* Ownership change - set OS_OWNED bit */
bc092b
-	  grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
bc092b
-	  /* Ensure PCI register is written */
bc092b
-	  grub_pci_read (pciaddr_eecp);
bc092b
-	}
bc092b
-
bc092b
-    /* Disable SMI, just to be sure.  */
bc092b
-    pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4);
bc092b
-    grub_pci_write (pciaddr_eecp, 0);
bc092b
-    /* Ensure PCI register is written */
bc092b
-    grub_pci_read (pciaddr_eecp);
bc092b
-
bc092b
-    }
bc092b
-
bc092b
-  grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n");
bc092b
-
bc092b
   /* Now we can setup EHCI (maybe...) */
bc092b
 
bc092b
   /* Check if EHCI is halted and halt it if not */
bc092b
@@ -864,7 +697,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
bc092b
 
bc092b
   grub_dprintf ("ehci",
bc092b
 		"EHCI grub_ehci_pci_iter: iobase of oper. regs: %08x\n",
bc092b
-		(base & GRUB_EHCI_ADDR_MEM_MASK));
bc092b
+		(grub_addr_t) regs);
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n",
bc092b
 		grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n",
bc092b
@@ -880,7 +713,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
bc092b
   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n",
bc092b
 		grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG));
bc092b
 
bc092b
-  return 0;
bc092b
+  return;
bc092b
 
bc092b
 fail:
bc092b
   if (e)
bc092b
@@ -894,7 +727,7 @@ fail:
bc092b
     }
bc092b
   grub_free (e);
bc092b
 
bc092b
-  return 0;
bc092b
+  return;
bc092b
 }
bc092b
 
bc092b
 static int
bc092b
@@ -1891,12 +1724,6 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
bc092b
     }
bc092b
 }
bc092b
 
bc092b
-static void
bc092b
-grub_ehci_inithw (void)
bc092b
-{
bc092b
-  grub_pci_iterate (grub_ehci_pci_iter, NULL);
bc092b
-}
bc092b
-
bc092b
 static grub_err_t
bc092b
 grub_ehci_restore_hw (void)
bc092b
 {
bc092b
@@ -1997,7 +1824,7 @@ GRUB_MOD_INIT (ehci)
bc092b
   grub_stop_disk_firmware ();
bc092b
 
bc092b
   grub_boot_time ("Initing EHCI hardware");
bc092b
-  grub_ehci_inithw ();
bc092b
+  grub_ehci_pci_scan ();
bc092b
   grub_boot_time ("Registering EHCI driver");
bc092b
   grub_usb_controller_dev_register (&usb_controller);
bc092b
   grub_boot_time ("EHCI driver registered");