Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ uspace/drv/uhci-hcd/batch.c	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -54,4 +54,5 @@
 static void batch_call_in_and_dispose(batch_t *instance);
 static void batch_call_out_and_dispose(batch_t *instance);
+static void batch_dispose(batch_t *instance);
 
 
@@ -61,5 +62,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 +140,5 @@
 	instance->arg = arg;
 	instance->speed = speed;
+	instance->manager = manager;
 
 	queue_head_element_td(instance->qh, addr_to_phys(instance->tds));
@@ -160,4 +164,7 @@
 			usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
 			    instance, i, instance->tds[i].status);
+
+			device_keeper_set_toggle(instance->manager, instance->target,
+			    td_toggle(&instance->tds[i]));
 			if (i > 0)
 				goto substract_ret;
@@ -232,9 +239,10 @@
 }
 /*----------------------------------------------------------------------------*/
-static void batch_data(batch_t *instance, usb_packet_id pid)
+void batch_data(batch_t *instance, usb_packet_id pid)
 {
 	assert(instance);
 	const bool low_speed = instance->speed == USB_SPEED_LOW;
-	int toggle = 1;
+	int toggle = device_keeper_get_toggle(instance->manager, instance->target);
+	assert(toggle == 0 || toggle == 1);
 
 	size_t packet = 0;
@@ -245,5 +253,4 @@
 		    - remain_size;
 
-		toggle = 1 - toggle;
 
 		const size_t packet_size =
@@ -256,4 +263,5 @@
 		    &instance->tds[packet + 1]);
 
+		toggle = 1 - toggle;
 		++packet;
 		assert(packet <= instance->packets);
@@ -261,4 +269,5 @@
 		remain_size -= packet_size;
 	}
+	device_keeper_set_toggle(instance->manager, instance->target, toggle);
 
 	instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
@@ -266,5 +275,5 @@
 }
 /*----------------------------------------------------------------------------*/
-static void batch_control(batch_t *instance,
+void batch_control(batch_t *instance,
    usb_packet_id data_stage, usb_packet_id status_stage)
 {
@@ -347,4 +356,17 @@
 	assert(instance);
 	batch_call_in(instance);
+	batch_dispose(instance);
+}
+/*----------------------------------------------------------------------------*/
+void batch_call_out_and_dispose(batch_t *instance)
+{
+	assert(instance);
+	batch_call_out(instance);
+	batch_dispose(instance);
+}
+/*----------------------------------------------------------------------------*/
+void batch_dispose(batch_t *instance)
+{
+	assert(instance);
 	usb_log_debug("Batch(%p) disposing.\n", instance);
 	free32(instance->tds);
@@ -355,16 +377,4 @@
 }
 /*----------------------------------------------------------------------------*/
-void batch_call_out_and_dispose(batch_t *instance)
-{
-	assert(instance);
-	batch_call_out(instance);
-	usb_log_debug("Batch(%p) disposing.\n", instance);
-	free32(instance->tds);
-	free32(instance->qh);
-	free32(instance->setup_buffer);
-	free32(instance->transport_buffer);
-	free(instance);
-}
-/*----------------------------------------------------------------------------*/
 int batch_schedule(batch_t *instance)
 {
Index: uspace/drv/uhci-hcd/batch.h
===================================================================
--- uspace/drv/uhci-hcd/batch.h	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ uspace/drv/uhci-hcd/batch.h	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -42,4 +42,5 @@
 #include "uhci_struct/transfer_descriptor.h"
 #include "uhci_struct/queue_head.h"
+#include "utils/device_keeper.h"
 
 typedef struct batch
@@ -67,4 +68,5 @@
 	td_t *tds;
 	void (*next_step)(struct batch*);
+	device_keeper_t *manager;
 } batch_t;
 
@@ -74,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);
Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ uspace/drv/uhci-hcd/iface.c	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -114,5 +114,6 @@
 
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
-	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
+	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
+	    &hc->device_manager);
 	if (!batch)
 		return ENOMEM;
@@ -133,5 +134,6 @@
 
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
-	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
+	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
+			&hc->device_manager);
 	if (!batch)
 		return ENOMEM;
@@ -153,5 +155,6 @@
 
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
-	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
+	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
+	    &hc->device_manager);
 	if (!batch)
 		return ENOMEM;
@@ -172,5 +175,6 @@
 
 	batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
-	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
+	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
+	    &hc->device_manager);
 	if (!batch)
 		return ENOMEM;
@@ -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;
Index: pace/drv/uhci-hcd/transfers.c
===================================================================
--- uspace/drv/uhci-hcd/transfers.c	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ 	(revision )
@@ -1,160 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <usb/hcdhubd.h>
-#include <errno.h>
-
-#include "uhci.h"
-
-static int enqueue_transfer_out(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer OUT [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-static int enqueue_transfer_setup(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer SETUP [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-static int enqueue_transfer_in(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer IN [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-
-static int get_address(device_t *dev, devman_handle_t handle,
-    usb_address_t *address)
-{
-	return ENOTSUP;
-}
-
-static int interrupt_out(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_INTERRUPT,
-	    data, size,
-	    callback, arg);
-}
-
-static int interrupt_in(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_setup(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_data(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
-	    NULL, 0,
-	    callback, arg);
-}
-
-static int control_read_setup(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_read_data(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_read_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
-	    NULL, 0,
-	    callback, arg);
-}
-
-
-usbhc_iface_t uhci_iface = {
-	.tell_address = get_address,
-	.interrupt_out = interrupt_out,
-	.interrupt_in = interrupt_in,
-	.control_write_setup = control_write_setup,
-	.control_write_data = control_write_data,
-	.control_write_status = control_write_status,
-	.control_read_setup = control_read_setup,
-	.control_read_data = control_read_data,
-	.control_read_status = control_read_status
-};
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ uspace/drv/uhci-hcd/uhci.c	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -167,6 +167,6 @@
 	/* reset hc, all states and counters */
 	pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET);
-	while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)
-		{ async_usleep(10); }
+	do { async_usleep(10); }
+	while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
 
 	/* set framelist pointer */
@@ -175,7 +175,9 @@
 
 	/* enable all interrupts, but resume interrupt */
-	pio_write_16(&instance->registers->usbintr,
-	    UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
-
+//	pio_write_16(&instance->registers->usbintr,
+//	    UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
+
+	uint16_t status = pio_read_16(&instance->registers->usbcmd);
+	usb_log_warning("Previous command value: %x.\n", status);
 	/* Start the hc with large(64B) packet FSBR */
 	pio_write_16(&instance->registers->usbcmd,
Index: uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -75,4 +75,8 @@
 	    instance->next, instance->status, instance->device,
 	    instance->buffer_ptr, buffer);
+	if (pid == USB_PID_SETUP) {
+		usb_log_debug("SETUP BUFFER: %s\n",
+			usb_debug_str_buffer(buffer, 8, 8));
+	}
 }
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -115,4 +115,11 @@
 }
 
+static inline int td_toggle(td_t *instance)
+{
+	assert(instance);
+	return ((instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) != 0)
+	    ? 1 : 0;
+}
+
 static inline bool td_is_active(td_t *instance)
 {
Index: uspace/drv/uhci-hcd/utils/device_keeper.c
===================================================================
--- uspace/drv/uhci-hcd/utils/device_keeper.c	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ uspace/drv/uhci-hcd/utils/device_keeper.c	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -49,4 +49,5 @@
 		instance->devices[i].occupied = false;
 		instance->devices[i].handle = 0;
+		instance->devices[i].toggle_status = 0;
 	}
 }
@@ -73,4 +74,72 @@
 	fibril_mutex_unlock(&instance->guard);
 	fibril_condvar_signal(&instance->default_address_occupied);
+}
+/*----------------------------------------------------------------------------*/
+void device_keeper_reset_if_need(
+    device_keeper_t *instance, usb_target_t target, const unsigned char *data)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+	if (target.endpoint > 15 || target.endpoint < 0
+	    || target.address >= USB_ADDRESS_COUNT || target.address < 0
+	    || !instance->devices[target.address].occupied) {
+		goto the_end;
+	}
+
+	switch (data[1])
+	{
+	case 0x01: /*clear feature*/
+		/* recipient is enpoint, value is zero (ENDPOINT_STALL) */
+		if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
+			/* enpoint number is < 16, thus first byte is enough */
+			instance->devices[target.address].toggle_status &= ~(1 << data[4]);
+		}
+	break;
+
+	case 0x9: /* set configuration */
+	case 0x11: /* set interface */
+		instance->devices[target.address].toggle_status = 0;
+	break;
+	}
+the_end:
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target)
+{
+	assert(instance);
+	int ret;
+	fibril_mutex_lock(&instance->guard);
+	if (target.endpoint > 15 || target.endpoint < 0
+	    || target.address >= USB_ADDRESS_COUNT || target.address < 0
+	    || !instance->devices[target.address].occupied) {
+		ret = EINVAL;
+	} else {
+		ret = (instance->devices[target.address].toggle_status >> target.endpoint) & 1;
+	}
+	fibril_mutex_unlock(&instance->guard);
+	return ret;
+}
+/*----------------------------------------------------------------------------*/
+int device_keeper_set_toggle(
+    device_keeper_t *instance, usb_target_t target, bool toggle)
+{
+	assert(instance);
+	int ret;
+	fibril_mutex_lock(&instance->guard);
+	if (target.endpoint > 15 || target.endpoint < 0
+	    || target.address >= USB_ADDRESS_COUNT || target.address < 0
+	    || !instance->devices[target.address].occupied) {
+		ret = EINVAL;
+	} else {
+		if (toggle) {
+			instance->devices[target.address].toggle_status |= (1 << target.endpoint);
+		} else {
+			instance->devices[target.address].toggle_status &= ~(1 << target.endpoint);
+		}
+		ret = EOK;
+	}
+	fibril_mutex_unlock(&instance->guard);
+	return ret;
 }
 /*----------------------------------------------------------------------------*/
@@ -96,4 +165,5 @@
 	instance->devices[new_address].occupied = true;
 	instance->devices[new_address].speed = speed;
+	instance->devices[new_address].toggle_status = 0;
 	instance->last_address = new_address;
 	fibril_mutex_unlock(&instance->guard);
Index: uspace/drv/uhci-hcd/utils/device_keeper.h
===================================================================
--- uspace/drv/uhci-hcd/utils/device_keeper.h	(revision 24d5432f767469670c882adb1832b1ddecf4610c)
+++ uspace/drv/uhci-hcd/utils/device_keeper.h	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -44,4 +44,5 @@
 	usb_speed_t speed;
 	bool occupied;
+	uint16_t toggle_status;
 	devman_handle_t handle;
 };
@@ -55,13 +56,26 @@
 
 void device_keeper_init(device_keeper_t *instance);
+
 void device_keeper_reserve_default(
     device_keeper_t *instance, usb_speed_t speed);
+
 void device_keeper_release_default(device_keeper_t *instance);
+
+void device_keeper_reset_if_need(
+    device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data);
+
+int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target);
+
+int device_keeper_set_toggle(
+    device_keeper_t *instance, usb_target_t target, bool toggle);
 
 usb_address_t device_keeper_request(
     device_keeper_t *instance, usb_speed_t speed);
+
 void device_keeper_bind(
     device_keeper_t *instance, usb_address_t address, devman_handle_t handle);
+
 void device_keeper_release(device_keeper_t *instance, usb_address_t address);
+
 usb_address_t device_keeper_find(
     device_keeper_t *instance, devman_handle_t handle);
