Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -142,6 +142,7 @@
 if (ret != EOK) { \
 	usb_log_error(message); \
-	usb_endpoint_manager_unregister_ep( \
-	    &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH);\
+	usb_endpoint_manager_remove_ep( \
+	    &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, \
+	    NULL, NULL);\
 	usb_device_manager_release( \
 	    &instance->generic.dev_manager, hub_address); \
@@ -150,5 +151,5 @@
 	int ret = usb_endpoint_manager_add_ep(
 	    &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH,
-	    USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0);
+	    USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0, NULL, NULL);
 	CHECK_RET_UNREG_RETURN(ret,
 	    "Failed to register root hub control endpoint: %s.\n",
@@ -197,4 +198,5 @@
 	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/ohci_endpoint.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_endpoint.c	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/drv/bus/usb/ohci/ohci_endpoint.c	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -62,19 +62,4 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Disposes hcd endpoint structure
- *
- * @param[in] hcd_ep endpoint structure
- */
-static void ohci_endpoint_fini(endpoint_t *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);
-		free(instance);
-	}
-}
-/*----------------------------------------------------------------------------*/
 /** Creates new hcd endpoint representation.
  *
@@ -104,9 +89,27 @@
 	ed_init(ohci_ep->ed, ep, ohci_ep->td);
 	endpoint_set_hc_data(
-	    ep, ohci_ep, ohci_endpoint_fini, ohci_ep_toggle_get, ohci_ep_toggle_set);
+	    ep, ohci_ep, ohci_ep_toggle_get, ohci_ep_toggle_set);
 	ohci_ep->hcd = hcd;
 	hc_enqueue_endpoint(hcd->private_data, ep);
 	return EOK;
 }
+/*----------------------------------------------------------------------------*/
+/** Disposes hcd endpoint structure
+ *
+ * @param[in] hcd_ep endpoint structure
+ */
+void ohci_endpoint_fini(hcd_t *hcd, endpoint_t *ep)
+{
+	assert(hcd);
+	assert(ep);
+	ohci_endpoint_t *instance = ohci_endpoint_get(ep);
+	hc_dequeue_endpoint(hcd->private_data, ep);
+	if (instance) {
+		free32(instance->ed);
+		free32(instance->td);
+		free(instance);
+	}
+	endpoint_clear_hc_data(ep);
+}
 /**
  * @}
Index: uspace/drv/bus/usb/ohci/ohci_endpoint.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_endpoint.h	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/drv/bus/usb/ohci/ohci_endpoint.h	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -56,4 +56,5 @@
 
 int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep);
+void ohci_endpoint_fini(hcd_t *hcd, endpoint_t *ep);
 
 /** Get and convert assigned ohci_endpoint_t structure
Index: uspace/drv/bus/usb/vhc/connhost.c
===================================================================
--- uspace/drv/bus/usb/vhc/connhost.c	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/drv/bus/usb/vhc/connhost.c	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -140,20 +140,10 @@
     size_t max_packet_size, unsigned int interval)
 {
-	/* TODO: Use usb_endpoint_manager_add_ep */
-	VHC_DATA(vhc, fun);
-
-	endpoint_t *ep = endpoint_create(
-	    address, endpoint, direction, transfer_type, USB_SPEED_FULL, 1, 0);
-	if (ep == NULL) {
-		return ENOMEM;
-	}
-
-	int rc = usb_endpoint_manager_register_ep(&vhc->ep_manager, ep, 1);
-	if (rc != EOK) {
-		endpoint_destroy(ep);
-		return rc;
-	}
-
-	return EOK;
+	VHC_DATA(vhc, fun);
+
+	return usb_endpoint_manager_add_ep(&vhc->ep_manager,
+	    address, endpoint, direction, transfer_type, USB_SPEED_FULL, 1, 0,
+	    NULL, NULL);
+
 }
 
@@ -171,6 +161,6 @@
 	VHC_DATA(vhc, fun);
 
-	int rc = usb_endpoint_manager_unregister_ep(&vhc->ep_manager,
-	    address, endpoint, direction);
+	int rc = usb_endpoint_manager_remove_ep(&vhc->ep_manager,
+	    address, endpoint, direction, NULL, NULL);
 
 	return rc;
@@ -413,5 +403,5 @@
 	VHC_DATA(vhc, fun);
 
-	endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager,
+	endpoint_t *ep = usb_endpoint_manager_find_ep(&vhc->ep_manager,
 	    target.address, target.endpoint, USB_DIRECTION_IN);
 	if (ep == NULL) {
@@ -455,5 +445,5 @@
 	VHC_DATA(vhc, fun);
 
-	endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager,
+	endpoint_t *ep = usb_endpoint_manager_find_ep(&vhc->ep_manager,
 	    target.address, target.endpoint, USB_DIRECTION_OUT);
 	if (ep == NULL) {
Index: uspace/lib/usbhost/include/usb/host/endpoint.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -54,5 +54,4 @@
 	fibril_condvar_t avail;
 	volatile bool active;
-	void (*destroy_hook)(struct endpoint *);
 	struct {
 		void *data;
@@ -68,6 +67,5 @@
 
 void endpoint_set_hc_data(endpoint_t *instance,
-    void *data, void (*destroy_hook)(endpoint_t *),
-    int (*toggle_get)(void *), void (*toggle_set)(void *, int));
+    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int));
 void endpoint_clear_hc_data(endpoint_t *instance);
 
Index: uspace/lib/usbhost/include/usb/host/hcd.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/hcd.h	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/lib/usbhost/include/usb/host/hcd.h	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -51,4 +51,5 @@
 	int (*schedule)(hcd_t *, usb_transfer_batch_t *);
 	int (*ep_add_hook)(hcd_t *, endpoint_t *);
+	void (*ep_remove_hook)(hcd_t *, endpoint_t *);
 };
 /*----------------------------------------------------------------------------*/
@@ -65,5 +66,5 @@
 {
 	assert(hcd);
-	usb_endpoint_manager_reset_if_need(
+	usb_endpoint_manager_reset_eps_if_need(
 	    &hcd->ep_manager, target, (const uint8_t *)setup_data);
 }
Index: uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -64,43 +64,24 @@
     size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t));
 
-void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance);
+void usb_endpoint_manager_reset_eps_if_need(
+    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data);
 
-int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
-    endpoint_t *ep, size_t data_size);
-
-int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
+int usb_endpoint_manager_register_ep(
+    usb_endpoint_manager_t *instance, endpoint_t *ep, size_t data_size);
+int usb_endpoint_manager_unregister_ep(
+    usb_endpoint_manager_t *instance, endpoint_t *ep);
+endpoint_t * usb_endpoint_manager_find_ep(usb_endpoint_manager_t *instance,
     usb_address_t address, usb_endpoint_t ep, usb_direction_t direction);
 
-endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
-    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction);
-
-void usb_endpoint_manager_reset_if_need(
-    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data);
-
-/** Wrapper combining allocation and insertion */
-static inline int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
+int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
     usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
     usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
-    size_t data_size)
-{
-	assert(instance);
-	const size_t bw =
-	    instance->bw_count(speed, type, data_size, max_packet_size);
+    size_t data_size, int (*callback)(endpoint_t *, void *), void *arg);
 
-	endpoint_t *ep = endpoint_create(
-	    address, endpoint, direction, type, speed, max_packet_size, bw);
-	if (!ep)
-		return ENOMEM;
-
-	const int ret =
-	    usb_endpoint_manager_register_ep(instance, ep, data_size);
-	if (ret != EOK) {
-		endpoint_destroy(ep);
-	}
-	return ret;
-}
+int usb_endpoint_manager_remove_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
+    void (*callback)(endpoint_t *, void *), void *arg);
 #endif
 /**
  * @}
  */
-
Index: uspace/lib/usbhost/src/endpoint.c
===================================================================
--- uspace/lib/usbhost/src/endpoint.c	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/lib/usbhost/src/endpoint.c	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -54,5 +54,4 @@
 		instance->toggle = 0;
 		instance->active = false;
-		instance->destroy_hook = NULL;
 		instance->hc_data.data = NULL;
 		instance->hc_data.toggle_get = NULL;
@@ -70,17 +69,12 @@
 	assert(instance);
 	assert(!instance->active);
-	if (instance->hc_data.data) {
-		assert(instance->destroy_hook);
-		instance->destroy_hook(instance);
-	}
+	assert(instance->hc_data.data == NULL);
 	free(instance);
 }
 /*----------------------------------------------------------------------------*/
 void endpoint_set_hc_data(endpoint_t *instance,
-    void *data, void (*destroy_hook)(endpoint_t *),
-    int (*toggle_get)(void *), void (*toggle_set)(void *, int))
+    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int))
 {
 	assert(instance);
-	instance->destroy_hook = destroy_hook;
 	instance->hc_data.data = data;
 	instance->hc_data.toggle_get = toggle_get;
@@ -91,5 +85,4 @@
 {
 	assert(instance);
-	instance->destroy_hook = NULL;
 	instance->hc_data.data = NULL;
 	instance->hc_data.toggle_get = NULL;
Index: uspace/lib/usbhost/src/iface.c
===================================================================
--- uspace/lib/usbhost/src/iface.c	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/lib/usbhost/src/iface.c	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -49,5 +49,5 @@
 	assert(hcd);
 
-	endpoint_t *ep = usb_endpoint_manager_get_ep(&hcd->ep_manager,
+	endpoint_t *ep = usb_endpoint_manager_find_ep(&hcd->ep_manager,
 	    target.address, target.endpoint, direction);
 	if (ep == NULL) {
@@ -165,4 +165,23 @@
 }
 /*----------------------------------------------------------------------------*/
+static int register_helper(endpoint_t *ep, void *arg)
+{
+	hcd_t *hcd = arg;
+	assert(ep);
+	assert(hcd);
+	if (hcd->ep_add_hook)
+		return hcd->ep_add_hook(hcd, ep);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+static void unregister_helper(endpoint_t *ep, void *arg)
+{
+	hcd_t *hcd = arg;
+	assert(ep);
+	assert(hcd);
+	if (hcd->ep_remove_hook)
+		hcd->ep_remove_hook(hcd, ep);
+}
+/*----------------------------------------------------------------------------*/
 static int register_endpoint(
     ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
@@ -188,24 +207,7 @@
 	    max_packet_size, interval);
 
-	endpoint_t *ep =
-	    endpoint_create(address, endpoint, direction, transfer_type,
-	        speed, max_packet_size, 0);
-	if (!ep)
-		return ENOMEM;
-
-	if (hcd->ep_add_hook) {
-		const int ret = hcd->ep_add_hook(hcd, ep);
-		if (ret != EOK) {
-			endpoint_destroy(ep);
-			return ret;
-		}
-	}
-
-	const int ret =
-	    usb_endpoint_manager_register_ep(&hcd->ep_manager, ep, size);
-	if (ret != EOK) {
-		endpoint_destroy(ep);
-	}
-	return ret;
+	return usb_endpoint_manager_add_ep(&hcd->ep_manager, address, endpoint,
+	    direction, transfer_type, speed, max_packet_size, size,
+	    register_helper, hcd);
 }
 /*----------------------------------------------------------------------------*/
@@ -219,6 +221,6 @@
 	usb_log_debug("Unregister endpoint %d:%d %s.\n",
 	    address, endpoint, usb_str_direction(direction));
-	return usb_endpoint_manager_unregister_ep(&hcd->ep_manager, address,
-	    endpoint, direction);
+	return usb_endpoint_manager_remove_ep(&hcd->ep_manager, address,
+	    endpoint, direction, unregister_helper, hcd);
 }
 /*----------------------------------------------------------------------------*/
Index: uspace/lib/usbhost/src/usb_endpoint_manager.c
===================================================================
--- uspace/lib/usbhost/src/usb_endpoint_manager.c	(revision 726555872772a00f6886dddce7eea7232189c06e)
+++ uspace/lib/usbhost/src/usb_endpoint_manager.c	(revision 48ae3ef60beee610cc95a4e34ea78d76a44715e0)
@@ -120,64 +120,4 @@
 }
 /*----------------------------------------------------------------------------*/
-int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
-    endpoint_t *ep, size_t data_size)
-{
-	assert(instance);
-	assert(instance->bw_count);
-	assert(ep);
-	ep->bandwidth = instance->bw_count(ep->speed, ep->transfer_type,
-	    data_size, ep->max_packet_size);
-
-	fibril_mutex_lock(&instance->guard);
-
-	if (ep->bandwidth > instance->free_bw) {
-		fibril_mutex_unlock(&instance->guard);
-		return ENOSPC;
-	}
-
-	/* Check for existence */
-	const endpoint_t *endpoint =
-	    find_locked(instance, ep->address, ep->endpoint, ep->direction);
-	if (endpoint != NULL) {
-		fibril_mutex_unlock(&instance->guard);
-		return EEXISTS;
-	}
-	list_t *list = get_list(instance, ep->address);
-	list_append(&ep->link, list);
-
-	instance->free_bw -= ep->bandwidth;
-	fibril_mutex_unlock(&instance->guard);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
-    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
-{
-	assert(instance);
-
-	fibril_mutex_lock(&instance->guard);
-	endpoint_t *ep = find_locked(instance, address, endpoint, direction);
-	if (ep != NULL) {
-		list_remove(&ep->link);
-		instance->free_bw += ep->bandwidth;
-	}
-
-	fibril_mutex_unlock(&instance->guard);
-	endpoint_destroy(ep);
-	return (ep != NULL) ? EOK : EINVAL;
-}
-/*----------------------------------------------------------------------------*/
-endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
-    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
-{
-	assert(instance);
-
-	fibril_mutex_lock(&instance->guard);
-	endpoint_t *ep = find_locked(instance, address, endpoint, direction);
-	fibril_mutex_unlock(&instance->guard);
-
-	return ep;
-}
-/*----------------------------------------------------------------------------*/
 /** Check setup packet data for signs of toggle reset.
  *
@@ -188,5 +128,5 @@
  * Really ugly one.
  */
-void usb_endpoint_manager_reset_if_need(
+void usb_endpoint_manager_reset_eps_if_need(
     usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data)
 {
@@ -234,2 +174,106 @@
 	}
 }
+/*----------------------------------------------------------------------------*/
+int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
+    endpoint_t *ep, size_t data_size)
+{
+	assert(instance);
+	assert(instance->bw_count);
+	assert(ep);
+	fibril_mutex_lock(&instance->guard);
+
+	if (ep->bandwidth > instance->free_bw) {
+		fibril_mutex_unlock(&instance->guard);
+		return ENOSPC;
+	}
+
+	/* Check for existence */
+	const endpoint_t *endpoint =
+	    find_locked(instance, ep->address, ep->endpoint, ep->direction);
+	if (endpoint != NULL) {
+		fibril_mutex_unlock(&instance->guard);
+		return EEXISTS;
+	}
+	list_t *list = get_list(instance, ep->address);
+	list_append(&ep->link, list);
+
+	instance->free_bw -= ep->bandwidth;
+	fibril_mutex_unlock(&instance->guard);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+int usb_endpoint_manager_unregister_ep(
+    usb_endpoint_manager_t *instance, endpoint_t *ep)
+{
+	assert(instance);
+	if (ep == NULL)
+		return ENOENT;
+	fibril_mutex_lock(&instance->guard);
+	list_remove(&ep->link);
+	fibril_mutex_unlock(&instance->guard);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+endpoint_t * usb_endpoint_manager_find_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
+{
+	assert(instance);
+
+	fibril_mutex_lock(&instance->guard);
+	endpoint_t *ep = find_locked(instance, address, endpoint, direction);
+	fibril_mutex_unlock(&instance->guard);
+
+	return ep;
+}
+/*----------------------------------------------------------------------------*/
+int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
+    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
+    size_t data_size, int (*callback)(endpoint_t *, void *), void *arg)
+{
+	assert(instance);
+	const size_t bw =
+	    instance->bw_count(speed, type, data_size, max_packet_size);
+
+	endpoint_t *ep = endpoint_create(
+	    address, endpoint, direction, type, speed, max_packet_size, bw);
+	if (!ep)
+		return ENOMEM;
+
+	if (callback) {
+		const int ret = callback(ep, arg);
+		if (ret != EOK) {
+			endpoint_destroy(ep);
+			return ret;
+		}
+	}
+
+	const int ret =
+	    usb_endpoint_manager_register_ep(instance, ep, data_size);
+	if (ret != EOK) {
+		endpoint_destroy(ep);
+	}
+	return ret;
+}
+/*----------------------------------------------------------------------------*/
+int usb_endpoint_manager_remove_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
+    void (*callback)(endpoint_t *, void *), void *arg)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+	endpoint_t *ep = find_locked(instance, address, endpoint, direction);
+	if (ep != NULL) {
+		list_remove(&ep->link);
+		instance->free_bw += ep->bandwidth;
+	}
+	fibril_mutex_unlock(&instance->guard);
+	if (ep == NULL)
+		return ENOENT;
+
+	if (callback) {
+		callback(ep, arg);
+	}
+	endpoint_destroy(ep);
+	return EOK;
+}
