Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision 4125b7d6623fde4fc0b0dfa664848db2d491c2b9)
+++ uspace/drv/uhci-hcd/uhci.c	(revision d2bff2f14a4df1b66541e1f560f9eba303514e2d)
@@ -44,4 +44,28 @@
 #include "pci.h"
 
+#include "hc.h"
+#include "root_hub.h"
+
+/** Structure representing both functions of UHCI hc, USB host controller
+ * and USB root hub */
+typedef struct uhci {
+	/** Pointer to DDF represenation of UHCI host controller */
+	ddf_fun_t *hc_fun;
+	/** Pointer to DDF represenation of UHCI root hub */
+	ddf_fun_t *rh_fun;
+
+	/** Internal driver's represenation of UHCI host controller */
+	hc_t hc;
+	/** Internal driver's represenation of UHCI root hub */
+	rh_t rh;
+} uhci_t;
+
+static inline uhci_t * dev_to_uhci(ddf_dev_t *dev)
+{
+	assert(dev);
+	assert(dev->driver_data);
+	return dev->driver_data;
+}
+/*----------------------------------------------------------------------------*/
 /** IRQ handling callback, forward status from call to diver structure.
  *
@@ -69,8 +93,7 @@
 {
 	assert(fun);
-	usb_device_keeper_t *manager =
-	    &((uhci_t*)fun->dev->driver_data)->hc.manager;
-
+	usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager;
 	usb_address_t addr = usb_device_keeper_find(manager, handle);
+
 	if (addr < 0) {
 		return addr;
@@ -93,9 +116,10 @@
     ddf_fun_t *fun, devman_handle_t *handle)
 {
-	assert(handle);
-	ddf_fun_t *hc_fun = ((uhci_t*)fun->dev->driver_data)->hc_fun;
-	assert(hc_fun != NULL);
-
-	*handle = hc_fun->handle;
+	assert(fun);
+	ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun;
+	assert(hc_fun);
+
+	if (handle != NULL)
+		*handle = hc_fun->handle;
 	return EOK;
 }
@@ -126,5 +150,5 @@
 static hw_res_ops_t hw_res_iface = {
 	.get_resource_list = get_resource_list,
-	.enable_interrupt = NULL
+	.enable_interrupt = NULL,
 };
 /*----------------------------------------------------------------------------*/
@@ -146,33 +170,55 @@
  *  - registers interrupt handler
  */
-int uhci_init(uhci_t *instance, ddf_dev_t *device)
-{
-	assert(instance);
-	instance->hc_fun = NULL;
+int device_setup_uhci(ddf_dev_t *device)
+{
+	assert(device);
+	uhci_t *instance = malloc(sizeof(uhci_t));
+	if (instance == NULL) {
+		usb_log_error("Failed to allocate OHCI driver.\n");
+		return ENOMEM;
+	}
+
+#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
+if (ret != EOK) { \
+	if (instance->hc_fun) \
+		instance->hc_fun->ops = NULL; \
+		instance->hc_fun->driver_data = NULL; \
+		ddf_fun_destroy(instance->hc_fun); \
+	if (instance->rh_fun) {\
+		instance->rh_fun->ops = NULL; \
+		instance->rh_fun->driver_data = NULL; \
+		ddf_fun_destroy(instance->rh_fun); \
+	} \
+	free(instance); \
+	usb_log_error(message); \
+	return ret; \
+} else (void)0
+
 	instance->rh_fun = NULL;
-#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
-if (ret != EOK) { \
-	usb_log_error(message); \
-	if (instance->hc_fun) \
-		ddf_fun_destroy(instance->hc_fun); \
-	if (instance->rh_fun) \
-		ddf_fun_destroy(instance->rh_fun); \
-	return ret; \
-}
-
-	uintptr_t io_reg_base = 0;
-	size_t io_reg_size = 0;
+	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");
+	instance->hc_fun->ops = &hc_ops;
+	instance->hc_fun->driver_data = &instance->hc;
+
+	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");
+	instance->rh_fun->ops = &rh_ops;
+	instance->rh_fun->driver_data = &instance->rh;
+
+	uintptr_t reg_base = 0;
+	size_t reg_size = 0;
 	int irq = 0;
 
-	int ret =
-	    pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
-	CHECK_RET_DEST_FUN_RETURN(ret,
+	ret = pci_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",
 	    device->handle, str_error(ret));
 	usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
-	    (void *) io_reg_base, io_reg_size, irq);
+	    (void *) reg_base, reg_size, irq);
 
 	ret = pci_disable_legacy(device);
-	CHECK_RET_DEST_FUN_RETURN(ret,
+	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
 
@@ -194,32 +240,15 @@
 #endif
 
-	instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
-	ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_DEST_FUN_RETURN(ret,
-	    "Failed(%d) to create HC function: %s.\n", ret, str_error(ret));
-
-	ret = hc_init(&instance->hc, instance->hc_fun,
-	    (void*)io_reg_base, io_reg_size, interrupts);
-	CHECK_RET_DEST_FUN_RETURN(ret,
+
+	ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
+	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed(%d) to init uhci-hcd: %s.\n", ret, str_error(ret));
-
-	instance->hc_fun->ops = &hc_ops;
-	instance->hc_fun->driver_data = &instance->hc;
-	ret = ddf_fun_bind(instance->hc_fun);
-	CHECK_RET_DEST_FUN_RETURN(ret,
-	    "Failed(%d) to bind UHCI device function: %s.\n",
-	    ret, str_error(ret));
-#undef CHECK_RET_HC_RETURN
 
 #define CHECK_RET_FINI_RETURN(ret, message...) \
 if (ret != EOK) { \
-	usb_log_error(message); \
-	if (instance->hc_fun) \
-		ddf_fun_destroy(instance->hc_fun); \
-	if (instance->rh_fun) \
-		ddf_fun_destroy(instance->rh_fun); \
 	hc_fini(&instance->hc); \
+	CHECK_RET_DEST_FREE_RETURN(ret, message); \
 	return ret; \
-}
+} else (void)0
 
 	/* It does no harm if we register this on polling */
@@ -230,8 +259,7 @@
 	    ret, str_error(ret));
 
-	instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
-	ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed(%d) to create root hub function: %s.\n",
+	ret = ddf_fun_bind(instance->hc_fun);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed(%d) to bind UHCI device function: %s.\n",
 	    ret, str_error(ret));
 
@@ -241,10 +269,9 @@
 	    "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret));
 
-	instance->rh_fun->ops = &rh_ops;
-	instance->rh_fun->driver_data = &instance->rh;
 	ret = ddf_fun_bind(instance->rh_fun);
 	CHECK_RET_FINI_RETURN(ret,
 	    "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret));
 
+	device->driver_data = instance;
 	return EOK;
 #undef CHECK_RET_FINI_RETURN
