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 57e06ef438456990c2fdcdff3e56ebd1b0fa0c97)
@@ -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 57e06ef438456990c2fdcdff3e56ebd1b0fa0c97)
@@ -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 57e06ef438456990c2fdcdff3e56ebd1b0fa0c97)
@@ -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 57e06ef438456990c2fdcdff3e56ebd1b0fa0c97)
@@ -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 57e06ef438456990c2fdcdff3e56ebd1b0fa0c97)
@@ -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 57e06ef438456990c2fdcdff3e56ebd1b0fa0c97)
@@ -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;
+}
