Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision e20eaed316ce4d05fbacbcf2391fa52e9fc09c30)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision 620c710af8ea806f074c8dc9ea391400b6b82226)
@@ -61,5 +61,10 @@
 static int hc_init_memory(hc_t *instance);
 static int interrupt_emulator(hc_t *instance);
-
+/*----------------------------------------------------------------------------*/
+static int schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
+{
+	assert(hcd);
+	return hc_schedule(hcd->private_data, batch);
+}
 /*----------------------------------------------------------------------------*/
 /** Get number of commands used in IRQ code.
@@ -163,10 +168,4 @@
 }
 /*----------------------------------------------------------------------------*/
-static int schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
-{
-	assert(hcd);
-	return hc_schedule(hcd->private_data, batch);
-}
-/*----------------------------------------------------------------------------*/
 /** Initialize OHCI hc driver structure
  *
@@ -203,5 +202,5 @@
 	instance->generic.private_data = instance;
 	instance->generic.schedule = schedule;
-	instance->generic.ep_add_hook = ohci_endpoint_assign;
+	instance->generic.ep_add_hook = ohci_endpoint_init;
 
 	ret = hc_init_memory(instance);
@@ -224,4 +223,60 @@
 
 	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep)
+{
+	endpoint_list_t *list = &instance->lists[ep->transfer_type];
+	ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
+	/* Enqueue ep */
+	switch (ep->transfer_type) {
+	case USB_TRANSFER_CONTROL:
+		instance->registers->control &= ~C_CLE;
+		endpoint_list_add_ep(list, ohci_ep);
+		instance->registers->control_current = 0;
+		instance->registers->control |= C_CLE;
+		break;
+	case USB_TRANSFER_BULK:
+		instance->registers->control &= ~C_BLE;
+		endpoint_list_add_ep(
+		    &instance->lists[ep->transfer_type], ohci_endpoint_get(ep));
+		instance->registers->control |= C_BLE;
+		break;
+	case USB_TRANSFER_ISOCHRONOUS:
+	case USB_TRANSFER_INTERRUPT:
+		instance->registers->control &= (~C_PLE & ~C_IE);
+		endpoint_list_add_ep(
+		    &instance->lists[ep->transfer_type], ohci_endpoint_get(ep));
+		instance->registers->control |= C_PLE | C_IE;
+		break;
+	}
+}
+/*----------------------------------------------------------------------------*/
+void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep)
+{
+	/* Dequeue ep */
+	endpoint_list_t *list = &instance->lists[ep->transfer_type];
+	ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
+	switch (ep->transfer_type) {
+	case USB_TRANSFER_CONTROL:
+		instance->registers->control &= ~C_CLE;
+		endpoint_list_remove_ep(list, ohci_ep);
+		instance->registers->control_current = 0;
+		instance->registers->control |= C_CLE;
+		break;
+	case USB_TRANSFER_BULK:
+		instance->registers->control &= ~C_BLE;
+		endpoint_list_remove_ep(list, ohci_ep);
+		instance->registers->control |= C_BLE;
+		break;
+	case USB_TRANSFER_ISOCHRONOUS:
+	case USB_TRANSFER_INTERRUPT:
+		instance->registers->control &= (~C_PLE & ~C_IE);
+		endpoint_list_remove_ep(list, ohci_ep);
+		instance->registers->control |= C_PLE | C_IE;
+		break;
+	default:
+		break;
+	}
 }
 /*----------------------------------------------------------------------------*/
@@ -249,5 +304,5 @@
 		return ENOMEM;
 
-	int ret = ohci_endpoint_assign(&instance->generic, ep);
+	int ret = ohci_endpoint_init(&instance->generic, ep);
 	if (ret != EOK) {
 		endpoint_destroy(ep);
@@ -260,28 +315,5 @@
 		return ret;
 	}
-
-	/* Enqueue ep */
-	switch (ep->transfer_type) {
-	case USB_TRANSFER_CONTROL:
-		instance->registers->control &= ~C_CLE;
-		endpoint_list_add_ep(
-		    &instance->lists[ep->transfer_type], ohci_endpoint_get(ep));
-		instance->registers->control_current = 0;
-		instance->registers->control |= C_CLE;
-		break;
-	case USB_TRANSFER_BULK:
-		instance->registers->control &= ~C_BLE;
-		endpoint_list_add_ep(
-		    &instance->lists[ep->transfer_type], ohci_endpoint_get(ep));
-		instance->registers->control |= C_BLE;
-		break;
-	case USB_TRANSFER_ISOCHRONOUS:
-	case USB_TRANSFER_INTERRUPT:
-		instance->registers->control &= (~C_PLE & ~C_IE);
-		endpoint_list_add_ep(
-		    &instance->lists[ep->transfer_type], ohci_endpoint_get(ep));
-		instance->registers->control |= C_PLE | C_IE;
-		break;
-	}
+	hc_enqueue_endpoint(instance, ep);
 
 	return EOK;
@@ -311,29 +343,5 @@
 	ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
 	if (ohci_ep) {
-		/* Dequeue ep */
-		switch (ep->transfer_type) {
-		case USB_TRANSFER_CONTROL:
-			instance->registers->control &= ~C_CLE;
-			endpoint_list_remove_ep(
-			    &instance->lists[ep->transfer_type], ohci_ep);
-			instance->registers->control_current = 0;
-			instance->registers->control |= C_CLE;
-			break;
-		case USB_TRANSFER_BULK:
-			instance->registers->control &= ~C_BLE;
-			endpoint_list_remove_ep(
-			    &instance->lists[ep->transfer_type], ohci_ep);
-			instance->registers->control |= C_BLE;
-			break;
-		case USB_TRANSFER_ISOCHRONOUS:
-		case USB_TRANSFER_INTERRUPT:
-			instance->registers->control &= (~C_PLE & ~C_IE);
-			endpoint_list_remove_ep(
-			    &instance->lists[ep->transfer_type], ohci_ep);
-			instance->registers->control |= C_PLE | C_IE;
-			break;
-		default:
-			break;
-		}
+		hc_dequeue_endpoint(instance, ep);
 	} else {
 		usb_log_warning("Endpoint without hcd equivalent structure.\n");
Index: uspace/drv/bus/usb/ohci/hc.h
===================================================================
--- uspace/drv/bus/usb/ohci/hc.h	(revision e20eaed316ce4d05fbacbcf2391fa52e9fc09c30)
+++ uspace/drv/bus/usb/ohci/hc.h	(revision 620c710af8ea806f074c8dc9ea391400b6b82226)
@@ -84,6 +84,6 @@
 int hc_get_irq_commands(
     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
+int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
-int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
 
 /** Safely dispose host controller internal structures
@@ -93,4 +93,7 @@
 static inline void hc_fini(hc_t *instance)
 	{ /* TODO: implement*/ };
+
+void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep);
+void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep);
 
 int hc_add_endpoint(hc_t *instance, usb_address_t address, usb_endpoint_t ep,
Index: uspace/drv/bus/usb/ohci/ohci.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci.c	(revision e20eaed316ce4d05fbacbcf2391fa52e9fc09c30)
+++ uspace/drv/bus/usb/ohci/ohci.c	(revision 620c710af8ea806f074c8dc9ea391400b6b82226)
@@ -89,5 +89,5 @@
 {
 	assert(fun);
-	usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager;
+	usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.generic.dev_manager;
 
 	usb_address_t addr = usb_device_keeper_find(manager, handle);
@@ -129,5 +129,5 @@
 /** Standard USB HC options (HC interface) */
 static ddf_dev_ops_t hc_ops = {
-	.interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
+	.interfaces[USBHC_DEV_IFACE] = &hcd_iface,
 };
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/bus/usb/ohci/ohci_endpoint.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_endpoint.c	(revision e20eaed316ce4d05fbacbcf2391fa52e9fc09c30)
+++ uspace/drv/bus/usb/ohci/ohci_endpoint.c	(revision 620c710af8ea806f074c8dc9ea391400b6b82226)
@@ -34,4 +34,5 @@
 #include "utils/malloc32.h"
 #include "ohci_endpoint.h"
+#include "hc.h"
 
 /** Callback to set toggle on ED.
@@ -65,8 +66,9 @@
  * @param[in] hcd_ep endpoint structure
  */
-static void ohci_ep_destroy(void *ohci_ep)
+static void ohci_endpoint_fini(endpoint_t *ep)
 {
-	if (ohci_ep) {
-		ohci_endpoint_t *instance = ohci_ep;
+	ohci_endpoint_t *instance = ep->hc_data.data;
+	hc_dequeue_endpoint(instance->hcd->private_data, ep);
+	if (instance) {
 		free32(instance->ed);
 		free32(instance->td);
@@ -80,5 +82,5 @@
  * @return pointer to a new hcd endpoint structure, NULL on failure.
  */
-int ohci_endpoint_assign(hcd_t *hcd, endpoint_t *ep)
+int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep)
 {
 	assert(ep);
@@ -103,6 +105,7 @@
 	ed_set_td(ohci_ep->ed, ohci_ep->td);
 	endpoint_set_hc_data(
-	    ep, ohci_ep, ohci_ep_destroy, ohci_ep_toggle_get, ohci_ep_toggle_set);
-
+	    ep, ohci_ep, ohci_endpoint_fini, ohci_ep_toggle_get, ohci_ep_toggle_set);
+	ohci_ep->hcd = hcd;
+	hc_enqueue_endpoint(hcd->private_data, ep);
 	return EOK;
 }
Index: uspace/drv/bus/usb/ohci/ohci_endpoint.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_endpoint.h	(revision e20eaed316ce4d05fbacbcf2391fa52e9fc09c30)
+++ uspace/drv/bus/usb/ohci/ohci_endpoint.h	(revision 620c710af8ea806f074c8dc9ea391400b6b82226)
@@ -55,5 +55,5 @@
 } ohci_endpoint_t;
 
-int ohci_endpoint_assign(hcd_t *hcd, endpoint_t *ep);
+int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep);
 
 /** Get and convert assigned ohci_endpoint_t structure
Index: uspace/lib/usbhost/include/usb/host/endpoint.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/endpoint.h	(revision e20eaed316ce4d05fbacbcf2391fa52e9fc09c30)
+++ uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 620c710af8ea806f074c8dc9ea391400b6b82226)
@@ -54,7 +54,7 @@
 	fibril_condvar_t avail;
 	volatile bool active;
+	void (*destroy_hook)(struct endpoint *);
 	struct {
 		void *data;
-		void (*data_dtor)(void*);
 		int (*toggle_get)(void *);
 		void (*toggle_set)(void *, int);
@@ -69,5 +69,5 @@
 
 void endpoint_set_hc_data(endpoint_t *instance,
-    void *data, void (*data_dtor)(void *),
+    void *data, void (*destroy_hook)(endpoint_t *),
     int (*toggle_get)(void *), void (*toggle_set)(void *, int));
 
Index: uspace/lib/usbhost/src/endpoint.c
===================================================================
--- uspace/lib/usbhost/src/endpoint.c	(revision e20eaed316ce4d05fbacbcf2391fa52e9fc09c30)
+++ uspace/lib/usbhost/src/endpoint.c	(revision 620c710af8ea806f074c8dc9ea391400b6b82226)
@@ -53,6 +53,6 @@
 		instance->toggle = 0;
 		instance->active = false;
+		instance->destroy_hook = NULL;
 		instance->hc_data.data = NULL;
-		instance->hc_data.data_dtor = NULL;
 		instance->hc_data.toggle_get = NULL;
 		instance->hc_data.toggle_set = NULL;
@@ -69,6 +69,6 @@
 	assert(!instance->active);
 	if (instance->hc_data.data) {
-		assert(instance->hc_data.data_dtor);
-		instance->hc_data.data_dtor(instance->hc_data.data);
+		assert(instance->destroy_hook);
+		instance->destroy_hook(instance);
 	}
 	free(instance);
@@ -76,10 +76,10 @@
 /*----------------------------------------------------------------------------*/
 void endpoint_set_hc_data(endpoint_t *instance,
-    void *data, void (*data_dtor)(void *),
+    void *data, void (*destroy_hook)(endpoint_t *),
     int (*toggle_get)(void *), void (*toggle_set)(void *, int))
 {
 	assert(instance);
+	instance->destroy_hook = destroy_hook;
 	instance->hc_data.data = data;
-	instance->hc_data.data_dtor = data_dtor;
 	instance->hc_data.toggle_get = toggle_get;
 	instance->hc_data.toggle_set = toggle_set;
