Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision 98807e16a5c0772485f4b14788ab3a810e762bbf)
+++ uspace/drv/uhci-hcd/batch.c	(revision 5620bd439d14dda3836717e848fd17aef354ddf8)
@@ -49,5 +49,5 @@
 static void batch_control(batch_t *instance,
     usb_packet_id data_stage, usb_packet_id status_stage);
-static void batch_data(batch_t *instance, usb_packet_id pid, device_keeper_t *keeper);
+static void batch_data(batch_t *instance, usb_packet_id pid);
 static void batch_call_in(batch_t *instance);
 static void batch_call_out(batch_t *instance);
@@ -61,5 +61,7 @@
     char* setup_buffer, size_t setup_size,
     usbhc_iface_transfer_in_callback_t func_in,
-    usbhc_iface_transfer_out_callback_t func_out, void *arg)
+    usbhc_iface_transfer_out_callback_t func_out, void *arg,
+    device_keeper_t *manager
+    )
 {
 	assert(func_in == NULL || func_out == NULL);
@@ -137,4 +139,5 @@
 	instance->arg = arg;
 	instance->speed = speed;
+	instance->manager = manager;
 
 	queue_head_element_td(instance->qh, addr_to_phys(instance->tds));
@@ -194,8 +197,8 @@
 }
 /*----------------------------------------------------------------------------*/
-void batch_interrupt_in(batch_t *instance, device_keeper_t *keeper)
-{
-	assert(instance);
-	batch_data(instance, USB_PID_IN, keeper);
+void batch_interrupt_in(batch_t *instance)
+{
+	assert(instance);
+	batch_data(instance, USB_PID_IN);
 	instance->next_step = batch_call_in_and_dispose;
 	usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
@@ -203,9 +206,9 @@
 }
 /*----------------------------------------------------------------------------*/
-void batch_interrupt_out(batch_t *instance, device_keeper_t *keeper)
+void batch_interrupt_out(batch_t *instance)
 {
 	assert(instance);
 	memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
-	batch_data(instance, USB_PID_OUT, keeper);
+	batch_data(instance, USB_PID_OUT);
 	instance->next_step = batch_call_out_and_dispose;
 	usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
@@ -213,8 +216,8 @@
 }
 /*----------------------------------------------------------------------------*/
-void batch_bulk_in(batch_t *instance, device_keeper_t *keeper)
-{
-	assert(instance);
-	batch_data(instance, USB_PID_IN, keeper);
+void batch_bulk_in(batch_t *instance)
+{
+	assert(instance);
+	batch_data(instance, USB_PID_IN);
 	instance->next_step = batch_call_in_and_dispose;
 	usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
@@ -222,9 +225,9 @@
 }
 /*----------------------------------------------------------------------------*/
-void batch_bulk_out(batch_t *instance, device_keeper_t *keeper)
+void batch_bulk_out(batch_t *instance)
 {
 	assert(instance);
 	memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
-	batch_data(instance, USB_PID_OUT, keeper);
+	batch_data(instance, USB_PID_OUT);
 	instance->next_step = batch_call_out_and_dispose;
 	usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance);
@@ -232,9 +235,9 @@
 }
 /*----------------------------------------------------------------------------*/
-void batch_data(batch_t *instance, usb_packet_id pid, device_keeper_t *keeper)
+void batch_data(batch_t *instance, usb_packet_id pid)
 {
 	assert(instance);
 	const bool low_speed = instance->speed == USB_SPEED_LOW;
-	int toggle = device_keeper_get_toggle(keeper, instance->target);
+	int toggle = device_keeper_get_toggle(instance->manager, instance->target);
 	assert(toggle == 0 || toggle == 1);
 
@@ -262,5 +265,5 @@
 		remain_size -= packet_size;
 	}
-	device_keeper_set_toggle(keeper, instance->target, toggle);
+	device_keeper_set_toggle(instance->manager, instance->target, toggle);
 
 	instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
Index: uspace/drv/uhci-hcd/batch.h
===================================================================
--- uspace/drv/uhci-hcd/batch.h	(revision 98807e16a5c0772485f4b14788ab3a810e762bbf)
+++ uspace/drv/uhci-hcd/batch.h	(revision 5620bd439d14dda3836717e848fd17aef354ddf8)
@@ -68,4 +68,5 @@
 	td_t *tds;
 	void (*next_step)(struct batch*);
+	device_keeper_t *manager;
 } batch_t;
 
@@ -75,5 +76,7 @@
 		char *setup_buffer, size_t setup_size,
     usbhc_iface_transfer_in_callback_t func_in,
-    usbhc_iface_transfer_out_callback_t func_out, void *arg);
+    usbhc_iface_transfer_out_callback_t func_out, void *arg,
+		device_keeper_t *manager
+		);
 
 bool batch_is_complete(batch_t *instance);
@@ -83,11 +86,11 @@
 void batch_control_read(batch_t *instance);
 
-void batch_interrupt_in(batch_t *instance, device_keeper_t *keeper);
+void batch_interrupt_in(batch_t *instance);
 
-void batch_interrupt_out(batch_t *instance, device_keeper_t *keeper);
+void batch_interrupt_out(batch_t *instance);
 
-void batch_bulk_in(batch_t *instance, device_keeper_t *keeper);
+void batch_bulk_in(batch_t *instance);
 
-void batch_bulk_out(batch_t *instance, device_keeper_t *keeper);
+void batch_bulk_out(batch_t *instance);
 #endif
 /**
Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision 98807e16a5c0772485f4b14788ab3a810e762bbf)
+++ uspace/drv/uhci-hcd/iface.c	(revision 5620bd439d14dda3836717e848fd17aef354ddf8)
@@ -114,8 +114,9 @@
 
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
-	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_interrupt_out(batch, &hc->device_manager);
+	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
+	    &hc->device_manager);
+	if (!batch)
+		return ENOMEM;
+	batch_interrupt_out(batch);
 	return EOK;
 }
@@ -133,8 +134,9 @@
 
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
-	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_interrupt_in(batch, &hc->device_manager);
+	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
+			&hc->device_manager);
+	if (!batch)
+		return ENOMEM;
+	batch_interrupt_in(batch);
 	return EOK;
 }
@@ -153,8 +155,9 @@
 
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
-	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_bulk_out(batch, &hc->device_manager);
+	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
+	    &hc->device_manager);
+	if (!batch)
+		return ENOMEM;
+	batch_bulk_out(batch);
 	return EOK;
 }
@@ -172,8 +175,9 @@
 
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
-	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_bulk_in(batch, &hc->device_manager);
+	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
+	    &hc->device_manager);
+	if (!batch)
+		return ENOMEM;
+	batch_bulk_in(batch);
 	return EOK;
 }
@@ -191,9 +195,13 @@
 	    target.address, target.endpoint, size, max_packet_size);
 
+	if (setup_size != 8)
+		return EINVAL;
+
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
 	    max_packet_size, speed, data, size, setup_data, setup_size,
-	    NULL, callback, arg);
-	if (!batch)
-		return ENOMEM;
+	    NULL, callback, arg, &hc->device_manager);
+	if (!batch)
+		return ENOMEM;
+	device_keeper_reset_if_need(&hc->device_manager, target, setup_data);
 	batch_control_write(batch);
 	return EOK;
@@ -214,5 +222,5 @@
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
 	    max_packet_size, speed, data, size, setup_data, setup_size, callback,
-	    NULL, arg);
+	    NULL, arg, &hc->device_manager);
 	if (!batch)
 		return ENOMEM;
