Index: uspace/drv/bus/usb/ehci/main.c
===================================================================
--- uspace/drv/bus/usb/ehci/main.c	(revision 7de1988cde59f3ad2459d423b31be5ea19d7df75)
+++ uspace/drv/bus/usb/ehci/main.c	(revision dc44023a126c400bd80646b282a56f72d8170292)
@@ -33,33 +33,56 @@
  * Main routines of EHCI driver.
  */
-
 #include <ddf/driver.h>
 #include <ddf/interrupt.h>
 #include <device/hw_res.h>
 #include <errno.h>
-#include <stdbool.h>
 #include <str_error.h>
 
 #include <usb_iface.h>
-#include <usb/ddfiface.h>
 #include <usb/debug.h>
-#include <usb/host/hcd.h>
+#include <usb/host/ddf_helpers.h>
 
 #include "res.h"
+#include "hc.h"
+#include "ehci_endpoint.h"
 
 #define NAME "ehci"
 
+static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
+{
+	assert(hcd);
+	assert(hcd->driver.data == NULL);
+
+	hc_t *instance = malloc(sizeof(hc_t));
+	if (!instance)
+		return ENOMEM;
+
+	const int ret = hc_init(instance, res, irq);
+	if (ret == EOK)
+		hcd_set_implementation(hcd, instance, ehci_hc_schedule,
+		    ehci_endpoint_init, ehci_endpoint_fini, ehci_hc_interrupt,
+		    ehci_hc_status);
+	return ret;
+}
+
+static void ehci_driver_fini(hcd_t *hcd)
+{
+	assert(hcd);
+	if (hcd->driver.data)
+		hc_fini(hcd->driver.data);
+
+	free(hcd->driver.data);
+	hcd_set_implementation(hcd, NULL, NULL, NULL, NULL, NULL, NULL);
+}
+
 static int ehci_dev_add(ddf_dev_t *device);
 
-static driver_ops_t ehci_driver_ops = {
+static const driver_ops_t ehci_driver_ops = {
 	.dev_add = ehci_dev_add,
 };
 
-static driver_t ehci_driver = {
+static const driver_t ehci_driver = {
 	.name = NAME,
 	.driver_ops = &ehci_driver_ops
-};
-static ddf_dev_ops_t hc_ops = {
-	.interfaces[USBHC_DEV_IFACE] = &hcd_iface,
 };
 
@@ -72,73 +95,27 @@
 static int ehci_dev_add(ddf_dev_t *device)
 {
-	ddf_fun_t *hc_fun = NULL;
-	bool fun_bound = false;
-
+	usb_log_debug("ehci_dev_add() called\n");
 	assert(device);
 
-	addr_range_t reg_range;
-	int irq = 0;
-
-	int rc = get_my_registers(device, &reg_range, &irq);
-	if (rc != EOK) {
-		usb_log_error("Failed to get memory addresses for %" PRIun
-		    ": %s.\n", ddf_dev_get_handle(device), str_error(rc));
-		goto error;
+	int ret = disable_legacy(device);
+	if (ret != EOK) {
+		usb_log_error("Failed to disable EHCI legacy support: %s\n",
+		    str_error(ret));
+		return ret;
 	}
 
-	usb_log_info("Memory mapped regs at %p (size %zu), IRQ %d.\n",
-	    RNGABSPTR(reg_range), RNGSZ(reg_range), irq);
-
-	rc = disable_legacy(device, &reg_range);
-	if (rc != EOK) {
-		usb_log_error("Failed to disable legacy USB: %s.\n",
-		    str_error(rc));
-		goto error;
+	ret = ddf_hcd_device_setup_all(device, USB_SPEED_HIGH,
+	    BANDWIDTH_AVAILABLE_USB20, bandwidth_count_usb11,
+	    ddf_hcd_gen_irq_handler, ehci_hc_gen_irq_code,
+	    ehci_driver_init, ehci_driver_fini);
+	if (ret != EOK) {
+		usb_log_error("Failed to initialize EHCI driver: %s.\n",
+		    str_error(ret));
+		return ret;
 	}
-
-	hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
-	if (hc_fun == NULL) {
-		usb_log_error("Failed to create EHCI function.\n");
-		rc = ENOMEM;
-		goto error;
-	}
-
-	hcd_t *ehci_hc = ddf_fun_data_alloc(hc_fun, sizeof(hcd_t));
-	if (ehci_hc == NULL) {
-		usb_log_error("Failed to alloc generic HC driver.\n");
-		rc = ENOMEM;
-		goto error;
-	}
-
-	/* High Speed, no bandwidth */
-	hcd_init(ehci_hc, USB_SPEED_HIGH, 0, NULL);
-	ddf_fun_set_ops(hc_fun,  &hc_ops);
-
-	rc = ddf_fun_bind(hc_fun);
-	if (rc != EOK) {
-		usb_log_error("Failed to bind EHCI function: %s.\n",
-		    str_error(rc));
-		goto error;
-	}
-
-	fun_bound = true;
-
-	rc = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY);
-	if (rc != EOK) {
-		usb_log_error("Failed to add EHCI to HC class: %s.\n",
-		    str_error(rc));
-		goto error;
-	}
-
-	usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
-	    ddf_dev_get_name(device), ddf_dev_get_handle(device));
+	usb_log_info("Controlling new EHCI device '%s'.\n",
+	    ddf_dev_get_name(device));
 
 	return EOK;
-error:
-	if (fun_bound)
-		ddf_fun_unbind(hc_fun);
-	if (hc_fun != NULL)
-		ddf_fun_destroy(hc_fun);
-	return rc;
 }
 
