Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision acdb5bacffa0840fa18ced3443b7bcb244837b8d)
+++ uspace/lib/drv/generic/driver.c	(revision 69b264a9735df226a05998fb3c1faab281862562)
@@ -821,4 +821,5 @@
 	assert(fun->bound == false);
 	assert(fun->name != NULL);
+	assert(fun->dev != NULL);
 	
 	add_to_functions_list(fun);
Index: uspace/lib/drv/generic/remote_usb.c
===================================================================
--- uspace/lib/drv/generic/remote_usb.c	(revision acdb5bacffa0840fa18ced3443b7bcb244837b8d)
+++ uspace/lib/drv/generic/remote_usb.c	(revision 69b264a9735df226a05998fb3c1faab281862562)
@@ -35,8 +35,34 @@
 
 #include <async.h>
+#include <macros.h>
 #include <errno.h>
+#include <devman.h>
 
 #include "usb_iface.h"
 #include "ddf/driver.h"
+
+
+usb_dev_session_t *usb_dev_connect(devman_handle_t handle)
+{
+	// TODO All usb requests are atomic so this is safe,
+	// it will need to change once USING EXCHANGE PARALLEL is safe with
+	// devman_device_connect
+	return devman_device_connect(EXCHANGE_ATOMIC, handle, IPC_FLAG_BLOCKING);
+}
+
+usb_dev_session_t *usb_dev_connect_to_self(ddf_dev_t *dev)
+{
+	// TODO All usb requests are atomic so this is safe,
+	// it will need to change once USING EXCHANGE PARALLEL is safe with
+	// devman_parent_device_connect
+	return devman_parent_device_connect(EXCHANGE_ATOMIC,
+	    ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING);
+}
+
+void usb_dev_disconnect(usb_dev_session_t *sess)
+{
+	if (sess)
+		async_hangup(sess);
+}
 
 typedef enum {
@@ -44,4 +70,10 @@
 	IPC_M_USB_GET_MY_INTERFACE,
 	IPC_M_USB_GET_HOST_CONTROLLER_HANDLE,
+	IPC_M_USB_RESERVE_DEFAULT_ADDRESS,
+	IPC_M_USB_RELEASE_DEFAULT_ADDRESS,
+	IPC_M_USB_DEVICE_ENUMERATE,
+	IPC_M_USB_DEVICE_REMOVE,
+	IPC_M_USB_REGISTER_ENDPOINT,
+	IPC_M_USB_UNREGISTER_ENDPOINT,
 } usb_iface_funcs_t;
 
@@ -101,8 +133,93 @@
 }
 
+/** Reserve default USB address.
+ * @param[in] exch IPC communication exchange
+ * @param[in] speed Communication speed of the newly attached device
+ * @return Error code.
+ */
+int usb_reserve_default_address(async_exch_t *exch, usb_speed_t speed)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_RESERVE_DEFAULT_ADDRESS, speed);
+}
+
+/** Release default USB address.
+ * @param[in] exch IPC communication exchange
+ * @return Error code.
+ */
+int usb_release_default_address(async_exch_t *exch)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_1_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_RELEASE_DEFAULT_ADDRESS);
+}
+
+/** Trigger USB device enumeration
+ * @param[in] exch IPC communication exchange
+ * @param[out] handle Identifier of the newly added device (if successful)
+ * @return Error code.
+ */
+int usb_device_enumerate(async_exch_t *exch, usb_device_handle_t *handle)
+{
+	if (!exch || !handle)
+		return EBADMEM;
+	sysarg_t h;
+	const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_DEVICE_ENUMERATE, &h);
+	if (ret == EOK)
+		*handle = (usb_device_handle_t)h;
+	return ret;
+}
+
+/** Trigger USB device enumeration
+ * @param[in] exch IPC communication exchange
+ * @param[in] handle Identifier of the device
+ * @return Error code.
+ */
+int usb_device_remove(async_exch_t *exch, usb_device_handle_t handle)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_DEVICE_REMOVE, handle);
+}
+
+int usb_register_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
+    usb_transfer_type_t type, usb_direction_t direction,
+    size_t mps, unsigned interval)
+{
+	if (!exch)
+		return EBADMEM;
+#define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))
+
+	return async_req_4_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_REGISTER_ENDPOINT, endpoint,
+	    _PACK2(type, direction), _PACK2(mps, interval));
+
+#undef _PACK2
+}
+
+int usb_unregister_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
+    usb_direction_t direction)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_3_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_UNREGISTER_ENDPOINT, endpoint, direction);
+}
 
 static void remote_usb_get_my_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usb_get_my_interface(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usb_get_hc_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+
+static void remote_usb_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_device_enumerate(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_device_remove(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 
 /** Remote USB interface operations. */
@@ -111,4 +228,10 @@
 	[IPC_M_USB_GET_MY_INTERFACE] = remote_usb_get_my_interface,
 	[IPC_M_USB_GET_HOST_CONTROLLER_HANDLE] = remote_usb_get_hc_handle,
+	[IPC_M_USB_RESERVE_DEFAULT_ADDRESS] = remote_usb_reserve_default_address,
+	[IPC_M_USB_RELEASE_DEFAULT_ADDRESS] = remote_usb_release_default_address,
+	[IPC_M_USB_DEVICE_ENUMERATE] = remote_usb_device_enumerate,
+	[IPC_M_USB_DEVICE_REMOVE] = remote_usb_device_remove,
+	[IPC_M_USB_REGISTER_ENDPOINT] = remote_usb_register_endpoint,
+	[IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usb_unregister_endpoint,
 };
 
@@ -116,7 +239,6 @@
  */
 remote_iface_t remote_usb_iface = {
-	.method_count = sizeof(remote_usb_iface_ops) /
-	    sizeof(remote_usb_iface_ops[0]),
-	.methods = remote_usb_iface_ops
+	.method_count = ARRAY_SIZE(remote_usb_iface_ops),
+	.methods = remote_usb_iface_ops,
 };
 
@@ -178,4 +300,117 @@
 	async_answer_1(callid, EOK, (sysarg_t) handle);
 }
+
+void remote_usb_reserve_default_address(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	const usb_iface_t *usb_iface = (usb_iface_t *) iface;
+
+	if (usb_iface->reserve_default_address == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
+	const int ret = usb_iface->reserve_default_address(fun, speed);
+	async_answer_0(callid, ret);
+}
+
+void remote_usb_release_default_address(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	const usb_iface_t *usb_iface = (usb_iface_t *) iface;
+
+	if (usb_iface->release_default_address == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	const int ret = usb_iface->release_default_address(fun);
+	async_answer_0(callid, ret);
+}
+
+static void remote_usb_device_enumerate(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	const usb_iface_t *usb_iface = (usb_iface_t *) iface;
+
+	if (usb_iface->device_enumerate == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	usb_device_handle_t handle = 0;
+	const int ret = usb_iface->device_enumerate(fun, &handle);
+	if (ret != EOK) {
+		async_answer_0(callid, ret);
+	}
+
+	async_answer_1(callid, EOK, (sysarg_t) handle);
+}
+
+static void remote_usb_device_remove(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	const usb_iface_t *usb_iface = (usb_iface_t *) iface;
+
+	if (usb_iface->device_remove == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	usb_device_handle_t handle = DEV_IPC_GET_ARG1(*call);
+	const int ret = usb_iface->device_remove(fun, handle);
+	async_answer_0(callid, ret);
+}
+
+static void remote_usb_register_endpoint(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	usb_iface_t *usb_iface = (usb_iface_t *) iface;
+
+	if (!usb_iface->register_endpoint) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+#define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \
+	type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) >> 16)
+#define _INIT_FROM_LOW_DATA2(type, var, arg_no) \
+	type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) & 0xffff)
+
+	const usb_endpoint_t endpoint = DEV_IPC_GET_ARG1(*call);
+
+	_INIT_FROM_HIGH_DATA2(usb_transfer_type_t, transfer_type, 2);
+	_INIT_FROM_LOW_DATA2(usb_direction_t, direction, 2);
+
+	_INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);
+	_INIT_FROM_LOW_DATA2(unsigned int, interval, 3);
+
+#undef _INIT_FROM_HIGH_DATA2
+#undef _INIT_FROM_LOW_DATA2
+
+	const int ret = usb_iface->register_endpoint(fun, endpoint,
+	    transfer_type, direction, max_packet_size, interval);
+
+	async_answer_0(callid, ret);
+}
+
+static void remote_usb_unregister_endpoint(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	usb_iface_t *usb_iface = (usb_iface_t *) iface;
+
+	if (!usb_iface->unregister_endpoint) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG1(*call);
+	usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG2(*call);
+
+	int rc = usb_iface->unregister_endpoint(fun, endpoint, direction);
+
+	async_answer_0(callid, rc);
+}
 /**
  * @}
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision acdb5bacffa0840fa18ced3443b7bcb244837b8d)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision 69b264a9735df226a05998fb3c1faab281862562)
@@ -84,25 +84,4 @@
  */
 typedef enum {
-	/** Asks for address assignment by host controller.
-	 * Answer:
-	 * - ELIMIT - host controller run out of address
-	 * - EOK - address assigned
-	 * Answer arguments:
-	 * - assigned address
-	 *
-	 * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS.
-	 */
-	IPC_M_USBHC_REQUEST_ADDRESS,
-
-	/** Bind USB address with devman handle.
-	 * Parameters:
-	 * - USB address
-	 * - devman handle
-	 * Answer:
-	 * - EOK - address binded
-	 * - ENOENT - address is not in use
-	 */
-	IPC_M_USBHC_BIND_ADDRESS,
-
 	/** Get handle binded with given USB address.
 	 * Parameters
@@ -113,13 +92,4 @@
 	 */
 	IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
-
-	/** Release address in use.
-	 * Arguments:
-	 * - address to be released
-	 * Answer:
-	 * - ENOENT - address not in use
-	 * - EPERM - trying to release default USB address
-	 */
-	IPC_M_USBHC_RELEASE_ADDRESS,
 
 	/** Register endpoint attributes at host controller.
@@ -161,25 +131,5 @@
 } usbhc_iface_funcs_t;
 
-int usbhc_request_address(async_exch_t *exch, usb_address_t *address,
-    bool strict, usb_speed_t speed)
-{
-	if (!exch || !address)
-		return EBADMEM;
-	sysarg_t new_address;
-	const int ret = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_REQUEST_ADDRESS, *address, strict, speed, &new_address);
-	if (ret == EOK)
-		*address = (usb_address_t)new_address;
-	return ret;
-}
-
-int usbhc_bind_address(async_exch_t *exch, usb_address_t address,
-    devman_handle_t handle)
-{
-	if (!exch)
-		return EBADMEM;
-	return async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_BIND_ADDRESS, address, handle);
-}
+
 
 int usbhc_get_handle(async_exch_t *exch, usb_address_t address,
@@ -196,12 +146,4 @@
 }
 
-int usbhc_release_address(async_exch_t *exch, usb_address_t address)
-{
-	if (!exch)
-		return EBADMEM;
-	return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_RELEASE_ADDRESS, address);
-}
-
 int usbhc_register_endpoint(async_exch_t *exch, usb_address_t address,
     usb_endpoint_t endpoint, usb_transfer_type_t type,
@@ -323,8 +265,5 @@
 
 
-static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -335,7 +274,4 @@
 /** Remote USB host controller interface operations. */
 static remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
-	[IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address,
-	[IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,
-	[IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address,
 	[IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_get_handle,
 
@@ -387,42 +323,4 @@
 }
 
-void remote_usbhc_request_address(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	const usbhc_iface_t *usb_iface = iface;
-
-	if (!usb_iface->request_address) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	usb_address_t address = DEV_IPC_GET_ARG1(*call);
-	const bool strict = DEV_IPC_GET_ARG2(*call);
-	const usb_speed_t speed = DEV_IPC_GET_ARG3(*call);
-
-	const int rc = usb_iface->request_address(fun, &address, strict, speed);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-	} else {
-		async_answer_1(callid, EOK, (sysarg_t) address);
-	}
-}
-
-void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	const usbhc_iface_t *usb_iface = iface;
-
-	if (!usb_iface->bind_address) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
-	const devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call);
-
-	const int ret = usb_iface->bind_address(fun, address, handle);
-	async_answer_0(callid, ret);
-}
 
 void remote_usbhc_get_handle(ddf_fun_t *fun, void *iface,
@@ -447,22 +345,6 @@
 }
 
-void remote_usbhc_release_address(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	const usbhc_iface_t *usb_iface = iface;
-
-	if (!usb_iface->release_address) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
-
-	const int ret = usb_iface->release_address(fun, address);
-	async_answer_0(callid, ret);
-}
-
-static void callback_out(ddf_fun_t *fun,
-    int outcome, void *arg)
+
+static void callback_out(int outcome, void *arg)
 {
 	async_transaction_t *trans = arg;
@@ -473,6 +355,5 @@
 }
 
-static void callback_in(ddf_fun_t *fun,
-    int outcome, size_t actual_size, void *arg)
+static void callback_in(int outcome, size_t actual_size, void *arg)
 {
 	async_transaction_t *trans = (async_transaction_t *)arg;
Index: uspace/lib/drv/include/usb_iface.h
===================================================================
--- uspace/lib/drv/include/usb_iface.h	(revision acdb5bacffa0840fa18ced3443b7bcb244837b8d)
+++ uspace/lib/drv/include/usb_iface.h	(revision 69b264a9735df226a05998fb3c1faab281862562)
@@ -42,7 +42,27 @@
 #include <usb/usb.h>
 
+typedef intptr_t usb_device_handle_t;
+enum {
+	USB_DEVICE_HANDLE_INVALID = -1
+};
+typedef async_sess_t usb_dev_session_t;
+
+usb_dev_session_t *usb_dev_connect(devman_handle_t);
+usb_dev_session_t *usb_dev_connect_to_self(ddf_dev_t *);
+void usb_dev_disconnect(usb_dev_session_t *);
+
 int usb_get_my_address(async_exch_t *, usb_address_t *);
 int usb_get_my_interface(async_exch_t *, int *);
 int usb_get_hc_handle(async_exch_t *, devman_handle_t *);
+
+int usb_reserve_default_address(async_exch_t *, usb_speed_t);
+int usb_release_default_address(async_exch_t *);
+
+int usb_device_enumerate(async_exch_t *, usb_device_handle_t *);
+int usb_device_remove(async_exch_t *, usb_device_handle_t);
+
+int usb_register_endpoint(async_exch_t *, usb_endpoint_t, usb_transfer_type_t,
+    usb_direction_t, size_t, unsigned);
+int usb_unregister_endpoint(async_exch_t *, usb_endpoint_t, usb_direction_t);
 
 /** USB device communication interface. */
@@ -51,4 +71,13 @@
 	int (*get_my_interface)(ddf_fun_t *, int *);
 	int (*get_hc_handle)(ddf_fun_t *, devman_handle_t *);
+
+	int (*reserve_default_address)(ddf_fun_t *, usb_speed_t);
+	int (*release_default_address)(ddf_fun_t *);
+	int (*device_enumerate)(ddf_fun_t *, usb_device_handle_t *);
+	int (*device_remove)(ddf_fun_t *, usb_device_handle_t);
+	int (*register_endpoint)(ddf_fun_t *, usb_endpoint_t,
+	    usb_transfer_type_t, usb_direction_t, size_t, unsigned);
+	int (*unregister_endpoint)(ddf_fun_t *, usb_endpoint_t,
+	    usb_direction_t);
 } usb_iface_t;
 
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision acdb5bacffa0840fa18ced3443b7bcb244837b8d)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision 69b264a9735df226a05998fb3c1faab281862562)
@@ -44,8 +44,5 @@
 #include <stdbool.h>
 
-int usbhc_request_address(async_exch_t *, usb_address_t *, bool, usb_speed_t);
-int usbhc_bind_address(async_exch_t *, usb_address_t, devman_handle_t);
 int usbhc_get_handle(async_exch_t *, usb_address_t, devman_handle_t *);
-int usbhc_release_address(async_exch_t *, usb_address_t);
 int usbhc_register_endpoint(async_exch_t *, usb_address_t, usb_endpoint_t,
     usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
@@ -58,20 +55,14 @@
 
 /** Callback for outgoing transfer. */
-typedef void (*usbhc_iface_transfer_out_callback_t)(ddf_fun_t *, int, void *);
+typedef void (*usbhc_iface_transfer_out_callback_t)(int, void *);
 
 /** Callback for incoming transfer. */
-typedef void (*usbhc_iface_transfer_in_callback_t)(ddf_fun_t *,
-    int, size_t, void *);
+typedef void (*usbhc_iface_transfer_in_callback_t)(int, size_t, void *);
 
 /** USB host controller communication interface. */
 typedef struct {
-	int (*request_address)(ddf_fun_t *, usb_address_t *, bool, usb_speed_t);
-	int (*bind_address)(ddf_fun_t *, usb_address_t, devman_handle_t);
-	int (*get_handle)(ddf_fun_t *, usb_address_t,
-	    devman_handle_t *);
-	int (*release_address)(ddf_fun_t *, usb_address_t);
+	int (*get_handle)(ddf_fun_t *, usb_address_t, devman_handle_t *);
 
-	int (*register_endpoint)(ddf_fun_t *,
-	    usb_address_t, usb_endpoint_t,
+	int (*register_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
 	    usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
 	int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
