Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision 36a4738785c51e127601de2dfe27d687cf316117)
+++ uspace/drv/uhci-hcd/batch.c	(revision 30a4301d6b681aa121009add6826cf9a58c6aa09)
@@ -248,4 +248,6 @@
 	}
 
+	instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
+
 	instance->next_step = batch_call_in_and_dispose;
 	batch_schedule(instance);
@@ -272,4 +274,6 @@
 	}
 
+	instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
+
 	instance->next_step = batch_call_out_and_dispose;
 	batch_schedule(instance);
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision 36a4738785c51e127601de2dfe27d687cf316117)
+++ uspace/drv/uhci-hcd/uhci.c	(revision 30a4301d6b681aa121009add6826cf9a58c6aa09)
@@ -44,5 +44,5 @@
 static void uhci_init_hw(uhci_t *instance);
 
-static int uhci_clean_finished(void *arg);
+static int uhci_interrupt_emulator(void *arg);
 static int uhci_debug_checker(void *arg);
 
@@ -69,5 +69,5 @@
 	usb_log_debug("Device registers accessible.\n");
 
-	instance->cleaner = fibril_create(uhci_clean_finished, instance);
+	instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
 	fibril_add_ready(instance->cleaner);
 
@@ -189,15 +189,26 @@
 }
 /*----------------------------------------------------------------------------*/
-int uhci_clean_finished(void* arg)
-{
-	usb_log_debug("Started cleaning fibril.\n");
+void uhci_interrupt(uhci_t *instance)
+{
+	assert(instance);
+	const uint16_t sts = pio_read_16(&instance->registers->usbsts);
+	if ((sts & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
+		return;
+	usb_log_debug("UHCI interrupt: %X.\n", sts);
+	transfer_list_check(&instance->transfers_interrupt);
+	transfer_list_check(&instance->transfers_control_slow);
+	transfer_list_check(&instance->transfers_control_full);
+	transfer_list_check(&instance->transfers_bulk_full);
+	pio_write_16(&instance->registers->usbsts, 0xf);
+}
+/*----------------------------------------------------------------------------*/
+int uhci_interrupt_emulator(void* arg)
+{
+	usb_log_debug("Started interrupt emulator.\n");
 	uhci_t *instance = (uhci_t*)arg;
 	assert(instance);
 
 	while(1) {
-		transfer_list_check(&instance->transfers_interrupt);
-		transfer_list_check(&instance->transfers_control_slow);
-		transfer_list_check(&instance->transfers_control_full);
-		transfer_list_check(&instance->transfers_bulk_full);
+		uhci_interrupt(instance);
 		async_usleep(UHCI_CLEANER_TIMEOUT);
 	}
Index: uspace/drv/uhci-hcd/uhci.h
===================================================================
--- uspace/drv/uhci-hcd/uhci.h	(revision 36a4738785c51e127601de2dfe27d687cf316117)
+++ uspace/drv/uhci-hcd/uhci.h	(revision 30a4301d6b681aa121009add6826cf9a58c6aa09)
@@ -117,4 +117,6 @@
 int uhci_schedule(uhci_t *instance, batch_t *batch);
 
+void uhci_interrupt(uhci_t *instance);
+
 static inline uhci_t * dev_to_uhci(device_t *dev)
 	{ return (uhci_t*)dev->driver_data; }
