Index: uspace/drv/uhci-hcd/main.c
===================================================================
--- uspace/drv/uhci-hcd/main.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
+++ uspace/drv/uhci-hcd/main.c	(revision b9d910f478e726c33c5a0e72d0448d03b92734a0)
@@ -80,25 +80,4 @@
 };
 /*----------------------------------------------------------------------------*/
-static irq_cmd_t uhci_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_16,
-		.addr = (void*)0xc022,
-		.dstarg = 1
-	},
-	{
-		.cmd = CMD_PIO_WRITE_16,
-		.addr = (void*)0xc022,
-		.value = 0x1f
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-/*----------------------------------------------------------------------------*/
-static irq_code_t uhci_code = {
-	sizeof(uhci_cmds) / sizeof(irq_cmd_t),
-	uhci_cmds
-};
-/*----------------------------------------------------------------------------*/
 static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call)
 {
@@ -111,4 +90,10 @@
 }
 /*----------------------------------------------------------------------------*/
+#define CHECK_RET_RETURN(ret, message...) \
+if (ret != EOK) { \
+	usb_log_error(message); \
+	return ret; \
+}
+
 static int uhci_add_device(device_t *device)
 {
@@ -125,11 +110,7 @@
 	    pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
 
-	if (ret != EOK) {
-		usb_log_error(
-		    "Failed(%d) to get I/O registers addresses for device:.\n",
-		    ret, device->handle);
-		return ret;
-	}
-
+	CHECK_RET_RETURN(ret,
+	    "Failed(%d) to get I/O registers addresses for device:.\n",
+	    ret, device->handle);
 	usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
 	    io_reg_base, io_reg_size, irq);
@@ -158,23 +139,31 @@
 	async_hangup(irc_phone);
 
-	ret = register_interrupt_handler(device, irq, irq_handler, &uhci_code);
-	usb_log_debug("Registered interrupt handler %d.\n", ret);
 
 	uhci_t *uhci_hc = malloc(sizeof(uhci_t));
-	if (!uhci_hc) {
-		usb_log_error("Failed to allocate memory for uhci hcd driver.\n");
-		return ENOMEM;
-	}
+	ret = (uhci_hc != NULL) ? EOK : ENOMEM;
+	CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n");
 
 	ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
 	if (ret != EOK) {
 		usb_log_error("Failed to init uhci-hcd.\n");
+		free(uhci_hc);
 		return ret;
 	}
+
+	ret = register_interrupt_handler(device, irq, irq_handler,
+	    &uhci_hc->interrupt_code);
+	if (ret != EOK) {
+		usb_log_error("Failed to register interrupt handler.\n");
+		uhci_fini(uhci_hc);
+		free(uhci_hc);
+		return ret;
+	}
+
 	device_t *rh;
 	ret = setup_root_hub(&rh, device);
 	if (ret != EOK) {
 		usb_log_error("Failed to setup uhci root hub.\n");
-		/* TODO: destroy uhci here */
+		uhci_fini(uhci_hc);
+		free(uhci_hc);
 		return ret;
 	}
@@ -183,10 +172,11 @@
 	if (ret != EOK) {
 		usb_log_error("Failed to register root hub.\n");
-		/* TODO: destroy uhci here */
+		uhci_fini(uhci_hc);
+		free(uhci_hc);
+		free(rh);
 		return ret;
 	}
 
 	device->driver_data = uhci_hc;
-
 	return EOK;
 }
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
+++ uspace/drv/uhci-hcd/uhci.c	(revision b9d910f478e726c33c5a0e72d0448d03b92734a0)
@@ -39,4 +39,19 @@
 
 #include "uhci.h"
+static irq_cmd_t uhci_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_16,
+		.addr = (void*)0xc022,
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_PIO_WRITE_16,
+		.addr = (void*)0xc022,
+		.value = 0x1f
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
 
 static int uhci_init_transfer_lists(uhci_t *instance);
@@ -101,4 +116,17 @@
 {
 	assert(instance);
+
+	/* init interrupt code */
+	irq_cmd_t *interrupt_commands = malloc(sizeof(uhci_cmds));
+	if (interrupt_commands == NULL) {
+		return ENOMEM;
+	}
+	memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
+	interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
+	interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
+	instance->interrupt_code.cmds = interrupt_commands;
+	instance->interrupt_code.cmdcount =
+	    sizeof(uhci_cmds) / sizeof(irq_cmd_t);
+
 	/* init transfer lists */
 	int ret = uhci_init_transfer_lists(instance);
Index: uspace/drv/uhci-hcd/uhci.h
===================================================================
--- uspace/drv/uhci-hcd/uhci.h	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
+++ uspace/drv/uhci-hcd/uhci.h	(revision b9d910f478e726c33c5a0e72d0448d03b92734a0)
@@ -93,4 +93,6 @@
 	transfer_list_t *transfers[2][4];
 
+	irq_code_t interrupt_code;
+
 	fid_t cleaner;
 	fid_t debug_checker;
@@ -100,5 +102,5 @@
 int uhci_init(uhci_t *instance, void *regs, size_t reg_size);
 
-int uhci_fini(uhci_t *device);
+static inline void uhci_fini(uhci_t *instance) {};
 
 int uhci_transfer(
@@ -122,4 +124,5 @@
 	{ return (uhci_t*)dev->driver_data; }
 
+
 #endif
 /**
