Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision f83666c85c38a93847c830fe6af1660249d56919)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision c53007f8f839360255b99edfba5f7a90acf0b96f)
@@ -90,20 +90,13 @@
 static int hc_debug_checker(void *arg);
 
-
-/** Get number of PIO ranges used in IRQ code.
- * @return Number of ranges.
- */
-size_t hc_irq_pio_range_count(void)
-{
-	return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t);
-}
-
-/** Get number of commands used in IRQ code.
- * @return Number of commands.
- */
-size_t hc_irq_cmd_count(void)
-{
-	return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t);
-}
+enum {
+	/** Number of PIO ranges used in IRQ code */
+	hc_irq_pio_range_count =
+	    sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t),
+
+	/* Number of commands used in IRQ code */
+	hc_irq_cmd_count =
+	    sizeof(uhci_irq_commands) / sizeof(irq_cmd_t)
+};
 
 /** Generate IRQ code.
@@ -133,4 +126,46 @@
 	cmds[0].addr = &registers->usbsts;
 	cmds[3].addr = &registers->usbsts;
+
+	return EOK;
+}
+
+/** Register interrupt handler.
+ *
+ * @param[in] device Host controller DDF device
+ * @param[in] reg_base Register range base
+ * @param[in] reg_size Register range size
+ * @param[in] irq Interrupt number
+ * @paran[in] handler Interrupt handler
+ *
+ * @return EOK on success or negative error code
+ */
+int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size,
+    int irq, interrupt_handler_t handler)
+{
+	int rc;
+	irq_pio_range_t irq_ranges[hc_irq_pio_range_count];
+	irq_cmd_t irq_cmds[hc_irq_cmd_count];
+	rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
+	    sizeof(irq_cmds), reg_base, reg_size);
+	if (rc != EOK) {
+		usb_log_error("Failed to generate IRQ commands: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+
+	irq_code_t irq_code = {
+		.rangecount = hc_irq_pio_range_count,
+		.ranges = irq_ranges,
+		.cmdcount = hc_irq_cmd_count,
+		.cmds = irq_cmds
+	};
+
+        /* Register handler to avoid interrupt lockup */
+        rc = register_interrupt_handler(device, irq, handler, &irq_code);
+        if (rc != EOK) {
+    		usb_log_error("Failed to register interrupt handler: %s.\n",
+    		    str_error(rc));
+    		return rc;
+    	}
 
 	return EOK;
@@ -209,11 +244,5 @@
 {
 	assert(reg_size >= sizeof(uhci_regs_t));
-	int ret;
-
-#define CHECK_RET_RETURN(ret, message...) \
-	if (ret != EOK) { \
-		usb_log_error(message); \
-		return ret; \
-	} else (void) 0
+	int rc;
 
 	instance->hw_interrupts = interrupts;
@@ -222,17 +251,21 @@
 	/* allow access to hc control registers */
 	uhci_regs_t *io;
-	ret = pio_enable(regs, reg_size, (void **)&io);
-	CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n",
-	    io, str_error(ret));
+	rc = pio_enable(regs, reg_size, (void **)&io);
+	if (rc != EOK) {
+		usb_log_error("Failed to gain access to registers at %p: %s.\n",
+		    io, str_error(rc));
+		return rc;
+	}
+
 	instance->registers = io;
 	usb_log_debug(
 	    "Device registers at %p (%zuB) accessible.\n", io, reg_size);
 
-	ret = hc_init_mem_structures(instance);
-	CHECK_RET_RETURN(ret,
-	    "Failed to initialize UHCI memory structures: %s.\n",
-	    str_error(ret));
-
-#undef CHECK_RET_RETURN
+	rc = hc_init_mem_structures(instance);
+	if (rc != EOK) {
+		usb_log_error("Failed to initialize UHCI memory structures: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
 
 	hcd_init(&instance->generic, USB_SPEED_FULL,
Index: uspace/drv/bus/usb/uhci/hc.h
===================================================================
--- uspace/drv/bus/usb/uhci/hc.h	(revision f83666c85c38a93847c830fe6af1660249d56919)
+++ uspace/drv/bus/usb/uhci/hc.h	(revision c53007f8f839360255b99edfba5f7a90acf0b96f)
@@ -36,4 +36,5 @@
 #define DRV_UHCI_HC_H
 
+#include <ddf/interrupt.h>
 #include <fibril.h>
 #include <usb/host/hcd.h>
@@ -119,6 +120,5 @@
 } hc_t;
 
-size_t hc_irq_pio_range_count(void);
-size_t hc_irq_cmd_count(void);
+int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t);
 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
     size_t);
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision f83666c85c38a93847c830fe6af1660249d56919)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision c53007f8f839360255b99edfba5f7a90acf0b96f)
@@ -38,4 +38,5 @@
 
 #include <errno.h>
+#include <stdbool.h>
 #include <str_error.h>
 #include <ddf/interrupt.h>
@@ -149,4 +150,9 @@
 int device_setup_uhci(ddf_dev_t *device)
 {
+	bool ih_registered = false;
+	bool hc_inited = false;
+	bool fun_bound = false;
+	int rc;
+
 	if (!device)
 		return EBADMEM;
@@ -158,25 +164,21 @@
 	}
 
-#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
-if (ret != EOK) { \
-	if (instance->hc_fun) \
-		ddf_fun_destroy(instance->hc_fun); \
-	if (instance->rh_fun) {\
-		ddf_fun_destroy(instance->rh_fun); \
-	} \
-	usb_log_error(message); \
-	return ret; \
-} else (void)0
-
-	instance->rh_fun = NULL;
 	instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci_hc");
-	int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
+	if (instance->hc_fun == NULL) {
+		usb_log_error("Failed to create UHCI HC function.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
 	ddf_fun_set_ops(instance->hc_fun, &hc_ops);
 	ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic);
 
 	instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh");
-	ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
+	if (instance->rh_fun == NULL) {
+		usb_log_error("Failed to create UHCI RH function.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
 	ddf_fun_set_ops(instance->rh_fun, &rh_ops);
 	ddf_fun_data_implant(instance->rh_fun, &instance->rh);
@@ -186,41 +188,34 @@
 	int irq = 0;
 
-	ret = get_my_registers(device, &reg_base, &reg_size, &irq);
-	CHECK_RET_DEST_FREE_RETURN(ret,
-	    "Failed to get I/O addresses for %" PRIun ": %s.\n",
-	    ddf_dev_get_handle(device), str_error(ret));
+	rc = get_my_registers(device, &reg_base, &reg_size, &irq);
+	if (rc != EOK) {
+		usb_log_error("Failed to get I/O addresses for %" PRIun ": %s.\n",
+		    ddf_dev_get_handle(device), str_error(rc));
+		goto error;
+	}
 	usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
 	    (void *) reg_base, reg_size, irq);
 
-	ret = disable_legacy(device);
-	CHECK_RET_DEST_FREE_RETURN(ret,
-	    "Failed to disable legacy USB: %s.\n", str_error(ret));
-
-	const size_t ranges_count = hc_irq_pio_range_count();
-	const size_t cmds_count = hc_irq_cmd_count();
-	irq_pio_range_t irq_ranges[ranges_count];
-	irq_cmd_t irq_cmds[cmds_count];
-	ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
-	    sizeof(irq_cmds), reg_base, reg_size);
-	CHECK_RET_DEST_FREE_RETURN(ret,
-	    "Failed to generate IRQ commands: %s.\n", str_error(ret));
-
-	irq_code_t irq_code = {
-		.rangecount = ranges_count,
-		.ranges = irq_ranges,
-		.cmdcount = cmds_count,
-		.cmds = irq_cmds
-	};
-
-        /* Register handler to avoid interrupt lockup */
-        ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
-        CHECK_RET_DEST_FREE_RETURN(ret,
-            "Failed to register interrupt handler: %s.\n", str_error(ret));
+	rc = disable_legacy(device);
+	if (rc != EOK) {
+		usb_log_error("Failed to disable legacy USB: %s.\n",
+		    str_error(rc));
+		goto error;
+	}
+
+	rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler);
+	if (rc != EOK) {
+		usb_log_error("Failed to register interrupt handler: %s.\n",
+		    str_error(rc));
+		goto error;
+	}
+
+	ih_registered = true;
 
 	bool interrupts = false;
-	ret = enable_interrupts(device);
-	if (ret != EOK) {
+	rc = enable_interrupts(device);
+	if (rc != EOK) {
 		usb_log_warning("Failed to enable interrupts: %s."
-		    " Falling back to polling.\n", str_error(ret));
+		    " Falling back to polling.\n", str_error(rc));
 	} else {
 		usb_log_debug("Hw interrupts enabled.\n");
@@ -228,34 +223,58 @@
 	}
 
-	ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
-	CHECK_RET_DEST_FREE_RETURN(ret,
-	    "Failed to init uhci_hcd: %s.\n", str_error(ret));
-
-#define CHECK_RET_FINI_RETURN(ret, message...) \
-if (ret != EOK) { \
-	hc_fini(&instance->hc); \
-	CHECK_RET_DEST_FREE_RETURN(ret, message); \
-	return ret; \
-} else (void)0
-
-	ret = ddf_fun_bind(instance->hc_fun);
-	CHECK_RET_FINI_RETURN(ret, "Failed to bind UHCI device function: %s.\n",
-	    str_error(ret));
-
-	ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed to add UHCI to HC class: %s.\n", str_error(ret));
-
-	ret = rh_init(&instance->rh, instance->rh_fun,
+	rc = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
+	if (rc != EOK) {
+		usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(rc));
+		goto error;
+	}
+
+	hc_inited = true;
+
+	rc = ddf_fun_bind(instance->hc_fun);
+	if (rc != EOK) {
+		usb_log_error("Failed to bind UHCI device function: %s.\n",
+		    str_error(rc));
+		goto error;
+	}
+
+	fun_bound = true;
+
+	rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
+	if (rc != EOK) {
+		usb_log_error("Failed to add UHCI to HC class: %s.\n",
+		    str_error(rc));
+		goto error;
+	}
+
+	rc = rh_init(&instance->rh, instance->rh_fun,
 	    (uintptr_t)instance->hc.registers + 0x10, 4);
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed to setup UHCI root hub: %s.\n", str_error(ret));
-
-	ret = ddf_fun_bind(instance->rh_fun);
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed to register UHCI root hub: %s.\n", str_error(ret));
+	if (rc != EOK) {
+		usb_log_error("Failed to setup UHCI root hub: %s.\n",
+		    str_error(rc));
+		goto error;
+	}
+
+	rc = ddf_fun_bind(instance->rh_fun);
+	if (rc != EOK) {
+		usb_log_error("Failed to register UHCI root hub: %s.\n",
+		    str_error(rc));
+		goto error;
+	}
 
 	return EOK;
-#undef CHECK_RET_FINI_RETURN
+
+error:
+	if (fun_bound)
+		ddf_fun_unbind(instance->hc_fun);
+	if (hc_inited)
+		hc_fini(&instance->hc);
+	if (ih_registered)
+		unregister_interrupt_handler(device, irq);
+	if (instance->hc_fun != NULL)
+		ddf_fun_destroy(instance->hc_fun);
+	if (instance->rh_fun != NULL) {
+		ddf_fun_destroy(instance->rh_fun);
+	}
+	return rc;
 }
 /**
Index: uspace/drv/bus/usb/uhcirh/main.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/main.c	(revision f83666c85c38a93847c830fe6af1660249d56919)
+++ uspace/drv/bus/usb/uhcirh/main.c	(revision c53007f8f839360255b99edfba5f7a90acf0b96f)
@@ -93,30 +93,32 @@
 	size_t io_size = 0;
 	uhci_root_hub_t *rh = NULL;
-	int ret = EOK;
+	int rc;
 
-#define CHECK_RET_FREE_RH_RETURN(ret, message...) \
-if (ret != EOK) { \
-	usb_log_error(message); \
-	return ret; \
-} else (void)0
+	rc = hc_get_my_registers(device, &io_regs, &io_size);
+	if (rc != EOK) {
+		usb_log_error( "Failed to get registers from HC: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
 
-	ret = hc_get_my_registers(device, &io_regs, &io_size);
-	CHECK_RET_FREE_RH_RETURN(ret,
-	    "Failed to get registers from HC: %s.\n", str_error(ret));
 	usb_log_debug("I/O regs at %p (size %zuB).\n",
 	    (void *) io_regs, io_size);
 
 	rh = ddf_dev_data_alloc(device, sizeof(uhci_root_hub_t));
-	ret = (rh == NULL) ? ENOMEM : EOK;
-	CHECK_RET_FREE_RH_RETURN(ret,
-	    "Failed to allocate rh driver instance.\n");
+	if (rh == NULL) {
+		usb_log_error("Failed to allocate rh driver instance.\n");
+		return ENOMEM;
+	}
 
-	ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
-	CHECK_RET_FREE_RH_RETURN(ret,
-	    "Failed(%d) to initialize rh driver instance: %s.\n",
-	    ret, str_error(ret));
+	rc = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
+	if (rc != EOK) {
+		usb_log_error("Failed(%d) to initialize rh driver instance: "
+		    "%s.\n", rc, str_error(rc));
+		return rc;
+	}
 
 	usb_log_info("Controlling root hub '%s' (%" PRIun ").\n",
 	    ddf_dev_get_name(device), ddf_dev_get_handle(device));
+
 	return EOK;
 }
Index: uspace/drv/bus/usb/uhcirh/port.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/port.c	(revision f83666c85c38a93847c830fe6af1660249d56919)
+++ uspace/drv/bus/usb/uhcirh/port.c	(revision c53007f8f839360255b99edfba5f7a90acf0b96f)
@@ -150,18 +150,8 @@
 {
 	uhci_port_t *instance = port;
+	int rc;
 	assert(instance);
 
 	unsigned allowed_failures = MAX_ERROR_COUNT;
-#define CHECK_RET_FAIL(ret, msg...) \
-	if (ret != EOK) { \
-		usb_log_error(msg); \
-		if (!(allowed_failures-- > 0)) { \
-			usb_log_fatal( \
-			   "Maximum number of failures reached, " \
-			   "bailing out.\n"); \
-			return ret; \
-		} \
-		continue; \
-	} else (void)0
 
 	while (1) {
@@ -182,7 +172,12 @@
 		    instance->id_string, port_status);
 
-		int ret = usb_hc_connection_open(&instance->hc_connection);
-		CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n",
-		    instance->id_string, str_error(ret));
+		rc = usb_hc_connection_open(&instance->hc_connection);
+		if (rc != EOK) {
+			usb_log_error("%s: Failed to connect to HC %s.\n",
+			    instance->id_string, str_error(rc));
+			if (!(allowed_failures-- > 0))
+				goto fatal_error;
+			continue;
+		}
 
 		/* Remove any old device */
@@ -204,9 +199,19 @@
 		}
 
-		ret = usb_hc_connection_close(&instance->hc_connection);
-		CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n",
-		    instance->id_string, str_error(ret));
-	}
-	return EOK;
+		rc = usb_hc_connection_close(&instance->hc_connection);
+		if (rc != EOK) {
+			usb_log_error("%s: Failed to disconnect from HC %s.\n",
+			    instance->id_string, str_error(rc));
+			if (!(allowed_failures-- > 0))
+				goto fatal_error;
+			continue;
+		}
+	}
+
+	return EOK;
+
+fatal_error:
+	usb_log_fatal("Maximum number of failures reached, bailing out.\n");
+	return rc;
 }
 
