Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision feb10c881f64ba4f899fa9366c46240a927219e6)
+++ uspace/drv/uhci-hcd/iface.c	(revision 2e6bbcf98d749ab7ff9dc259a1ab8d64c9b6e678)
@@ -41,4 +41,51 @@
 #include "hc.h"
 
+static inline int setup_batch(
+    ddf_fun_t *fun, usb_target_t target, usb_direction_t direction,
+    void *data, size_t size, void * setup_data, size_t setup_size,
+    usbhc_iface_transfer_in_callback_t in,
+    usbhc_iface_transfer_out_callback_t out, void *arg, const char* name,
+    hc_t **hc, usb_transfer_batch_t **batch)
+{
+	assert(hc);
+	assert(batch);
+	assert(fun);
+	*hc = fun_to_hc(fun);
+	assert(*hc);
+
+	size_t res_bw;
+	endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager,
+	    target.address, target.endpoint, direction, &res_bw);
+	if (ep == NULL) {
+		usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
+		    target.address, target.endpoint, name);
+		return ENOENT;
+	}
+
+	const size_t bw = bandwidth_count_usb11(
+	    ep->speed, ep->transfer_type, size, ep->max_packet_size);
+	if (res_bw < bw) {
+		usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
+		    "but only %zu is reserved.\n",
+		    name, target.address, target.endpoint, bw, res_bw);
+		return ENOSPC;
+	}
+	usb_log_debug("%s %d:%d %zu(%zu).\n",
+	    name, target.address, target.endpoint, size, ep->max_packet_size);
+
+	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);
+
+	*batch =
+	    batch_get(fun, ep, data, size, setup_data, setup_size,
+		in, out, arg);
+	if (!batch)
+		return ENOMEM;
+	return EOK;
+}
+
+
 /** Reserve default address interface function
  *
@@ -215,4 +262,11 @@
     size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
+	usb_transfer_batch_t *batch = NULL;
+	hc_t *hc = NULL;
+	int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
+	    NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch);
+	if (ret != EOK)
+		return ret;
+#if 0
 	assert(fun);
 	hc_t *hc = fun_to_hc(fun);
@@ -233,9 +287,10 @@
 	    size, ep->max_packet_size);
 	if (res_bw < bw) {
-		usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
+		usb_log_error("Endpoint(%d:%d) INT OUT needs %zu bw "
 		    "but only %zu is reserved.\n",
 		    target.address, target.endpoint, bw, res_bw);
-		return ENOENT;
-	}
+		return ENOSPC;
+	}
+
 	assert(ep->speed ==
 	    usb_device_keeper_get_speed(&hc->manager, target.address));
@@ -247,6 +302,7 @@
 	if (!batch)
 		return ENOMEM;
+#endif
 	batch_interrupt_out(batch);
-	const int ret = hc_schedule(hc, batch);
+	ret = hc_schedule(hc, batch);
 	if (ret != EOK) {
 		batch_dispose(batch);
@@ -270,4 +326,11 @@
     size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
+	usb_transfer_batch_t *batch = NULL;
+	hc_t *hc = NULL;
+	int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
+	    NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch);
+	if (ret != EOK)
+		return ret;
+#if 0
 	assert(fun);
 	hc_t *hc = fun_to_hc(fun);
@@ -283,5 +346,5 @@
 		usb_log_error("Endpoint(%d:%d) not registered for INT IN.\n",
 		    target.address, target.endpoint);
-		return ENOENT;
+		return ENOSPC;
 	}
 	const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
@@ -303,6 +366,7 @@
 	if (!batch)
 		return ENOMEM;
+#endif
 	batch_interrupt_in(batch);
-	const int ret = hc_schedule(hc, batch);
+	ret = hc_schedule(hc, batch);
 	if (ret != EOK) {
 		batch_dispose(batch);
@@ -326,4 +390,11 @@
     size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
+	usb_transfer_batch_t *batch = NULL;
+	hc_t *hc = NULL;
+	int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
+	    NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch);
+	if (ret != EOK)
+		return ret;
+#if 0
 	assert(fun);
 	hc_t *hc = fun_to_hc(fun);
@@ -349,6 +420,7 @@
 	if (!batch)
 		return ENOMEM;
+#endif
 	batch_bulk_out(batch);
-	const int ret = hc_schedule(hc, batch);
+	ret = hc_schedule(hc, batch);
 	if (ret != EOK) {
 		batch_dispose(batch);
@@ -372,7 +444,15 @@
     size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
-	assert(fun);
-	hc_t *hc = fun_to_hc(fun);
-	assert(hc);
+	usb_transfer_batch_t *batch = NULL;
+	hc_t *hc = NULL;
+	int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
+	    NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch);
+	if (ret != EOK)
+		return ret;
+#if 0
+	assert(fun);
+	hc_t *hc = fun_to_hc(fun);
+	assert(hc);
+
 	usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
 	    target.address, target.endpoint, size, max_packet_size);
@@ -394,6 +474,7 @@
 	if (!batch)
 		return ENOMEM;
+#endif
 	batch_bulk_in(batch);
-	const int ret = hc_schedule(hc, batch);
+	ret = hc_schedule(hc, batch);
 	if (ret != EOK) {
 		batch_dispose(batch);
@@ -420,4 +501,12 @@
     usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
+	usb_transfer_batch_t *batch = NULL;
+	hc_t *hc = NULL;
+	int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
+	    setup_data, setup_size, NULL, callback, arg, "Control WRITE",
+	    &hc, &batch);
+	if (ret != EOK)
+		return ret;
+#if 0
 	assert(fun);
 	hc_t *hc = fun_to_hc(fun);
@@ -447,7 +536,8 @@
 	if (!batch)
 		return ENOMEM;
+#endif
 	usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
 	batch_control_write(batch);
-	const int ret = hc_schedule(hc, batch);
+	ret = hc_schedule(hc, batch);
 	if (ret != EOK) {
 		batch_dispose(batch);
@@ -474,4 +564,12 @@
     usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
+	usb_transfer_batch_t *batch = NULL;
+	hc_t *hc = NULL;
+	int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
+	    setup_data, setup_size, callback, NULL, arg, "Control READ",
+	    &hc, &batch);
+	if (ret != EOK)
+		return ret;
+#if 0
 	assert(fun);
 	hc_t *hc = fun_to_hc(fun);
@@ -498,6 +596,7 @@
 	if (!batch)
 		return ENOMEM;
+#endif
 	batch_control_read(batch);
-	const int ret = hc_schedule(hc, batch);
+	ret = hc_schedule(hc, batch);
 	if (ret != EOK) {
 		batch_dispose(batch);
