Index: uspace/drv/ehci-hcd/hc_iface.c
===================================================================
--- uspace/drv/ehci-hcd/hc_iface.c	(revision 7b71589214d277bc89e2dc6a413210eead6776df)
+++ uspace/drv/ehci-hcd/hc_iface.c	(revision a9d67aa466df883d1cd0d12261cae57a88fbc88e)
@@ -123,4 +123,5 @@
  * @param[in] fun Device function the action was invoked on.
  * @param[in] address USB address of the device.
+ * @param[in] speed Endpoint speed (invalid means to use device one).
  * @param[in] endpoint Endpoint number.
  * @param[in] transfer_type USB transfer type.
@@ -131,5 +132,5 @@
  */
 static int register_endpoint(ddf_fun_t *fun,
-    usb_address_t address, usb_endpoint_t endpoint,
+    usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
     usb_transfer_type_t transfer_type, usb_direction_t direction,
     size_t max_packet_size, unsigned int interval)
@@ -165,5 +166,4 @@
  * @param[in] fun Device function the action was invoked on.
  * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] max_packet_size Max packet size for the transfer.
  * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
  *	by the caller).
@@ -174,5 +174,5 @@
  */
 static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size, void *data, size_t size,
+    void *data, size_t size,
     usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
@@ -191,5 +191,4 @@
  * @param[in] fun Device function the action was invoked on.
  * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] max_packet_size Max packet size for the transfer.
  * @param[in] data Buffer where to store the data (in USB endianess,
  *	allocated and deallocated by the caller).
@@ -200,5 +199,5 @@
  */
 static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size, void *data, size_t size,
+    void *data, size_t size,
     usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
@@ -217,5 +216,4 @@
  * @param[in] fun Device function the action was invoked on.
  * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] max_packet_size Max packet size for the transfer.
  * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
  *	by the caller).
@@ -226,5 +224,5 @@
  */
 static int bulk_out(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size, void *data, size_t size,
+    void *data, size_t size,
     usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
@@ -243,5 +241,4 @@
  * @param[in] fun Device function the action was invoked on.
  * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] max_packet_size Max packet size for the transfer.
  * @param[in] data Buffer where to store the data (in USB endianess,
  *	allocated and deallocated by the caller).
@@ -252,5 +249,5 @@
  */
 static int bulk_in(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size, void *data, size_t size,
+    void *data, size_t size,
     usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
@@ -269,5 +266,4 @@
  * @param[in] fun Device function the action was invoked on.
  * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] max_packet_size Max packet size for the transfer.
  * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
  *	and deallocated by the caller).
@@ -281,5 +277,4 @@
  */
 static int control_write(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size,
     void *setup_packet, size_t setup_packet_size,
     void *data_buffer, size_t data_buffer_size,
@@ -300,5 +295,4 @@
  * @param[in] fun Device function the action was invoked on.
  * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] max_packet_size Max packet size for the transfer.
  * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
  *	and deallocated by the caller).
@@ -312,5 +306,4 @@
  */
 static int control_read(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size,
     void *setup_packet, size_t setup_packet_size,
     void *data_buffer, size_t data_buffer_size,
Index: uspace/drv/ohci/iface.c
===================================================================
--- uspace/drv/ohci/iface.c	(revision 7b71589214d277bc89e2dc6a413210eead6776df)
+++ uspace/drv/ohci/iface.c	(revision a9d67aa466df883d1cd0d12261cae57a88fbc88e)
@@ -197,6 +197,18 @@
 }
 /*----------------------------------------------------------------------------*/
-static int register_endpoint(
-    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
+/** Register endpoint for bandwidth reservation.
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] address USB address of the device.
+ * @param[in] ep_speed Endpoint speed (invalid means to use device one).
+ * @param[in] endpoint Endpoint number.
+ * @param[in] transfer_type USB transfer type.
+ * @param[in] direction Endpoint data direction.
+ * @param[in] max_packet_size Max packet size of the endpoint.
+ * @param[in] interval Polling interval.
+ * @return Error code.
+ */
+static int register_endpoint(ddf_fun_t *fun,
+    usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint,
     usb_transfer_type_t transfer_type, usb_direction_t direction,
     size_t max_packet_size, unsigned int interval)
@@ -204,6 +216,10 @@
 	hc_t *hc = fun_to_hc(fun);
 	assert(hc);
-	const usb_speed_t speed =
-	    usb_device_keeper_get_speed(&hc->manager, address);
+	if (address == hc->rh.address)
+		return EOK;
+	usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
+	if (speed >= USB_SPEED_MAX) {
+		speed = ep_speed;
+	}
 	const size_t size =
 	    (transfer_type == USB_TRANSFER_INTERRUPT
@@ -243,21 +259,31 @@
 	usb_log_debug("Unregister endpoint %d:%d %d.\n",
 	    address, endpoint, direction);
+	endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
+	    address, endpoint, direction, NULL);
+	if (ep != NULL) {
+		usb_device_keeper_del_ep(&hc->manager, address, ep);
+	}
 	return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
 	    endpoint, direction);
 }
 /*----------------------------------------------------------------------------*/
-/** Interrupt out transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts
- * @param[in] data Source of data.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion
- * @param[in] arg Additional for callback function.
+/** Schedule interrupt out transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
+ *	by the caller).
+ * @param[in] size Size of the @p data buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
  * @return Error code.
  */
 static int interrupt_out(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
+    ddf_fun_t *fun, usb_target_t target, void *data,
     size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
@@ -276,17 +302,22 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Interrupt in transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts
- * @param[out] data Data destination.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion
- * @param[in] arg Additional for callback function.
+/** Schedule interrupt in transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] data Buffer where to store the data (in USB endianess,
+ *	allocated and deallocated by the caller).
+ * @param[in] size Size of the @p data buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
  * @return Error code.
  */
 static int interrupt_in(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
+    ddf_fun_t *fun, usb_target_t target, void *data,
     size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
@@ -305,17 +336,22 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Bulk out transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts
- * @param[in] data Source of data.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion
- * @param[in] arg Additional for callback function.
+/** Schedule bulk out transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
+ *	by the caller).
+ * @param[in] size Size of the @p data buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
  * @return Error code.
  */
 static int bulk_out(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
+    ddf_fun_t *fun, usb_target_t target, void *data,
     size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
@@ -334,17 +370,22 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Bulk in transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts
- * @param[out] data Data destination.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion
- * @param[in] arg Additional for callback function.
+/** Schedule bulk in transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] data Buffer where to store the data (in USB endianess,
+ *	allocated and deallocated by the caller).
+ * @param[in] size Size of the @p data buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
  * @return Error code.
  */
 static int bulk_in(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
+    ddf_fun_t *fun, usb_target_t target, void *data,
     size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
@@ -363,19 +404,25 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Control write transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts.
- * @param[in] setup_data Data to send with SETUP transfer.
- * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
- * @param[in] data Source of data.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion.
- * @param[in] arg Additional for callback function.
+/** Schedule control write transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
+ *	and deallocated by the caller).
+ * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
+ * @param[in] data_buffer Data buffer (in USB endianess, allocated and
+ *	deallocated by the caller).
+ * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
  * @return Error code.
  */
 static int control_write(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
+    ddf_fun_t *fun, usb_target_t target,
     void *setup_data, size_t setup_size, void *data, size_t size,
     usbhc_iface_transfer_out_callback_t callback, void *arg)
@@ -397,19 +444,25 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Control read transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts.
- * @param[in] setup_data Data to send with SETUP packet.
- * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
- * @param[out] data Source of data.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion.
- * @param[in] arg Additional for callback function.
+/** Schedule control read transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
+ *	and deallocated by the caller).
+ * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
+ * @param[in] data_buffer Buffer where to store the data (in USB endianess,
+ *	allocated and deallocated by the caller).
+ * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
  * @return Error code.
  */
 static int control_read(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
+    ddf_fun_t *fun, usb_target_t target,
     void *setup_data, size_t setup_size, void *data, size_t size,
     usbhc_iface_transfer_in_callback_t callback, void *arg)
Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision 7b71589214d277bc89e2dc6a413210eead6776df)
+++ uspace/drv/uhci-hcd/iface.c	(revision a9d67aa466df883d1cd0d12261cae57a88fbc88e)
@@ -74,6 +74,6 @@
 	    name, target.address, target.endpoint, size, ep->max_packet_size);
 
-	assert(ep->speed ==
-	    usb_device_keeper_get_speed(&(*hc)->manager, target.address));
+//	assert(ep->speed ==
+//	    usb_device_keeper_get_speed(&(*hc)->manager, target.address));
 //	assert(ep->max_packet_size == max_packet_size);
 //	assert(ep->transfer_type == USB_TRANSFER_CONTROL);
@@ -198,5 +198,6 @@
 /*----------------------------------------------------------------------------*/
 static int register_endpoint(
-    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
+    ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
+    usb_endpoint_t endpoint,
     usb_transfer_type_t transfer_type, usb_direction_t direction,
     size_t max_packet_size, unsigned int interval)
@@ -204,7 +205,12 @@
 	hc_t *hc = fun_to_hc(fun);
 	assert(hc);
-	const usb_speed_t speed =
-	    usb_device_keeper_get_speed(&hc->manager, address);
-	const size_t size = max_packet_size;
+	usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
+	if (speed >= USB_SPEED_MAX) {
+		speed = ep_speed;
+	}
+	const size_t size =
+	    (transfer_type == USB_TRANSFER_INTERRUPT
+	    || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
+	    max_packet_size : 0;
 	int ret;
 
@@ -240,4 +246,9 @@
 	usb_log_debug("Unregister endpoint %d:%d %d.\n",
 	    address, endpoint, direction);
+	endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
+	    address, endpoint, direction, NULL);
+	if (ep != NULL) {
+		usb_device_keeper_del_ep(&hc->manager, address, ep);
+	}
 	return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
 	    endpoint, direction);
@@ -248,5 +259,4 @@
  * @param[in] fun DDF function that was called.
  * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts
  * @param[in] data Source of data.
  * @param[in] size Size of data source.
@@ -256,5 +266,5 @@
  */
 static int interrupt_out(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
+    ddf_fun_t *fun, usb_target_t target, void *data,
     size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
@@ -277,5 +287,4 @@
  * @param[in] fun DDF function that was called.
  * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts
  * @param[out] data Data destination.
  * @param[in] size Size of data source.
@@ -285,5 +294,5 @@
  */
 static int interrupt_in(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
+    ddf_fun_t *fun, usb_target_t target, void *data,
     size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
@@ -306,5 +315,4 @@
  * @param[in] fun DDF function that was called.
  * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts
  * @param[in] data Source of data.
  * @param[in] size Size of data source.
@@ -314,5 +322,5 @@
  */
 static int bulk_out(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
+    ddf_fun_t *fun, usb_target_t target, void *data,
     size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
@@ -335,5 +343,4 @@
  * @param[in] fun DDF function that was called.
  * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts
  * @param[out] data Data destination.
  * @param[in] size Size of data source.
@@ -343,5 +350,5 @@
  */
 static int bulk_in(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
+    ddf_fun_t *fun, usb_target_t target, void *data,
     size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
@@ -364,5 +371,4 @@
  * @param[in] fun DDF function that was called.
  * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts.
  * @param[in] setup_data Data to send with SETUP transfer.
  * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
@@ -374,5 +380,5 @@
  */
 static int control_write(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
+    ddf_fun_t *fun, usb_target_t target,
     void *setup_data, size_t setup_size, void *data, size_t size,
     usbhc_iface_transfer_out_callback_t callback, void *arg)
@@ -398,5 +404,4 @@
  * @param[in] fun DDF function that was called.
  * @param[in] target USB device to write to.
- * @param[in] max_packet_size maximum size of data packet the device accepts.
  * @param[in] setup_data Data to send with SETUP packet.
  * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
@@ -408,5 +413,5 @@
  */
 static int control_read(
-    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
+    ddf_fun_t *fun, usb_target_t target,
     void *setup_data, size_t setup_size, void *data, size_t size,
     usbhc_iface_transfer_in_callback_t callback, void *arg)
Index: uspace/drv/vhc/connhost.c
===================================================================
--- uspace/drv/vhc/connhost.c	(revision 7b71589214d277bc89e2dc6a413210eead6776df)
+++ uspace/drv/vhc/connhost.c	(revision a9d67aa466df883d1cd0d12261cae57a88fbc88e)
@@ -257,5 +257,4 @@
 
 static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size,
     void *data, size_t size,
     usbhc_iface_transfer_out_callback_t callback, void *arg)
@@ -267,5 +266,4 @@
 
 static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size,
     void *data, size_t size,
     usbhc_iface_transfer_in_callback_t callback, void *arg)
@@ -277,5 +275,4 @@
 
 static int control_write(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size,
     void *setup_packet, size_t setup_packet_size,
     void *data, size_t data_size,
@@ -295,5 +292,4 @@
 
 static int control_read(ddf_fun_t *fun, usb_target_t target,
-    size_t max_packet_size,
     void *setup_packet, size_t setup_packet_size,
     void *data, size_t data_size,
