Index: uspace/lib/usbhost/include/usb/host/hcd.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/hcd.h	(revision 4dfc905860c1e80378dde24f172dfa72c8133de8)
+++ uspace/lib/usbhost/include/usb/host/hcd.h	(revision 549ff23eeccbe3fe8e6eb34fffc58415a5e01252)
@@ -97,5 +97,5 @@
  * @return pointer cast to hcd_t*.
  */
-static inline hcd_t * fun_to_hcd(ddf_fun_t *fun)
+static inline hcd_t * fun_to_hcd(const ddf_fun_t *fun)
 {
 	assert(fun);
Index: uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h	(revision 4dfc905860c1e80378dde24f172dfa72c8133de8)
+++ uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h	(revision 549ff23eeccbe3fe8e6eb34fffc58415a5e01252)
@@ -43,7 +43,6 @@
 #define USB_SETUP_PACKET_SIZE 8
 
-typedef struct usb_transfer_batch usb_transfer_batch_t;
 /** Structure stores additional data needed for communication with EP */
-struct usb_transfer_batch {
+typedef struct usb_transfer_batch {
 	/** Endpoint used for communication */
 	endpoint_t *ep;
@@ -77,5 +76,5 @@
 	/** Callback to properly remove driver data during destruction */
 	void (*private_data_dtor)(void *p_data);
-};
+} usb_transfer_batch_t;
 
 /** Printf formatting string for dumping usb_transfer_batch_t. */
@@ -93,5 +92,5 @@
 
 
-usb_transfer_batch_t * usb_transfer_batch_get(
+usb_transfer_batch_t * usb_transfer_batch_create(
     endpoint_t *ep,
     char *buffer,
@@ -105,36 +104,10 @@
     void (*private_data_dtor)(void *p_data)
 );
+void usb_transfer_batch_destroy(const usb_transfer_batch_t *instance);
 
-void usb_transfer_batch_finish(usb_transfer_batch_t *instance,
+void usb_transfer_batch_finish(const usb_transfer_batch_t *instance,
     const void* data, size_t size);
-void usb_transfer_batch_call_in(usb_transfer_batch_t *instance);
-void usb_transfer_batch_call_out(usb_transfer_batch_t *instance);
-void usb_transfer_batch_dispose(usb_transfer_batch_t *instance);
-
-/** Helper function, calls callback and correctly destroys batch structure.
- *
- * @param[in] instance Batch structure to use.
- */
-static inline void usb_transfer_batch_call_in_and_dispose(
-    usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	usb_transfer_batch_call_in(instance);
-	usb_transfer_batch_dispose(instance);
-}
 /*----------------------------------------------------------------------------*/
-/** Helper function calls callback and correctly destroys batch structure.
- *
- * @param[in] instance Batch structure to use.
- */
-static inline void usb_transfer_batch_call_out_and_dispose(
-    usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	usb_transfer_batch_call_out(instance);
-	usb_transfer_batch_dispose(instance);
-}
-/*----------------------------------------------------------------------------*/
-/** Helper function, sets error value and finishes transfer.
+/** Override error value and finishes transfer.
  *
  * @param[in] instance Batch structure to use.
@@ -151,6 +124,6 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Helper function, determines batch direction absed on the present callbacks
- * @param[in] instance Batch structure to use.
+/** Determine batch direction based on the callbacks present
+ * @param[in] instance Batch structure to use, non-null.
  * @return USB_DIRECTION_IN, or USB_DIRECTION_OUT.
  */
Index: uspace/lib/usbhost/src/iface.c
===================================================================
--- uspace/lib/usbhost/src/iface.c	(revision 4dfc905860c1e80378dde24f172dfa72c8133de8)
+++ uspace/lib/usbhost/src/iface.c	(revision 549ff23eeccbe3fe8e6eb34fffc58415a5e01252)
@@ -76,5 +76,5 @@
 	/* No private data and no private data dtor */
 	usb_transfer_batch_t *batch =
-	    usb_transfer_batch_get(ep, data, size, setup_data,
+	    usb_transfer_batch_create(ep, data, size, setup_data,
 	    in, out, arg, fun, NULL, NULL);
 	if (!batch) {
@@ -84,5 +84,5 @@
 	const int ret = hcd->schedule(hcd, batch);
 	if (ret != EOK)
-		usb_transfer_batch_dispose(batch);
+		usb_transfer_batch_destroy(batch);
 
 	return ret;
Index: uspace/lib/usbhost/src/usb_transfer_batch.c
===================================================================
--- uspace/lib/usbhost/src/usb_transfer_batch.c	(revision 4dfc905860c1e80378dde24f172dfa72c8133de8)
+++ uspace/lib/usbhost/src/usb_transfer_batch.c	(revision 549ff23eeccbe3fe8e6eb34fffc58415a5e01252)
@@ -37,8 +37,21 @@
 #include <usb/usb.h>
 #include <usb/debug.h>
+
 #include <usb/host/usb_transfer_batch.h>
 #include <usb/host/hcd.h>
 
-usb_transfer_batch_t * usb_transfer_batch_get(
+/** Allocate and initialize usb_transfer_batch structure.
+ * @param ep endpoint used by the transfer batch.
+ * @param buffer data to send/recieve.
+ * @param buffer_size Size of data buffer.
+ * @param setup_buffer Data to send in SETUP stage of control transfer.
+ * @param func_in callback on IN transfer completion.
+ * @param func_out callback on OUT transfer completion.
+ * @param arg Argument to pass to the callback function.
+ * @param private_data driver specific per batch data.
+ * @param private_data_dtor Function to properly destroy private_data.
+ * @return Pointer to valid usb_transfer_batch_t structure, NULL on failure.
+ */
+usb_transfer_batch_t * usb_transfer_batch_create(
     endpoint_t *ep,
     char *buffer,
@@ -53,4 +66,9 @@
     )
 {
+	if (func_in == NULL && func_out == NULL)
+		return NULL;
+	if (func_in != NULL && func_out != NULL)
+		return NULL;
+
 	usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));
 	if (instance) {
@@ -78,78 +96,9 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Mark batch as finished and run callback.
- *
- * @param[in] instance Batch structure to use.
- * @param[in] data Data to copy to the output buffer.
- * @param[in] size Size of @p data.
- */
-void usb_transfer_batch_finish(
-    usb_transfer_batch_t *instance, const void *data, size_t size)
-{
-	assert(instance);
-	assert(instance->ep);
-	/* we care about the data and there are some to copy */
-        if (instance->ep->direction != USB_DIRECTION_OUT
-	    && data) {
-		const size_t min_size =
-		    size < instance->buffer_size ? size : instance->buffer_size;
-                memcpy(instance->buffer, data, min_size);
-        }
-        if (instance->callback_out)
-                usb_transfer_batch_call_out(instance);
-        if (instance->callback_in)
-                usb_transfer_batch_call_in(instance);
-
-}
-/*----------------------------------------------------------------------------*/
-/** Prepare data, get error status and call callback in.
- *
- * @param[in] instance Batch structure to use.
- * Copies data from transport buffer, and calls callback with appropriate
- * parameters.
- */
-void usb_transfer_batch_call_in(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	assert(instance->callback_in);
-
-	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed (%zuB): %s.\n",
-	    instance, USB_TRANSFER_BATCH_ARGS(*instance),
-	    instance->transfered_size, str_error(instance->error));
-
-	instance->callback_in(instance->fun, instance->error,
-	    instance->transfered_size, instance->arg);
-}
-/*----------------------------------------------------------------------------*/
-/** Get error status and call callback out.
- *
- * @param[in] instance Batch structure to use.
- */
-void usb_transfer_batch_call_out(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	assert(instance->callback_out);
-
-	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed: %s.\n",
-	    instance, USB_TRANSFER_BATCH_ARGS(*instance),
-	    str_error(instance->error));
-
-	if (instance->ep->transfer_type == USB_TRANSFER_CONTROL
-	    && instance->error == EOK) {
-		const usb_target_t target =
-		    {{ instance->ep->address, instance->ep->endpoint }};
-		reset_ep_if_need(
-		    fun_to_hcd(instance->fun), target, instance->setup_buffer);
-	}
-
-	instance->callback_out(instance->fun,
-	    instance->error, instance->arg);
-}
-/*----------------------------------------------------------------------------*/
 /** Correctly dispose all used data structures.
  *
  * @param[in] instance Batch structure to use.
  */
-void usb_transfer_batch_dispose(usb_transfer_batch_t *instance)
+void usb_transfer_batch_destroy(const usb_transfer_batch_t *instance)
 {
 	if (!instance)
@@ -166,4 +115,43 @@
 	free(instance);
 }
+/*----------------------------------------------------------------------------*/
+/** Prepare data and call the right callback.
+ *
+ * @param[in] instance Batch structure to use.
+ * @param[in] data Data to copy to the output buffer.
+ * @param[in] size Size of @p data.
+ */
+void usb_transfer_batch_finish(
+    const usb_transfer_batch_t *instance, const void *data, size_t size)
+{
+	assert(instance);
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " finishing.\n",
+	    instance, USB_TRANSFER_BATCH_ARGS(*instance));
+
+	/* NOTE: Only one of these pointers should be set. */
+        if (instance->callback_out) {
+		/* Check for commands that reset toggle bit */
+		if (instance->ep->transfer_type == USB_TRANSFER_CONTROL
+		    && instance->error == EOK) {
+			const usb_target_t target =
+			    {{ instance->ep->address, instance->ep->endpoint }};
+			reset_ep_if_need(fun_to_hcd(instance->fun), target,
+			    instance->setup_buffer);
+		}
+		instance->callback_out(instance->fun,
+		    instance->error, instance->arg);
+	}
+
+        if (instance->callback_in) {
+		/* We care about the data and there are some to copy */
+		if (data) {
+			const size_t min_size = size < instance->buffer_size
+			    ? size : instance->buffer_size;
+	                memcpy(instance->buffer, data, min_size);
+		}
+		instance->callback_in(instance->fun, instance->error,
+		    instance->transfered_size, instance->arg);
+	}
+}
 /**
  * @}
