Index: uspace/drv/bus/usb/ehci/res.c
===================================================================
--- uspace/drv/bus/usb/ehci/res.c	(revision f9b2cb4cf365498e1fe141b1aa66950fbc3dcb17)
+++ uspace/drv/bus/usb/ehci/res.c	(revision b4b534ac1d1515633baff0d563e9c16938bfe19f)
@@ -46,16 +46,5 @@
 
 #include "res.h"
-
-#define HCC_PARAMS_OFFSET 0x8
-#define HCC_PARAMS_EECP_MASK 0xff
-#define HCC_PARAMS_EECP_OFFSET 8
-
-#define CMD_OFFSET 0x0
-#define STS_OFFSET 0x4
-#define INT_OFFSET 0x8
-#define CFG_OFFSET 0x40
-
-#define USBCMD_RUN 1
-#define USBSTS_HALTED (1 << 12)
+#include "ehci_regs.h"
 
 #define USBLEGSUP_OFFSET 0
@@ -67,62 +56,4 @@
 #define WAIT_STEP 10
 
-
-/** Get address of registers and IRQ for given device.
- *
- * @param[in] dev Device asking for the addresses.
- * @param[out] mem_regs_p Pointer to the register range.
- * @param[out] irq_no IRQ assigned to the device.
- * @return Error code.
- */
-int get_my_registers(ddf_dev_t *dev,
-    addr_range_t *mem_regs_p, int *irq_no)
-{
-	assert(dev);
-	
-	async_sess_t *parent_sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	hw_res_list_parsed_t hw_res;
-	hw_res_list_parsed_init(&hw_res);
-	const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
-	async_hangup(parent_sess);
-	if (ret != EOK) {
-		return ret;
-	}
-
-	if (hw_res.irqs.count != 1 || hw_res.mem_ranges.count != 1) {
-		hw_res_list_parsed_clean(&hw_res);
-		return ENOENT;
-	}
-
-	if (mem_regs_p)
-		*mem_regs_p = hw_res.mem_ranges.ranges[0];
-	if (irq_no)
-		*irq_no = hw_res.irqs.irqs[0];
-
-	hw_res_list_parsed_clean(&hw_res);
-	return EOK;
-}
-
-/** Calls the PCI driver with a request to enable interrupts
- *
- * @param[in] device Device asking for interrupts
- * @return Error code.
- */
-int enable_interrupts(ddf_dev_t *device)
-{
-	async_sess_t *parent_sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	const bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-	
-	return enabled ? EOK : EIO;
-}
-
 /** Implements BIOS hands-off routine as described in EHCI spec
  *
@@ -131,5 +62,5 @@
  * @return Error code.
  */
-static int disable_extended_caps(ddf_dev_t *device, unsigned eecp)
+static int disable_extended_caps(async_sess_t *parent_sess, unsigned eecp)
 {
 	/* nothing to do */
@@ -137,51 +68,34 @@
 		return EOK;
 
-	async_sess_t *parent_sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-
 	/* Read the first EEC. i.e. Legacy Support register */
 	uint32_t usblegsup;
-	int rc = pci_config_space_read_32(parent_sess,
+	int ret = pci_config_space_read_32(parent_sess,
 	    eecp + USBLEGSUP_OFFSET, &usblegsup);
-	if (rc != EOK) {
-		usb_log_error("Failed to read USBLEGSUP: %s.\n",
-		    str_error(rc));
-		goto error;
-	}
-
-	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
+	if (ret != EOK) {
+		usb_log_error("Failed to read USBLEGSUP: %s.\n", str_error(ret));
+		return ret;
+	}
+	usb_log_debug2("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
 
 	/* Request control from firmware/BIOS by writing 1 to highest
 	 * byte. (OS Control semaphore)*/
 	usb_log_debug("Requesting OS control.\n");
-	rc = pci_config_space_write_8(parent_sess,
+	ret = pci_config_space_write_8(parent_sess,
 	    eecp + USBLEGSUP_OFFSET + 3, 1);
-	if (rc != EOK) {
+	if (ret != EOK) {
 		usb_log_error("Failed to request OS EHCI control: %s.\n",
-		    str_error(rc));
-		goto error;
+		    str_error(ret));
+		return ret;
 	}
 
 	size_t wait = 0;
 	/* Wait for BIOS to release control. */
-	rc = pci_config_space_read_32(
+	ret = pci_config_space_read_32(
 	    parent_sess, eecp + USBLEGSUP_OFFSET, &usblegsup);
-	if (rc != EOK) {
-		usb_log_error("Failed reading PCI config space: %s.\n",
-		    str_error(rc));
-		goto error;
-	}
-
-	while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {
+	while ((ret == EOK) && (wait < DEFAULT_WAIT)
+	    && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {
 		async_usleep(WAIT_STEP);
-		rc = pci_config_space_read_32(parent_sess,
+		ret = pci_config_space_read_32(parent_sess,
 		    eecp + USBLEGSUP_OFFSET, &usblegsup);
-		if (rc != EOK) {
-			usb_log_error("Failed reading PCI config space: %s.\n",
-			    str_error(rc));
-			goto error;
-		}
 		wait += WAIT_STEP;
 	}
@@ -189,5 +103,4 @@
 	if ((usblegsup & USBLEGSUP_BIOS_CONTROL) == 0) {
 		usb_log_info("BIOS released control after %zu usec.\n", wait);
-		async_hangup(parent_sess);
 		return EOK;
 	}
@@ -196,10 +109,10 @@
 	usb_log_warning( "BIOS failed to release control after "
 	    "%zu usecs, force it.\n", wait);
-	rc = pci_config_space_write_32(parent_sess,
+	ret = pci_config_space_write_32(parent_sess,
 	    eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL);
-	if (rc != EOK) {
-		usb_log_error("Failed to force OS control: "
-		    "%s.\n", str_error(rc));
-		goto error;
+	if (ret != EOK) {
+		usb_log_error("Failed to force OS control: %s.\n",
+		    str_error(ret));
+		return ret;
 	}
 
@@ -213,13 +126,12 @@
 		/* Read the second EEC Legacy Support and Control register */
 		uint32_t usblegctlsts;
-		rc = pci_config_space_read_32(parent_sess,
+		ret = pci_config_space_read_32(parent_sess,
 		    eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
-		if (rc != EOK) {
+		if (ret != EOK) {
 			usb_log_error("Failed to get USBLEGCTLSTS: %s.\n",
-			    str_error(rc));
-			goto error;
+			    str_error(ret));
+			return ret;
 		}
-
-		usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts);
+		usb_log_debug2("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts);
 		/*
 		 * Zero SMI enables in legacy control register.
@@ -227,112 +139,97 @@
 		 * interfering. NOTE: Three upper bits are WC
 		 */
-		rc = pci_config_space_write_32(parent_sess,
+		ret = pci_config_space_write_32(parent_sess,
 		    eecp + USBLEGCTLSTS_OFFSET, 0xe0000000);
-		if (rc != EOK) {
-			usb_log_error("Failed(%d) zero USBLEGCTLSTS.\n", rc);
-			goto error;
+		if (ret != EOK) {
+			usb_log_error("Failed to zero USBLEGCTLSTS: %s\n",
+			    str_error(ret));
+			return ret;
 		}
 
 		udelay(10);
-		rc = pci_config_space_read_32(parent_sess,
+		/* read again to amke sure it's zeroed */
+		ret = pci_config_space_read_32(parent_sess,
 		    eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
-		if (rc != EOK) {
+		if (ret != EOK) {
 			usb_log_error("Failed to get USBLEGCTLSTS 2: %s.\n",
-			    str_error(rc));
-			goto error;
+			    str_error(ret));
+			return ret;
 		}
-
-		usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",
+		usb_log_debug2("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",
 		    usblegctlsts);
 	}
 
 	/* Read again Legacy Support register */
-	rc = pci_config_space_read_32(parent_sess,
+	ret = pci_config_space_read_32(parent_sess,
 	    eecp + USBLEGSUP_OFFSET, &usblegsup);
-	if (rc != EOK) {
+	if (ret != EOK) {
 		usb_log_error("Failed to read USBLEGSUP: %s.\n",
-		    str_error(rc));
-		goto error;
-	}
-
-	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
-	async_hangup(parent_sess);
-	return EOK;
-error:
-	async_hangup(parent_sess);
-	return rc;
+		    str_error(ret));
+		return ret;
+	}
+	usb_log_debug2("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
+	return ret;
 }
 
-int disable_legacy(ddf_dev_t *device, addr_range_t *reg_range)
+int disable_legacy(ddf_dev_t *device)
 {
 	assert(device);
+
+	async_sess_t *parent_sess = devman_parent_device_connect(
+	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+
 	usb_log_debug("Disabling EHCI legacy support.\n");
+
+	hw_res_list_parsed_t res;
+	hw_res_list_parsed_init(&res);
+	int ret = hw_res_get_list_parsed(parent_sess, &res, 0);
+	if (ret != EOK) {
+		usb_log_error("Failed to get resource list: %s\n",
+		    str_error(ret));
+		goto clean;
+	}
+
+	if (res.mem_ranges.count < 1) {
+		usb_log_error("Incorrect mem range count: %zu",
+		    res.mem_ranges.count);
+		ret = EINVAL;
+		goto clean;
+	}
 
 	/* Map EHCI registers */
 	void *regs = NULL;
-	int rc = pio_enable_range(reg_range, &regs);
-	if (rc != EOK) {
+	ret = pio_enable_range(&res.mem_ranges.ranges[0], &regs);
+	if (ret != EOK) {
 		usb_log_error("Failed to map registers %p: %s.\n",
-		    RNGABSPTR(*reg_range), str_error(rc));
-		return rc;
-	}
-
-	usb_log_debug2("Registers mapped at: %p.\n", regs);
-
-	const uint32_t hcc_params =
-	    *(uint32_t*)(regs + HCC_PARAMS_OFFSET);
-	usb_log_debug("Value of hcc params register: %x.\n", hcc_params);
+		    RNGABSPTR(res.mem_ranges.ranges[0]), str_error(ret));
+		goto clean;
+	}
+
+	usb_log_debug("Registers mapped at: %p.\n", regs);
+
+	ehci_caps_regs_t *ehci_caps = regs;
+
+	const uint32_t hcc_params = EHCI_RD(ehci_caps->hccparams);
+	usb_log_debug2("Value of hcc params register: %x.\n", hcc_params);
 
 	/* Read value of EHCI Extended Capabilities Pointer
 	 * position of EEC registers (points to PCI config space) */
 	const uint32_t eecp =
-	    (hcc_params >> HCC_PARAMS_EECP_OFFSET) & HCC_PARAMS_EECP_MASK;
-	usb_log_debug("Value of EECP: %x.\n", eecp);
-
-	rc = disable_extended_caps(device, eecp);
-	if (rc != EOK) {
+	    (hcc_params >> EHCI_CAPS_HCC_EECP_SHIFT) & EHCI_CAPS_HCC_EECP_MASK;
+	usb_log_debug2("Value of EECP: %x.\n", eecp);
+
+	ret = disable_extended_caps(parent_sess, eecp);
+	if (ret != EOK) {
 		usb_log_error("Failed to disable extended capabilities: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-
-	/*
-	 * TURN OFF EHCI FOR NOW, DRIVER WILL REINITIALIZE IT IF NEEDED
-	 */
-
-	/* Get size of capability registers in memory space. */
-	const unsigned operation_offset = *(uint8_t*)regs;
-	usb_log_debug("USBCMD offset: %d.\n", operation_offset);
-
-	/* Zero USBCMD register. */
-	volatile uint32_t *usbcmd =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + CMD_OFFSET);
-	volatile uint32_t *usbsts =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + STS_OFFSET);
-	volatile uint32_t *usbconf =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + CFG_OFFSET);
-	volatile uint32_t *usbint =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + INT_OFFSET);
-	usb_log_debug("USBCMD value: %x.\n", *usbcmd);
-	if (*usbcmd & USBCMD_RUN) {
-		*usbsts = 0x3f; /* ack all interrupts */
-		*usbint = 0; /* disable all interrupts */
-		*usbconf = 0; /* release control of RH ports */
-
-		*usbcmd = 0;
-		/* Wait until hc is halted */
-		while ((*usbsts & USBSTS_HALTED) == 0);
-		usb_log_info("EHCI turned off.\n");
-	} else {
-		usb_log_info("EHCI was not running.\n");
-	}
-	usb_log_debug("Registers: \n"
-	    "\t USBCMD(%p): %x(0x00080000 = at least 1ms between interrupts)\n"
-	    "\t USBSTS(%p): %x(0x00001000 = HC halted)\n"
-	    "\t USBINT(%p): %x(0x0 = no interrupts).\n"
-	    "\t CONFIG(%p): %x(0x0 = ports controlled by companion hc).\n",
-	    usbcmd, *usbcmd, usbsts, *usbsts, usbint, *usbint, usbconf,*usbconf);
-
-	return rc;
+		    str_error(ret));
+		    goto clean;
+	}
+clean:
+	//TODO unmap registers
+	hw_res_list_parsed_clean(&res);
+	async_hangup(parent_sess);
+	return ret;
 }
 
