Index: uspace/drv/bus/usb/ohci/ohci.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci.c	(revision 7de1988cde59f3ad2459d423b31be5ea19d7df75)
+++ uspace/drv/bus/usb/ohci/ohci.c	(revision 952bc668192e6b7eb974e8cbf0c3d5ed0383b87f)
@@ -34,30 +34,23 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
+#include <assert.h>
+#include <errno.h>
+#include <ddf/interrupt.h>
+#include <device/hw_res_parsed.h>
+#include <stdbool.h>
+#include <str_error.h>
+#include <sys/types.h>
 
-#include <errno.h>
-#include <str_error.h>
-#include <ddf/interrupt.h>
-#include <usb_iface.h>
 #include <usb/usb.h>
-#include <usb/ddfiface.h>
 #include <usb/debug.h>
 
+#include <usb/host/ddf_helpers.h>
+#include <usb/host/usb_bus.h>
+
 #include "ohci.h"
-#include "res.h"
+#include "ohci_endpoint.h"
 #include "hc.h"
 
-typedef struct ohci {
-	ddf_fun_t *hc_fun;
-	ddf_fun_t *rh_fun;
 
-	hc_t hc;
-} ohci_t;
-
-static inline ohci_t *dev_to_ohci(ddf_dev_t *dev)
-{
-	return ddf_dev_data_get(dev);
-}
 /** IRQ handling callback, identifies device
  *
@@ -69,64 +62,13 @@
 {
 	assert(dev);
-
-	ohci_t *ohci = dev_to_ohci(dev);
-	if (!ohci) {
+	hcd_t *hcd = dev_to_hcd(dev);
+	if (!hcd || !hcd->driver.data) {
 		usb_log_warning("Interrupt on device that is not ready.\n");
 		return;
 	}
+
 	const uint16_t status = IPC_GET_ARG1(*call);
-	hc_interrupt(&ohci->hc, status);
+	hc_interrupt(hcd->driver.data, status);
 }
-
-/** Get USB address assigned to root hub.
- *
- * @param[in] fun Root hub function.
- * @param[out] address Store the address here.
- * @return Error code.
- */
-static int rh_get_my_address(ddf_fun_t *fun, usb_address_t *address)
-{
-	assert(fun);
-
-	if (address != NULL) {
-		*address = dev_to_ohci(ddf_fun_get_dev(fun))->hc.rh.address;
-	}
-
-	return EOK;
-}
-
-/** Gets handle of the respective hc (this device, hc function).
- *
- * @param[in] root_hub_fun Root hub function seeking hc handle.
- * @param[out] handle Place to write the handle.
- * @return Error code.
- */
-static int rh_get_hc_handle(
-    ddf_fun_t *fun, devman_handle_t *handle)
-{
-	assert(fun);
-	ddf_fun_t *hc_fun = dev_to_ohci(ddf_fun_get_dev(fun))->hc_fun;
-	assert(hc_fun);
-
-	if (handle != NULL)
-		*handle = ddf_fun_get_handle(hc_fun);
-	return EOK;
-}
-
-/** Root hub USB interface */
-static usb_iface_t usb_iface = {
-	.get_hc_handle = rh_get_hc_handle,
-	.get_my_address = rh_get_my_address,
-};
-
-/** Standard USB HC options (HC interface) */
-static ddf_dev_ops_t hc_ops = {
-	.interfaces[USBHC_DEV_IFACE] = &hcd_iface,
-};
-
-/** Standard USB RH options (RH interface) */
-static ddf_dev_ops_t rh_ops = {
-	.interfaces[USB_DEV_IFACE] = &usb_iface,
-};
 
 /** Initialize hc and rh ddf structures and their respective drivers.
@@ -143,70 +85,43 @@
 int device_setup_ohci(ddf_dev_t *device)
 {
-	bool ih_registered = false;
-	bool hc_inited = false;
-	int rc;
-
-	if (device == NULL)
-		return EBADMEM;
-
-	ohci_t *instance = ddf_dev_data_alloc(device,sizeof(ohci_t));
-	if (instance == NULL) {
-		usb_log_error("Failed to allocate OHCI driver.\n");
-		return ENOMEM;
-	}
-
-	instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
-	if (instance->hc_fun == NULL) {
-		usb_log_error("Failed to create OHCI HC function: %s.\n",
-		    str_error(ENOMEM));
-		rc = ENOMEM;
-		goto error;
-	}
-
-	ddf_fun_set_ops(instance->hc_fun, &hc_ops);
-	ddf_fun_data_implant(instance->hc_fun, &instance->hc);
-
-	instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
-	if (instance->rh_fun == NULL) {
-		usb_log_error("Failed to create OHCI RH function: %s.\n",
-		    str_error(ENOMEM));
-		rc = ENOMEM;
-		goto error;
-	}
-
-	ddf_fun_set_ops(instance->rh_fun, &rh_ops);
-
-	addr_range_t regs;
-	int irq = 0;
-
-	rc = get_my_registers(device, &regs, &irq);
-	if (rc != EOK) {
+	hw_res_list_parsed_t hw_res;
+	int ret = hcd_ddf_get_registers(device, &hw_res);
+	if (ret != EOK ||
+	    hw_res.irqs.count != 1 || hw_res.mem_ranges.count != 1) {
 		usb_log_error("Failed to get register memory addresses "
 		    "for %" PRIun ": %s.\n", ddf_dev_get_handle(device),
-		    str_error(rc));
-		goto error;
+		    str_error(ret));
+		return ret;
 	}
+	addr_range_t regs = hw_res.mem_ranges.ranges[0];
+	const int irq = hw_res.irqs.irqs[0];
+	hw_res_list_parsed_clean(&hw_res);
 
 	usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
 	    RNGABSPTR(regs), RNGSZ(regs), irq);
 
-	rc = hc_register_irq_handler(device, &regs, irq, irq_handler);
-	if (rc != EOK) {
-		usb_log_error("Failed to register interrupt handler: %s.\n",
-		    str_error(rc));
-		goto error;
+	/* Initialize generic HCD driver */
+	ret = hcd_ddf_setup_hc(device, USB_SPEED_FULL,
+	    BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
+	if (ret != EOK) {
+		usb_log_error("Failed to setup generic hcd structures: %s.",
+		    str_error(ret));
+		return ret;
 	}
 
-	ih_registered = true;
+	hc_t *hc = malloc(sizeof(hc_t));
+	if (!hc) {
+		usb_log_error("Failed to allocate driver structure.\n");
+		ret = ENOMEM;
+		goto ddf_hc_clean;
+	}
 
 	/* Try to enable interrupts */
 	bool interrupts = false;
-	rc = enable_interrupts(device);
-	if (rc != EOK) {
+	ret = hcd_ddf_setup_interrupts(device, &regs, irq, irq_handler,
+	    hc_gen_irq_code);
+	if (ret != EOK) {
 		usb_log_warning("Failed to enable interrupts: %s."
-		    " Falling back to polling\n", str_error(rc));
-		/* We don't need that handler */
-		unregister_interrupt_handler(device, irq);
-		ih_registered = false;
+		    " Falling back to polling\n", str_error(ret));
 	} else {
 		usb_log_debug("Hw interrupts enabled.\n");
@@ -214,45 +129,28 @@
 	}
 
-	rc = hc_init(&instance->hc, &regs, interrupts);
-	if (rc != EOK) {
-		usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc));
-		goto error;
+	/* Initialize OHCI HC */
+	ret = hc_init(hc, &regs, interrupts);
+	if (ret != EOK) {
+		usb_log_error("Failed to init hc: %s.\n", str_error(ret));
+		goto unregister_irq;
 	}
 
-	hc_inited = true;
+	/* Connect OHCI to generic HCD */
+	hcd_set_implementation(dev_to_hcd(device), hc,
+	    hc_schedule, ohci_endpoint_init, ohci_endpoint_fini);
 
-	rc = ddf_fun_bind(instance->hc_fun);
-	if (rc != EOK) {
-		usb_log_error("Failed to bind OHCI device function: %s.\n",
-		    str_error(rc));
-		goto error;
+	/* HC should be running OK. We can add root hub */
+	ret = hcd_ddf_setup_root_hub(device);
+	if (ret != EOK) {
+		usb_log_error("Failed to register OHCI root hub: %s.\n",
+		    str_error(ret));
+		hc_fini(hc);
+unregister_irq:
+		unregister_interrupt_handler(device, irq);
+		free(hc);
+ddf_hc_clean:
+		hcd_ddf_clean_hc(device);
 	}
-
-	rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
-	if (rc != EOK) {
-		usb_log_error("Failed to add OHCI to HC category: %s.\n",
-		    str_error(rc));
-		goto error;
-	}
-
-	rc = hc_register_hub(&instance->hc, instance->rh_fun);
-	if (rc != EOK) {
-		usb_log_error("Failed to register OHCI root hub: %s.\n",
-		    str_error(rc));
-		goto error;
-	}
-
-	return EOK;
-
-error:
-	if (hc_inited)
-		hc_fini(&instance->hc);
-	if (ih_registered)
-		unregister_interrupt_handler(device, irq);
-	if (instance->hc_fun != NULL)
-		ddf_fun_destroy(instance->hc_fun);
-	if (instance->rh_fun != NULL)
-		ddf_fun_destroy(instance->rh_fun);
-	return rc;
+	return ret;
 }
 /**
