Index: uspace/lib/usbhost/include/usb/host/ddf_helpers.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision cb89430129f9d8d3b93b48217d53165f33b1774f)
+++ uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision 8cbc1670cebee160051351b4e0e6348c39e97c1c)
@@ -45,18 +45,31 @@
 #include <device/hw_res_parsed.h>
 
-typedef int (*driver_init_t)(hcd_t *, const hw_res_list_parsed_t *, bool);
+typedef int (*driver_init_t)(hcd_t *, const hw_res_list_parsed_t *);
+typedef int (*irq_code_gen_t)(irq_code_t *, hcd_t *, const hw_res_list_parsed_t *);
+typedef int (*claim_t)(hcd_t *, ddf_dev_t *);
+typedef int (*driver_start_t)(hcd_t *, bool irq);
+
+typedef void (*driver_stop_t)(hcd_t *);
 typedef void (*driver_fini_t)(hcd_t *);
-typedef int (*claim_t)(ddf_dev_t *);
-typedef int (*irq_code_gen_t)(irq_code_t *, const hw_res_list_parsed_t *);
 
+/**
+ * All callbacks are optional.
+ */
 typedef struct {
 	hcd_ops_t ops;
-	claim_t claim;
 	usb_speed_t hc_speed;
-	driver_init_t init;
-	driver_fini_t fini;
-	interrupt_handler_t *irq_handler;
-	irq_code_gen_t irq_code_gen;
 	const char *name;
+
+	interrupt_handler_t *irq_handler;  /**< Handler of IRQ. Do have generic implementation. */
+
+	/* Initialization sequence: */
+	driver_init_t init;                /**< Initialize internal structures, memory */
+	claim_t claim;                     /**< Claim device from BIOS */
+	irq_code_gen_t irq_code_gen;       /**< Generate IRQ handling code */
+	driver_start_t start;              /**< Start the HC */
+
+	/* Destruction sequence: */
+	driver_stop_t stop;                /**< Stop the HC (counterpart of start) */
+	driver_fini_t fini;                /**< Destroy internal structures (counterpart of init) */
 } ddf_hc_driver_t;
 
@@ -75,5 +88,5 @@
     const hw_res_list_parsed_t *hw_res,
     interrupt_handler_t handler,
-    int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *));
+    irq_code_gen_t gen_irq_code);
 void ddf_hcd_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev);
 
Index: uspace/lib/usbhost/src/ddf_helpers.c
===================================================================
--- uspace/lib/usbhost/src/ddf_helpers.c	(revision cb89430129f9d8d3b93b48217d53165f33b1774f)
+++ uspace/lib/usbhost/src/ddf_helpers.c	(revision 8cbc1670cebee160051351b4e0e6348c39e97c1c)
@@ -753,8 +753,10 @@
     const hw_res_list_parsed_t *hw_res,
     interrupt_handler_t handler,
-    int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *hw_res))
-{
-
+    irq_code_gen_t gen_irq_code)
+{
 	assert(device);
+
+	hcd_t *hcd = dev_to_hcd(device);
+
 	if (!handler || !gen_irq_code)
 		return ENOTSUP;
@@ -762,5 +764,5 @@
 	irq_code_t irq_code = {0};
 
-	const int irq = gen_irq_code(&irq_code, hw_res);
+	const int irq = gen_irq_code(&irq_code, hcd, hw_res);
 	if (irq < 0) {
 		usb_log_error("Failed to generate IRQ code: %s.\n",
@@ -878,32 +880,39 @@
 	if (ret != EOK) {
 		usb_log_error("Failed to setup generic HCD.\n");
-		hw_res_list_parsed_clean(&hw_res);
-		return ret;
-	}
-
+		goto err_hw_res;
+	}
+
+	hcd_t *hcd = dev_to_hcd(device);
+
+	if (driver->init)
+		ret = driver->init(hcd, &hw_res);
+	if (ret != EOK) {
+		usb_log_error("Failed to init HCD.\n");
+		goto err_hcd;
+	}
+
+	/* Setup interrupts  */
 	interrupt_handler_t *irq_handler =
 	    driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler;
-	const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler,
-	    driver->irq_code_gen);
+	const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler, driver->irq_code_gen);
 	if (!(irq < 0)) {
 		usb_log_debug("Hw interrupts enabled.\n");
 	}
 
+	/* Claim the device from BIOS */
 	if (driver->claim)
-		ret = driver->claim(device);
-	if (ret != EOK) {
-		usb_log_error("Failed to claim `%s' for driver `%s'",
-		    ddf_dev_get_name(device), driver->name);
-		return ret;
-	}
-
-
-	/* Init hw driver */
-	hcd_t *hcd = dev_to_hcd(device);
-	ret = driver->init(hcd, &hw_res, !(irq < 0));
-	hw_res_list_parsed_clean(&hw_res);
-	if (ret != EOK) {
-		usb_log_error("Failed to init HCD: %s.\n", str_error(ret));
-		goto irq_unregister;
+		ret = driver->claim(hcd, device);
+	if (ret != EOK) {
+		usb_log_error("Failed to claim `%s' for driver `%s': %s",
+		    ddf_dev_get_name(device), driver->name, str_error(ret));
+		goto err_irq;
+	}
+
+	/* Start hw driver */
+	if (driver->start)
+		ret = driver->start(hcd, !(irq < 0));
+	if (ret != EOK) {
+		usb_log_error("Failed to start HCD: %s.\n", str_error(ret));
+		goto err_irq;
 	}
 
@@ -914,5 +923,5 @@
 			usb_log_error("Failed to create polling fibril\n");
 			ret = ENOMEM;
-			goto irq_unregister;
+			goto err_started;
 		}
 		fibril_add_ready(hcd->polling_fibril);
@@ -929,10 +938,5 @@
 		usb_log_error("Failed to setup HC root hub: %s.\n",
 		    str_error(ret));
-		driver->fini(dev_to_hcd(device));
-irq_unregister:
-		/* Unregistering non-existent should be ok */
-		unregister_interrupt_handler(device, irq);
-		hcd_ddf_clean_hc(device);
-		return ret;
+		goto err_polling;
 	}
 
@@ -940,4 +944,20 @@
 	    driver->name, ddf_dev_get_name(device));
 	return EOK;
+	
+err_polling:
+	// TODO: Stop the polling fibril (refactor the interrupt_polling func)
+	//
+err_started:
+	if (driver->stop)
+		driver->stop(hcd);
+err_irq:
+	unregister_interrupt_handler(device, irq);
+	if (driver->fini)
+		driver->fini(hcd);
+err_hcd:
+	hcd_ddf_clean_hc(device);
+err_hw_res:
+	hw_res_list_parsed_clean(&hw_res);
+	return ret;
 }
 /**
