Index: uspace/lib/usbhost/src/hcd.c
===================================================================
--- uspace/lib/usbhost/src/hcd.c	(revision a6a9910d295ceef9a96352a8b36c6bb095c01a35)
+++ uspace/lib/usbhost/src/hcd.c	(revision 1affef2f445ecde39895d075b7be6269dbaa7b91)
@@ -38,4 +38,5 @@
 #include <usb_iface.h>
 #include <usb/debug.h>
+#include <usb/request.h>
 
 #include <usb/host/hcd.h>
@@ -60,4 +61,25 @@
 	hcd->ep_add_hook = NULL;
 	hcd->ep_remove_hook = NULL;
+}
+
+typedef struct {
+	void *original_data;
+	usbhc_iface_transfer_out_callback_t original_callback;
+	usb_target_t target;
+	hcd_t *hcd;
+} toggle_t;
+
+static void toggle_reset_callback(int retval, void *arg)
+{
+	assert(arg);
+	toggle_t *toggle = arg;
+	if (retval == EOK) {
+		usb_log_debug2("Reseting toggle on %d:%d.\n",
+		    toggle->target.address, toggle->target.endpoint);
+		usb_endpoint_manager_reset_toggle(&toggle->hcd->ep_manager,
+		    toggle->target, toggle->target.endpoint == 0);
+	}
+
+	toggle->original_callback(retval, toggle->original_data);
 }
 
@@ -106,8 +128,26 @@
 	}
 
-	/* No private data and no private data dtor */
-	usb_transfer_batch_t *batch =
-	    usb_transfer_batch_create(ep, data, size, setup_data,
-	    in, out, arg, fun);
+	/* Check for commands that reset toggle bit */
+	if (ep->transfer_type == USB_TRANSFER_CONTROL) {
+		const int reset_toggle = usb_request_needs_toggle_reset(
+		    (usb_device_request_setup_packet_t *) &setup_data);
+		if (reset_toggle >= 0) {
+			assert(out);
+			toggle_t *toggle = malloc(sizeof(toggle_t));
+			if (!toggle)
+				return ENOMEM;
+			toggle->target.address = target.address;
+			toggle->target.endpoint = reset_toggle;
+			toggle->original_callback = out;
+			toggle->original_data = arg;
+			toggle->hcd = hcd;
+
+			arg = toggle;
+			out = toggle_reset_callback;
+		}
+	}
+
+	usb_transfer_batch_t *batch = usb_transfer_batch_create(
+	    ep, data, size, setup_data, in, out, arg, fun);
 	if (!batch) {
 		return ENOMEM;
Index: uspace/lib/usbhost/src/usb_endpoint_manager.c
===================================================================
--- uspace/lib/usbhost/src/usb_endpoint_manager.c	(revision a6a9910d295ceef9a96352a8b36c6bb095c01a35)
+++ uspace/lib/usbhost/src/usb_endpoint_manager.c	(revision 1affef2f445ecde39895d075b7be6269dbaa7b91)
@@ -168,63 +168,4 @@
 }
 
-/** Check setup packet data for signs of toggle reset.
- *
- * @param[in] instance usb_endpoint_manager structure, non-null.
- * @param[in] target Device to receive setup packet.
- * @param[in] data Setup packet data.
- *
- * Really ugly one. Resets toggle bit on all endpoints that need it.
- * @TODO Use tools from libusbdev requests.h
- */
-void usb_endpoint_manager_reset_eps_if_need(usb_endpoint_manager_t *instance,
-    usb_target_t target, const uint8_t data[8])
-{
-	assert(instance);
-	if (!usb_target_is_valid(target)) {
-		usb_log_error("Invalid data when checking for toggle reset.\n");
-		return;
-	}
-
-	assert(data);
-	switch (data[1])
-	{
-	case 0x01: /* Clear Feature -- resets only cleared ep */
-		/* Recipient is endpoint, value is zero (ENDPOINT_STALL) */
-		// TODO Use macros in libusbdev requests.h
-		if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
-			fibril_mutex_lock(&instance->guard);
-			/* endpoint number is < 16, thus first byte is enough */
-			list_foreach(*get_list(instance, target.address), it) {
-				endpoint_t *ep = endpoint_get_instance(it);
-				if ((ep->address == target.address)
-				    && (ep->endpoint = data[4])) {
-					endpoint_toggle_set(ep,0);
-				}
-			}
-			fibril_mutex_unlock(&instance->guard);
-		}
-	break;
-
-	case 0x9: /* Set Configuration */
-	case 0x11: /* Set Interface */
-		/* Recipient must be device, this resets all endpoints,
-		 * In fact there should be no endpoints but EP 0 registered
-		 * as different interfaces use different endpoints,
-		 * unless you're changing configuration or alternative
-		 * interface of an already setup device. */
-		if ((data[0] & 0xf) == 0) {
-			fibril_mutex_lock(&instance->guard);
-			list_foreach(*get_list(instance, target.address), it) {
-				endpoint_t *ep = endpoint_get_instance(it);
-				if (ep->address == target.address) {
-					endpoint_toggle_set(ep,0);
-				}
-			}
-			fibril_mutex_unlock(&instance->guard);
-		}
-	break;
-	}
-}
-
 /** Register endpoint structure.
  * Checks for duplicates.
Index: uspace/lib/usbhost/src/usb_transfer_batch.c
===================================================================
--- uspace/lib/usbhost/src/usb_transfer_batch.c	(revision a6a9910d295ceef9a96352a8b36c6bb095c01a35)
+++ uspace/lib/usbhost/src/usb_transfer_batch.c	(revision 1affef2f445ecde39895d075b7be6269dbaa7b91)
@@ -125,12 +125,4 @@
 	/* 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
-		    && 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(error, instance->arg);
 	}
