Index: uspace/drv/bus/usb/ehci/ehci_endpoint.c
===================================================================
--- uspace/drv/bus/usb/ehci/ehci_endpoint.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/ehci/ehci_endpoint.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -80,4 +80,6 @@
 {
 	assert(ep);
+	hc_t *hc = hcd_get_driver_data(hcd);
+
 	ehci_endpoint_t *ehci_ep = malloc(sizeof(ehci_endpoint_t));
 	if (ehci_ep == NULL)
@@ -95,5 +97,5 @@
 	endpoint_set_hc_data(
 	    ep, ehci_ep, ehci_ep_toggle_get, ehci_ep_toggle_set);
-	hc_enqueue_endpoint(hcd->driver.data, ep);
+	hc_enqueue_endpoint(hc, ep);
 	return EOK;
 }
@@ -108,6 +110,8 @@
 	assert(hcd);
 	assert(ep);
+	hc_t *hc = hcd_get_driver_data(hcd);
+
 	ehci_endpoint_t *instance = ehci_endpoint_get(ep);
-	hc_dequeue_endpoint(hcd->driver.data, ep);
+	hc_dequeue_endpoint(hc, ep);
 	endpoint_clear_hc_data(ep);
 	usb_log_debug2("EP(%p): Destroying for %p", instance, ep);
Index: uspace/drv/bus/usb/ehci/hc.c
===================================================================
--- uspace/drv/bus/usb/ehci/hc.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/ehci/hc.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -273,5 +273,5 @@
 {
 	assert(hcd);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	assert(instance);
 	assert(status);
@@ -294,5 +294,5 @@
 {
 	assert(hcd);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	assert(instance);
 
@@ -325,5 +325,5 @@
 {
 	assert(hcd);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	status = EHCI_RD(status);
 	assert(instance);
Index: uspace/drv/bus/usb/ehci/main.c
===================================================================
--- uspace/drv/bus/usb/ehci/main.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/ehci/main.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -50,8 +50,28 @@
 #define NAME "ehci"
 
+static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
+static void ehci_driver_fini(hcd_t *);
+
+static const ddf_hc_driver_t ehci_hc_driver = {
+	.claim = disable_legacy,
+	.hc_speed = USB_SPEED_HIGH,
+	.irq_code_gen = ehci_hc_gen_irq_code,
+	.init = ehci_driver_init,
+	.fini = ehci_driver_fini,
+	.name = "EHCI-PCI",
+	.ops = {
+		.schedule       = ehci_hc_schedule,
+		.ep_add_hook    = ehci_endpoint_init,
+		.ep_remove_hook = ehci_endpoint_fini,
+		.irq_hook       = ehci_hc_interrupt,
+		.status_hook    = ehci_hc_status,
+	}
+};
+
+
 static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
 {
 	assert(hcd);
-	assert(hcd->driver.data == NULL);
+	assert(hcd_get_driver_data(hcd) == NULL);
 
 	hc_t *instance = malloc(sizeof(hc_t));
@@ -61,7 +81,5 @@
 	const int ret = hc_init(instance, res, irq);
 	if (ret == EOK)
-		hcd_set_implementation(hcd, instance, ehci_hc_schedule,
-		    ehci_endpoint_init, ehci_endpoint_fini, ehci_hc_interrupt,
-		    ehci_hc_status);
+		hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops);
 	return ret;
 }
@@ -70,31 +88,11 @@
 {
 	assert(hcd);
-	if (hcd->driver.data)
-		hc_fini(hcd->driver.data);
+	hc_t *hc = hcd_get_driver_data(hcd);
+	if (hc)
+		hc_fini(hc);
 
-	free(hcd->driver.data);
-	hcd_set_implementation(hcd, NULL, NULL, NULL, NULL, NULL, NULL);
+	free(hc);
+	hcd_set_implementation(hcd, NULL, NULL);
 }
-
-static int ehci_dev_add(ddf_dev_t *device);
-
-static const driver_ops_t ehci_driver_ops = {
-	.dev_add = ehci_dev_add,
-};
-
-static const driver_t ehci_driver = {
-	.name = NAME,
-	.driver_ops = &ehci_driver_ops
-};
-
-
-static const ddf_hc_driver_t ehci_hc_driver = {
-	.claim = disable_legacy,
-	.hc_speed = USB_SPEED_HIGH,
-	.irq_code_gen = ehci_hc_gen_irq_code,
-	.init = ehci_driver_init,
-	.fini = ehci_driver_fini,
-	.name = "EHCI-PCI"
-};
 
 /** Initializes a new ddf driver instance of EHCI hcd.
@@ -111,4 +109,15 @@
 
 }
+
+
+static const driver_ops_t ehci_driver_ops = {
+	.dev_add = ehci_dev_add,
+};
+
+static const driver_t ehci_driver = {
+	.name = NAME,
+	.driver_ops = &ehci_driver_ops
+};
+
 
 /** Initializes global driver structures (NONE).
Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -271,5 +271,5 @@
 	assert(hcd);
 	assert(status);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	assert(instance);
 
@@ -290,5 +290,5 @@
 {
 	assert(hcd);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	assert(instance);
 
@@ -330,5 +330,5 @@
 {
 	assert(hcd);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	status = OHCI_RD(status);
 	assert(instance);
Index: uspace/drv/bus/usb/ohci/main.c
===================================================================
--- uspace/drv/bus/usb/ohci/main.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/ohci/main.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -46,9 +46,27 @@
 
 #define NAME "ohci"
+static int ohci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
+static void ohci_driver_fini(hcd_t *);
+
+static const ddf_hc_driver_t ohci_hc_driver = {
+        .hc_speed = USB_SPEED_FULL,
+        .irq_code_gen = ohci_hc_gen_irq_code,
+        .init = ohci_driver_init,
+        .fini = ohci_driver_fini,
+        .name = "OHCI",
+	.ops = {
+                .schedule       = ohci_hc_schedule,
+                .ep_add_hook    = ohci_endpoint_init,
+                .ep_remove_hook = ohci_endpoint_fini,
+                .irq_hook       = ohci_hc_interrupt,
+                .status_hook    = ohci_hc_status,
+	},
+};
+
 
 static int ohci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
 {
 	assert(hcd);
-	assert(hcd->driver.data == NULL);
+	assert(hcd_get_driver_data(hcd) == NULL);
 
 	hc_t *instance = malloc(sizeof(hc_t));
@@ -58,7 +76,5 @@
 	const int ret = hc_init(instance, res, irq);
 	if (ret == EOK)
-		hcd_set_implementation(hcd, instance, ohci_hc_schedule,
-		    ohci_endpoint_init, ohci_endpoint_fini, ohci_hc_interrupt,
-		    ohci_hc_status);
+		hcd_set_implementation(hcd, instance, &ohci_hc_driver.ops);
 	return ret;
 }
@@ -67,18 +83,11 @@
 {
 	assert(hcd);
-	if (hcd->driver.data)
-		hc_fini(hcd->driver.data);
+	hc_t *hc = hcd_get_driver_data(hcd);
+	if (hc)
+		hc_fini(hc);
 
-	free(hcd->driver.data);
-	hcd_set_implementation(hcd, NULL, NULL, NULL, NULL, NULL, NULL);
+	hcd_set_implementation(hcd, NULL, NULL);
+	free(hc);
 }
-
-static const ddf_hc_driver_t ohci_hc_driver = {
-        .hc_speed = USB_SPEED_FULL,
-        .irq_code_gen = ohci_hc_gen_irq_code,
-        .init = ohci_driver_init,
-        .fini = ohci_driver_fini,
-        .name = "OHCI"
-};
 
 /** Initializes a new ddf driver instance of OHCI hcd.
Index: uspace/drv/bus/usb/ohci/ohci_endpoint.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_endpoint.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/ohci/ohci_endpoint.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -95,5 +95,5 @@
 	endpoint_set_hc_data(
 	    ep, ohci_ep, ohci_ep_toggle_get, ohci_ep_toggle_set);
-	hc_enqueue_endpoint(hcd->driver.data, ep);
+	hc_enqueue_endpoint(hcd_get_driver_data(hcd), ep);
 	return EOK;
 }
@@ -109,5 +109,6 @@
 	assert(ep);
 	ohci_endpoint_t *instance = ohci_endpoint_get(ep);
-	hc_dequeue_endpoint(hcd->driver.data, ep);
+	hc_dequeue_endpoint(hcd_get_driver_data(hcd), ep);
+	endpoint_clear_hc_data(ep);
 	if (instance) {
 		free32(instance->ed);
@@ -115,5 +116,4 @@
 		free(instance);
 	}
-	endpoint_clear_hc_data(ep);
 }
 /**
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -157,5 +157,5 @@
 {
 	assert(hcd);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	assert(instance);
 	/* Lower 2 bits are transaction error and transaction complete */
@@ -412,5 +412,5 @@
 	assert(hcd);
 	assert(status);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	assert(instance);
 
@@ -435,5 +435,5 @@
 {
 	assert(hcd);
-	hc_t *instance = hcd->driver.data;
+	hc_t *instance = hcd_get_driver_data(hcd);
 	assert(instance);
 	assert(batch);
Index: uspace/drv/bus/usb/uhci/main.c
===================================================================
--- uspace/drv/bus/usb/uhci/main.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/uhci/main.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -48,8 +48,26 @@
 #define NAME "uhci"
 
+static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
+static void uhci_driver_fini(hcd_t *);
+static int disable_legacy(ddf_dev_t *);
+
+static const ddf_hc_driver_t uhci_hc_driver = {
+        .claim = disable_legacy,
+        .hc_speed = USB_SPEED_FULL,
+        .irq_code_gen = uhci_hc_gen_irq_code,
+        .init = uhci_driver_init,
+        .fini = uhci_driver_fini,
+        .name = "UHCI",
+	.ops = {
+		.schedule    = uhci_hc_schedule,
+		.irq_hook    = uhci_hc_interrupt,
+		.status_hook = uhci_hc_status,
+	},
+};
+
 static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
 {
 	assert(hcd);
-	assert(hcd->driver.data == NULL);
+	assert(hcd_get_driver_data(hcd) == NULL);
 
 	hc_t *instance = malloc(sizeof(hc_t));
@@ -59,6 +77,5 @@
 	const int ret = hc_init(instance, res, irq);
 	if (ret == EOK)
-		hcd_set_implementation(hcd, instance, uhci_hc_schedule, NULL,
-		    NULL, uhci_hc_interrupt, uhci_hc_status);
+		hcd_set_implementation(hcd, instance, &uhci_hc_driver.ops);
 	return ret;
 }
@@ -67,21 +84,11 @@
 {
 	assert(hcd);
-	if (hcd->driver.data)
-		hc_fini(hcd->driver.data);
+	hc_t *hc = hcd_get_driver_data(hcd);
+	if (hc)
+		hc_fini(hc);
 
-	free(hcd->driver.data);
-	hcd_set_implementation(hcd, NULL, NULL, NULL, NULL, NULL, NULL);
+	hcd_set_implementation(hcd, NULL, NULL);
+	free(hc);
 }
-
-static int uhci_dev_add(ddf_dev_t *device);
-
-static const driver_ops_t uhci_driver_ops = {
-	.dev_add = uhci_dev_add,
-};
-
-static const driver_t uhci_driver = {
-	.name = NAME,
-	.driver_ops = &uhci_driver_ops
-};
 
 /** Call the PCI driver with a request to clear legacy support register
@@ -106,13 +113,4 @@
 	return rc;
 }
-static const ddf_hc_driver_t uhci_hc_driver = {
-        .claim = disable_legacy,
-        .hc_speed = USB_SPEED_FULL,
-        .irq_code_gen = uhci_hc_gen_irq_code,
-        .init = uhci_driver_init,
-        .fini = uhci_driver_fini,
-        .name = "UHCI"
-};
-
 
 /** Initialize a new ddf driver instance for uhci hc and hub.
@@ -121,5 +119,5 @@
  * @return Error code.
  */
-int uhci_dev_add(ddf_dev_t *device)
+static int uhci_dev_add(ddf_dev_t *device)
 {
 	usb_log_debug2("uhci_dev_add() called\n");
@@ -127,4 +125,14 @@
 	return hcd_ddf_add_hc(device, &uhci_hc_driver);
 }
+
+static const driver_ops_t uhci_driver_ops = {
+	.dev_add = uhci_dev_add,
+};
+
+static const driver_t uhci_driver = {
+	.name = NAME,
+	.driver_ops = &uhci_driver_ops
+};
+
 
 /** Initialize global driver structures (NONE).
Index: uspace/drv/bus/usb/vhc/main.c
===================================================================
--- uspace/drv/bus/usb/vhc/main.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/vhc/main.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -74,4 +74,8 @@
 }
 
+hcd_ops_t vhc_hc_ops = {
+	.schedule = vhc_schedule,
+};
+
 static int vhc_dev_add(ddf_dev_t *dev)
 {
@@ -95,5 +99,5 @@
 	}
 
-	hcd_set_implementation(dev_to_hcd(dev), data, vhc_schedule, NULL, NULL, NULL, NULL);
+	hcd_set_implementation(dev_to_hcd(dev), data, &vhc_hc_ops);
 
 	/* Add virtual hub device */
Index: uspace/drv/bus/usb/vhc/transfer.c
===================================================================
--- uspace/drv/bus/usb/vhc/transfer.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/drv/bus/usb/vhc/transfer.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -167,5 +167,5 @@
 	assert(hcd);
 	assert(batch);
-	vhc_data_t *vhc = hcd->driver.data;
+	vhc_data_t *vhc = hcd_get_driver_data(hcd);
 	assert(vhc);
 
Index: uspace/lib/usbhost/include/usb/host/ddf_helpers.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -51,5 +51,5 @@
 
 typedef struct {
-	hc_driver_t ops;
+	hcd_ops_t ops;
 	claim_t claim;
 	usb_speed_t hc_speed;
Index: uspace/lib/usbhost/include/usb/host/hcd.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/hcd.h	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/lib/usbhost/include/usb/host/hcd.h	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -55,6 +55,4 @@
 
 typedef struct {
-	/** Device specific driver data. */
-	void *data;
 	/** Transfer scheduling, implement in device driver. */
 	schedule_hook_t schedule;
@@ -67,5 +65,5 @@
 	/** Periodic polling hook */
 	status_hook_t status_hook;
-} hc_driver_t;
+} hcd_ops_t;
 
 /** Generic host controller driver structure. */
@@ -74,9 +72,11 @@
 	usb_bus_t bus;
 
-	/** Driver implementation */
-	hc_driver_t driver;
-
 	/** Interrupt replacement fibril */
 	fid_t polling_fibril;
+
+	/** Driver implementation */
+	hcd_ops_t ops;
+	/** Device specific driver data. */
+	void * driver_data;
 };
 
@@ -85,14 +85,19 @@
 
 static inline void hcd_set_implementation(hcd_t *hcd, void *data,
-    schedule_hook_t schedule, ep_add_hook_t add_hook, ep_remove_hook_t rem_hook,
-    interrupt_hook_t irq_hook, status_hook_t status_hook)
+    const hcd_ops_t *ops)
 {
 	assert(hcd);
-	hcd->driver.data = data;
-	hcd->driver.schedule = schedule;
-	hcd->driver.ep_add_hook = add_hook;
-	hcd->driver.ep_remove_hook = rem_hook;
-	hcd->driver.irq_hook = irq_hook;
-	hcd->driver.status_hook = status_hook;
+	if (ops) {
+		hcd->driver_data = data;
+		hcd->ops = *ops;
+	} else {
+		memset(&hcd->ops, 0, sizeof(hcd->ops));
+	}
+}
+
+static inline void * hcd_get_driver_data(hcd_t *hcd)
+{
+	assert(hcd);
+	return hcd->driver_data;
 }
 
Index: uspace/lib/usbhost/src/ddf_helpers.c
===================================================================
--- uspace/lib/usbhost/src/ddf_helpers.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/lib/usbhost/src/ddf_helpers.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -690,4 +690,5 @@
 }
 
+//TODO: Move this to generic ddf?
 int hcd_ddf_get_registers(ddf_dev_t *device, hw_res_list_parsed_t *hw_res)
 {
@@ -779,10 +780,10 @@
 	assert(dev);
 	hcd_t *hcd = dev_to_hcd(dev);
-	if (!hcd || !hcd->driver.irq_hook) {
+	if (!hcd || !hcd->ops.irq_hook) {
 		usb_log_error("Interrupt on not yet initialized device.\n");
 		return;
 	}
 	const uint32_t status = IPC_GET_ARG1(*call);
-	hcd->driver.irq_hook(hcd, status);
+	hcd->ops.irq_hook(hcd, status);
 }
 
@@ -791,9 +792,9 @@
 	hcd_t *hcd = arg;
 	assert(hcd);
-	if (!hcd->driver.status_hook || !hcd->driver.irq_hook)
+	if (!hcd->ops.status_hook || !hcd->ops.irq_hook)
 		return ENOTSUP;
 	uint32_t status = 0;
-	while (hcd->driver.status_hook(hcd, &status) == EOK) {
-		hcd->driver.irq_hook(hcd, status);
+	while (hcd->ops.status_hook(hcd, &status) == EOK) {
+		hcd->ops.irq_hook(hcd, status);
 		status = 0;
 		/* We should wait 1 frame - 1ms here, but this polling is a
@@ -885,5 +886,5 @@
 
 	/* Need working irq replacement to setup root hub */
-	if ((irq < 0) && hcd->driver.status_hook) {
+	if ((irq < 0) && hcd->ops.status_hook) {
 		hcd->polling_fibril = fibril_create(interrupt_polling, hcd);
 		if (hcd->polling_fibril == 0) {
Index: uspace/lib/usbhost/src/hcd.c
===================================================================
--- uspace/lib/usbhost/src/hcd.c	(revision 2dbfe4497342c4c6132143d23bc5b2c8239479cf)
+++ uspace/lib/usbhost/src/hcd.c	(revision b5f813c78023578df239717fa27402f0915a7610)
@@ -54,6 +54,6 @@
 	assert(ep);
 	assert(hcd);
-	if (hcd->driver.ep_add_hook)
-		return hcd->driver.ep_add_hook(hcd, ep);
+	if (hcd->ops.ep_add_hook)
+		return hcd->ops.ep_add_hook(hcd, ep);
 	return EOK;
 }
@@ -68,6 +68,6 @@
 	assert(ep);
 	assert(hcd);
-	if (hcd->driver.ep_remove_hook)
-		hcd->driver.ep_remove_hook(hcd, ep);
+	if (hcd->ops.ep_remove_hook)
+		hcd->ops.ep_remove_hook(hcd, ep);
 }
 
@@ -99,8 +99,5 @@
 	usb_bus_init(&hcd->bus, bandwidth, bw_count, max_speed);
 
-	hcd->driver.data = NULL;
-	hcd->driver.schedule = NULL;
-	hcd->driver.ep_add_hook = NULL;
-	hcd->driver.ep_remove_hook = NULL;
+	hcd_set_implementation(hcd, NULL, NULL);
 }
 
@@ -127,6 +124,5 @@
 	assert(hcd);
 	usb_address_t address = 0;
-	return usb_bus_request_address(
-	    &hcd->bus, &address, true, speed);
+	return usb_bus_request_address(&hcd->bus, &address, true, speed);
 }
 
@@ -209,5 +205,5 @@
 		return ENOSPC;
 	}
-	if (!hcd->driver.schedule) {
+	if (!hcd->ops.schedule) {
 		usb_log_error("HCD does not implement scheduler.\n");
 		return ENOTSUP;
@@ -241,5 +237,5 @@
 	}
 
-	const int ret = hcd->driver.schedule(hcd, batch);
+	const int ret = hcd->ops.schedule(hcd, batch);
 	if (ret != EOK)
 		usb_transfer_batch_destroy(batch);
