Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision 93708847c264a615d93878fbe4d6a34cb417f359)
+++ uspace/drv/uhci-hcd/batch.c	(revision a963a68c154774ed90a34537f7983202b12ff550)
@@ -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 93708847c264a615d93878fbe4d6a34cb417f359)
+++ uspace/drv/uhci-hcd/batch.h	(revision a963a68c154774ed90a34537f7983202b12ff550)
@@ -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 93708847c264a615d93878fbe4d6a34cb417f359)
+++ uspace/drv/uhci-hcd/transfer_list.c	(revision a963a68c154774ed90a34537f7983202b12ff550)
@@ -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 93708847c264a615d93878fbe4d6a34cb417f359)
+++ uspace/drv/uhci-hcd/transfer_list.h	(revision a963a68c154774ed90a34537f7983202b12ff550)
@@ -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 93708847c264a615d93878fbe4d6a34cb417f359)
+++ uspace/drv/uhci-hcd/uhci_hc.c	(revision a963a68c154774ed90a34537f7983202b12ff550)
@@ -347,5 +347,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 +354,13 @@
 		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) {
+		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);
+		/* reinitialize hw, this triggers virtual disconnect*/
+		uhci_hc_init_hw(instance);
 	}
 }
