Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/uhci-hcd/batch.c	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -153,4 +153,16 @@
 }
 /*----------------------------------------------------------------------------*/
+/** Mark batch as failed and continue with next step.
+ *
+ * @param[in] instance Batch structure to use.
+ *
+ */
+void batch_abort(batch_t *instance)
+{
+	assert(instance);
+	instance->error = EIO;
+	instance->next_step(instance);
+}
+/*----------------------------------------------------------------------------*/
 /** Check batch TDs for activity.
  *
@@ -251,5 +263,6 @@
 	assert(instance);
 	/* We are data out, we are supposed to provide data */
-	memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
+	memcpy(instance->transport_buffer, instance->buffer,
+	    instance->buffer_size);
 	batch_data(instance, USB_PID_OUT);
 	instance->next_step = batch_call_out_and_dispose;
@@ -281,5 +294,6 @@
 	assert(instance);
 	/* We are data out, we are supposed to provide data */
-	memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
+	memcpy(instance->transport_buffer, instance->buffer,
+	    instance->buffer_size);
 	batch_data(instance, USB_PID_OUT);
 	instance->next_step = batch_call_out_and_dispose;
Index: uspace/drv/uhci-hcd/batch.h
===================================================================
--- uspace/drv/uhci-hcd/batch.h	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/uhci-hcd/batch.h	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -69,14 +69,23 @@
 } batch_t;
 
-batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
-    usb_transfer_type_t transfer_type, size_t max_packet_size,
-    usb_speed_t speed, char *buffer, size_t size,
-		char *setup_buffer, size_t setup_size,
+batch_t * batch_get(
+    ddf_fun_t *fun,
+		usb_target_t target,
+    usb_transfer_type_t transfer_type,
+		size_t max_packet_size,
+    usb_speed_t speed,
+		char *buffer,
+		size_t size,
+		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
 		);
 
 void batch_dispose(batch_t *instance);
+
+void batch_abort(batch_t *instance);
 
 bool batch_is_complete(batch_t *instance);
Index: uspace/drv/uhci-hcd/transfer_list.c
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.c	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/uhci-hcd/transfer_list.c	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -129,4 +129,58 @@
 }
 /*----------------------------------------------------------------------------*/
+/** Check list for finished batches.
+ *
+ * @param[in] instance List to use.
+ * @return Error code
+ *
+ * Creates a local list of finished batches and calls next_step on each and
+ * every one. This is safer because next_step may theoretically access
+ * this transfer list leading to the deadlock if its done inline.
+ */
+void transfer_list_remove_finished(transfer_list_t *instance)
+{
+	assert(instance);
+
+	LIST_INITIALIZE(done);
+
+	fibril_mutex_lock(&instance->guard);
+	link_t *current = instance->batch_list.next;
+	while (current != &instance->batch_list) {
+		link_t *next = current->next;
+		batch_t *batch = list_get_instance(current, batch_t, link);
+
+		if (batch_is_complete(batch)) {
+			/* Save for post-processing */
+			transfer_list_remove_batch(instance, batch);
+			list_append(current, &done);
+		}
+		current = next;
+	}
+	fibril_mutex_unlock(&instance->guard);
+
+	while (!list_empty(&done)) {
+		link_t *item = done.next;
+		list_remove(item);
+		batch_t *batch = list_get_instance(item, batch_t, link);
+		batch->next_step(batch);
+	}
+}
+/*----------------------------------------------------------------------------*/
+/** Walk the list and abort all batches.
+ *
+ * @param[in] instance List to use.
+ */
+void transfer_list_abort_all(transfer_list_t *instance)
+{
+	fibril_mutex_lock(&instance->guard);
+	while (list_empty(&instance->batch_list)) {
+		link_t *current = instance->batch_list.next;
+		batch_t *batch = list_get_instance(current, batch_t, link);
+		transfer_list_remove_batch(instance, batch);
+		batch_abort(batch);
+	}
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
 /** Remove a transfer batch from the list and queue.
  *
@@ -163,42 +217,4 @@
 	    batch, pos, instance->name, batch->qh->next);
 }
-/*----------------------------------------------------------------------------*/
-/** Check list for finished batches.
- *
- * @param[in] instance List to use.
- * @return Error code
- *
- * Creates a local list of finished batches and calls next_step on each and
- * every one. This is safer because next_step may theoretically access
- * this transfer list leading to the deadlock if its done inline.
- */
-void transfer_list_remove_finished(transfer_list_t *instance)
-{
-	assert(instance);
-
-	LIST_INITIALIZE(done);
-
-	fibril_mutex_lock(&instance->guard);
-	link_t *current = instance->batch_list.next;
-	while (current != &instance->batch_list) {
-		link_t *next = current->next;
-		batch_t *batch = list_get_instance(current, batch_t, link);
-
-		if (batch_is_complete(batch)) {
-			/* Save for post-processing */
-			transfer_list_remove_batch(instance, batch);
-			list_append(current, &done);
-		}
-		current = next;
-	}
-	fibril_mutex_unlock(&instance->guard);
-
-	while (!list_empty(&done)) {
-		link_t *item = done.next;
-		list_remove(item);
-		batch_t *batch = list_get_instance(item, batch_t, link);
-		batch->next_step(batch);
-	}
-}
 /**
  * @}
Index: uspace/drv/uhci-hcd/transfer_list.h
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.h	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/uhci-hcd/transfer_list.h	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -66,7 +66,9 @@
 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);
 
+void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch);
+
 void transfer_list_remove_finished(transfer_list_t *instance);
 
-void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch);
+void transfer_list_abort_all(transfer_list_t *instance);
 #endif
 /**
Index: uspace/drv/uhci-hcd/uhci_hc.c
===================================================================
--- uspace/drv/uhci-hcd/uhci_hc.c	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/uhci-hcd/uhci_hc.c	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -97,4 +97,6 @@
 
 	instance->hw_interrupts = interrupts;
+	instance->hw_failures = 0;
+
 	/* Setup UHCI function. */
 	instance->ddf_instance = fun;
@@ -149,5 +151,8 @@
 	while ((pio_read_16(&registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
 
-	/* Set framelist pointer */
+	/* Set frame to exactly 1ms */
+	pio_write_8(&registers->sofmod, 64);
+
+	/* Set frame list pointer */
 	const uint32_t pa = addr_to_phys(instance->frame_list);
 	pio_write_32(&registers->flbaseadd, pa);
@@ -347,5 +352,5 @@
 {
 	assert(instance);
-	/* TODO: Check interrupt cause here */
+	/* TODO: Resume interrupts are not supported */
 	/* Lower 2 bits are transaction error and transaction complete */
 	if (status & 0x3) {
@@ -354,4 +359,21 @@
 		transfer_list_remove_finished(&instance->transfers_control_full);
 		transfer_list_remove_finished(&instance->transfers_bulk_full);
+	}
+	/* bits 4 and 5 indicate hc error */
+	if (status & 0x18) {
+		usb_log_error("UHCI hardware failure!.\n");
+		++instance->hw_failures;
+		transfer_list_abort_all(&instance->transfers_interrupt);
+		transfer_list_abort_all(&instance->transfers_control_slow);
+		transfer_list_abort_all(&instance->transfers_control_full);
+		transfer_list_abort_all(&instance->transfers_bulk_full);
+
+		if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {
+			/* reinitialize hw, this triggers virtual disconnect*/
+			uhci_hc_init_hw(instance);
+		} else {
+			usb_log_fatal("Too many UHCI hardware failures!.\n");
+			uhci_hc_fini(instance);
+		}
 	}
 }
Index: uspace/drv/uhci-hcd/uhci_hc.h
===================================================================
--- uspace/drv/uhci-hcd/uhci_hc.h	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/uhci-hcd/uhci_hc.h	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -80,4 +80,5 @@
 #define UHCI_CLEANER_TIMEOUT 10000
 #define UHCI_DEBUGER_TIMEOUT 5000000
+#define UHCI_ALLOWED_HW_FAIL 5
 
 typedef struct uhci_hc {
@@ -100,4 +101,5 @@
 	fid_t debug_checker;
 	bool hw_interrupts;
+	unsigned hw_failures;
 
 	ddf_fun_t *ddf_instance;
Index: uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -159,5 +159,5 @@
 	    (s & TD_STATUS_ERROR_BIT_STUFF) ? " BIT_STUFF," : "",
 	    (s & TD_STATUS_ERROR_RESERVED) ? " RESERVED," : "",
-	    (s >> TD_STATUS_ACTLEN_POS) & TD_STATUS_ACTLEN_MASK
+	    td_act_size(instance)
 	);
 }
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/usbhub/usbhub.c	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -72,8 +72,12 @@
 int usb_hub_control_loop(void * hub_info_param){
 	usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
-	while(true){
-		usb_hub_check_hub_changes(hub_info);
+	int errorCode = EOK;
+
+	while(errorCode == EOK){
+		errorCode = usb_hub_check_hub_changes(hub_info);
 		async_usleep(1000 * 1000 );/// \TODO proper number once
 	}
+	dprintf(USB_LOG_LEVEL_ERROR,
+				"something in ctrl loop went wrong, errno %d",errorCode);
 	return 0;
 }
@@ -380,5 +384,6 @@
  * @param target
  */
-static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) {
+static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
+		bool isLowSpeed) {
 	usb_device_request_setup_packet_t request;
 	int opResult;
@@ -386,6 +391,6 @@
 	assert(hub->endpoints.control.hc_phone);
 	//get default address
-	//opResult = usb_drv_reserve_default_address(hc);
-	opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
+	usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;
+	opResult = usb_hc_reserve_default_address(&hub->connection, speed);
 	
 	if (opResult != EOK) {
@@ -446,5 +451,5 @@
 	usb_address_t new_device_address = usb_hc_request_address(
 			&hub->connection,
-			speed/// \TODO fullspeed??
+			speed
 			);
 	if (new_device_address < 0) {
@@ -510,7 +515,5 @@
 static void usb_hub_removed_device(
     usb_hub_info_t * hub,uint16_t port) {
-	//usb_device_request_setup_packet_t request;
-	int opResult;
-	
+		
 	/** \TODO remove device from device manager - not yet implemented in
 	 * devide manager
@@ -519,5 +522,5 @@
 	//close address
 	if(hub->attached_devs[port].address!=0){
-		//opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
+		/*uncomment this code to use it when DDF allows device removal
 		opResult = usb_hc_unregister_device(
 				&hub->connection, hub->attached_devs[port].address);
@@ -528,4 +531,5 @@
 		hub->attached_devs[port].address = 0;
 		hub->attached_devs[port].handle = 0;
+		 */
 	}else{
 		dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address");
@@ -597,5 +601,5 @@
 		if (usb_port_dev_connected(&status)) {
 			dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
-			usb_hub_init_add_device(hub, port);
+			usb_hub_init_add_device(hub, port, usb_port_low_speed(&status));
 		} else {
 			usb_hub_removed_device(hub, port);
@@ -635,7 +639,9 @@
 /**
  * Check changes on particular hub
- * @param hub_info_param
- */
-void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
+ * @param hub_info_param pointer to usb_hub_info_t structure
+ * @return error code if there is problem when initializing communication with
+ * hub, EOK otherwise
+ */
+int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
 	int opResult;
 	opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
@@ -643,5 +649,5 @@
 		dprintf(USB_LOG_LEVEL_ERROR,
 				"could not initialize communication for hub; %d", opResult);
-		return;
+		return opResult;
 	}
 
@@ -665,5 +671,5 @@
 		dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
 		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
-		return;
+		return opResult;
 	}
 	unsigned int port;
@@ -673,5 +679,5 @@
 				opResult);
 		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
-		return;
+		return opResult;
 	}
 	opResult = usb_hc_connection_open(&hub_info->connection);
@@ -681,5 +687,5 @@
 		usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
 		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
-		return;
+		return opResult;
 	}
 
@@ -697,4 +703,5 @@
 	usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
 	free(change_bitmap);
+	return EOK;
 }
 
Index: uspace/drv/usbhub/usbhub.h
===================================================================
--- uspace/drv/usbhub/usbhub.h	(revision bf588955990bc96fb7e6cbb94584ca020666f796)
+++ uspace/drv/usbhub/usbhub.h	(revision 4fa05a324a1c38f24d71dff2ffe3f7d22923a6ea)
@@ -87,8 +87,10 @@
 
 /**
- * check changes on specified hub
+ * Check changes on specified hub
  * @param hub_info_param pointer to usb_hub_info_t structure
+ * @return error code if there is problem when initializing communication with
+ * hub, EOK otherwise
  */
-void usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
+int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
 
 
