Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 8de2cca8110ed56b2ed8065d0aa05dfbafd5e24c)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision f51587f5d5527851856fd126b17879a99946e1bb)
@@ -88,5 +88,4 @@
 static int hc_init_memory(hc_t *instance);
 static int interrupt_emulator(hc_t *instance);
-static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
 
 /** Get number of PIO ranges used in IRQ code.
@@ -161,11 +160,4 @@
 
 	list_initialize(&instance->pending_batches);
-
-	hcd_init(&instance->generic, USB_SPEED_FULL,
-	    BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
-	instance->generic.private_data = instance;
-	instance->generic.schedule = hc_schedule;
-	instance->generic.ep_add_hook = ohci_endpoint_init;
-	instance->generic.ep_remove_hook = ohci_endpoint_fini;
 
 	ret = hc_init_memory(instance);
Index: uspace/drv/bus/usb/ohci/hc.h
===================================================================
--- uspace/drv/bus/usb/ohci/hc.h	(revision 8de2cca8110ed56b2ed8065d0aa05dfbafd5e24c)
+++ uspace/drv/bus/usb/ohci/hc.h	(revision f51587f5d5527851856fd126b17879a99946e1bb)
@@ -89,4 +89,5 @@
 void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep);
 void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep);
+int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
 
 void hc_interrupt(hc_t *instance, uint32_t status);
Index: uspace/drv/bus/usb/ohci/ohci.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci.c	(revision 8de2cca8110ed56b2ed8065d0aa05dfbafd5e24c)
+++ uspace/drv/bus/usb/ohci/ohci.c	(revision f51587f5d5527851856fd126b17879a99946e1bb)
@@ -56,4 +56,24 @@
 }
 
+static inline hcd_t *dev_to_hcd(ddf_dev_t *dev)
+{
+	ohci_t *ohci = dev_to_ohci(dev);
+	if (!ohci || !ohci->hc_fun) {
+		usb_log_error("Invalid OHCI device.\n");
+		return NULL;
+	}
+	return ddf_fun_data_get(ohci->hc_fun);
+}
+
+static inline hc_t * dev_to_hc(ddf_dev_t *dev)
+{
+	hcd_t *hcd = dev_to_hcd(dev);
+	if (!hcd) {
+		usb_log_error("Invalid OHCI HCD");
+		return NULL;
+	}
+	return hcd->private_data;
+}
+
 /** IRQ handling callback, identifies device
  *
@@ -65,12 +85,9 @@
 {
 	assert(dev);
-
-	ohci_t *ohci = dev_to_ohci(dev);
-	if (!ohci) {
+	hc_t *hc = dev_to_hc(dev);
+	if (!hc) {
 		usb_log_warning("Interrupt on device that is not ready.\n");
 		return;
 	}
-	hc_t *hc = ddf_fun_data_get(ohci->hc_fun);
-	assert(hc);
 
 	const uint16_t status = IPC_GET_ARG1(*call);
@@ -89,6 +106,5 @@
 
 	if (address != NULL) {
-		hc_t *hc =
-		    ddf_fun_data_get(dev_to_ohci(ddf_fun_get_dev(fun))->hc_fun);
+		hc_t *hc = dev_to_hc(ddf_fun_get_dev(fun));
 		assert(hc);
 		*address = hc->rh.address;
@@ -176,4 +192,7 @@
 	    "Failed to allocate HCD structure: %s.\n", str_error(ret));
 
+	hcd_init(&hc->generic, USB_SPEED_FULL,
+	    BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
+
 	instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
 	ret = instance->rh_fun ? EOK : ENOMEM;
@@ -232,4 +251,7 @@
 	    "Failed to init ohci_hcd: %s.\n", str_error(ret));
 
+	hcd_set_implementation(&hc->generic, hc, hc_schedule,
+	    ohci_endpoint_init, ohci_endpoint_fini);
+
 #define CHECK_RET_FINI_RETURN(ret, message...) \
 if (ret != EOK) { \
