Index: uspace/drv/bus/usb/ehci/hc.c
===================================================================
--- uspace/drv/bus/usb/ehci/hc.c	(revision 2be477d52d8fed39a2862f10b87d12afb454b9c7)
+++ uspace/drv/bus/usb/ehci/hc.c	(revision 478e24302fde596ec5eacd600f475cedc015937b)
@@ -89,5 +89,4 @@
 };
 
-static void hc_gain_control(hc_t *instance);
 static void hc_start(hc_t *instance);
 static int hc_init_memory(hc_t *instance);
@@ -185,6 +184,4 @@
 	}
 
-	hc_gain_control(instance);
-
 	ehci_rh_init(
 	    &instance->rh, instance->caps, instance->registers, "ehci rh");
@@ -262,27 +259,52 @@
 }
 
-/** Turn off any (BIOS)driver that might be in control of the device.
- *
- * This function implements routines described in chapter 5.1.1.3 of the EHCI
- * specification (page 40, pdf page 54).
+/** EHCI hw initialization routine.
  *
  * @param[in] instance EHCI hc driver structure.
  */
-void hc_gain_control(hc_t *instance)
-{
-	assert(instance);
-}
-
-/** EHCI hw initialization routine.
- *
- * @param[in] instance EHCI hc driver structure.
- */
 void hc_start(hc_t *instance)
 {
 	assert(instance);
+	/* Turn of the HC if it's running, Reseting a running device is
+	 * undefined */
+	if (!(EHCI_RD(instance->registers->usbsts) & USB_STS_HC_HALTED_FLAG)) {
+		/* disable all interrupts */
+		EHCI_WR(instance->registers->usbintr, 0);
+		/* ack all interrupts */
+		EHCI_WR(instance->registers->usbsts, 0x3f);
+		/* Stop HC hw */
+		EHCI_WR(instance->registers->usbcmd, 0);
+		/* Wait until hc is halted */
+		while ((EHCI_RD(instance->registers->usbsts) & USB_STS_HC_HALTED_FLAG) == 0) {
+			async_usleep(1);
+		}
+		usb_log_info("EHCI turned off.\n");
+	} else {
+		usb_log_info("EHCI was not running.\n");
+	}
+
+	/* Hw initialization sequence, see page 53 (pdf 63) */
+	EHCI_SET(instance->registers->usbcmd, USB_CMD_HC_RESET_FLAG);
+	while (EHCI_RD(instance->registers->usbcmd) & USB_CMD_HC_RESET_FLAG) {
+		async_usleep(1);
+	}
+	/* Enable interrupts */
+	EHCI_WR(instance->registers->usbintr, USB_INTR_PORT_CHANGE_FLAG | USB_INTR_IRQ_FLAG);
+	/* Use lower 4G segment */
+	EHCI_WR(instance->registers->ctrldssegment, 0);
+	/* Set periodic list */
+	assert(instance->periodic_list_base);
+	const uintptr_t phys_base =
+	    addr_to_phys((void*)instance->periodic_list_base);
+	assert((phys_base & USB_PERIODIC_LIST_BASE_MASK) == phys_base);
+	EHCI_WR(instance->registers->periodiclistbase, phys_base);
+
+	/* start hc and get all ports */
+	EHCI_SET(instance->registers->usbcmd, USB_CMD_RUN_FLAG);
+	EHCI_SET(instance->registers->configflag, USB_CONFIG_FLAG_FLAG);
+#if 0
 	/*
 	 * TURN OFF EHCI FOR NOW
 	 */
-
 	usb_log_debug("USBCMD value: %x.\n",
 	    EHCI_RD(instance->registers->usbcmd));
@@ -301,4 +323,5 @@
 		usb_log_info("EHCI was not running.\n");
 	}
+#endif
 	usb_log_debug("Registers: \n"
 	    "\t USBCMD(%p): %x(0x00080000 = at least 1ms between interrupts)\n"
@@ -319,4 +342,16 @@
 int hc_init_memory(hc_t *instance)
 {
+	assert(instance);
+
+	/* Take 1024 periodic list heads, we ignore low mem options */
+	instance->periodic_list_base = get_page();
+	if (!instance->periodic_list_base)
+		return ENOMEM;
+	for (unsigned i = 0;
+	    i < PAGE_SIZE/sizeof(instance->periodic_list_base[0]); ++i)
+	{
+		/* Disable everything for now */
+		instance->periodic_list_base[i] = LINK_POINTER_TERM;
+	}
 	return EOK;
 }
Index: uspace/drv/bus/usb/ehci/hc.h
===================================================================
--- uspace/drv/bus/usb/ehci/hc.h	(revision 2be477d52d8fed39a2862f10b87d12afb454b9c7)
+++ uspace/drv/bus/usb/ehci/hc.h	(revision 478e24302fde596ec5eacd600f475cedc015937b)
@@ -50,4 +50,5 @@
 #include "ehci_regs.h"
 #include "ehci_rh.h"
+#include "hw_struct/link_pointer.h"
 //#include "endpoint_list.h"
 
@@ -58,4 +59,7 @@
 	/** Memory mapped I/O registers area */
 	ehci_regs_t *registers;
+
+	/** Iso transfer list */
+	link_pointer_t *periodic_list_base;
 
 	/** Transfer schedules */
Index: uspace/drv/bus/usb/ehci/utils/malloc32.h
===================================================================
--- uspace/drv/bus/usb/ehci/utils/malloc32.h	(revision 2be477d52d8fed39a2862f10b87d12afb454b9c7)
+++ uspace/drv/bus/usb/ehci/utils/malloc32.h	(revision 478e24302fde596ec5eacd600f475cedc015937b)
@@ -36,4 +36,5 @@
 
 #include <as.h>
+#include <ddi.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -44,5 +45,7 @@
  * buffers do not have to be aligned.
  */
-#define EHCI_ALIGN 32
+#define EHCI_ALIGN   32
+
+#define EHCI_REQUIRED_PAGE_SIZE   4096
 
 /** Get physical address translation
@@ -76,4 +79,25 @@
 static inline void free32(void *addr)
 	{ free(addr); }
+
+/** Create 4KB page mapping
+ *
+ * @return Address of the mapped page, NULL on failure.
+ */
+static inline void *get_page(void)
+{
+	uintptr_t phys;
+	void *address;
+
+	const int ret = dmamem_map_anonymous(EHCI_REQUIRED_PAGE_SIZE,
+	    DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
+	    &address);
+
+	return ((ret == EOK) ? address : NULL);
+}
+
+static inline void return_page(void *page)
+{
+	dmamem_unmap_anonymous(page);
+}
 #endif
 /**
