Index: uspace/drv/bus/usb/ohci/Makefile
===================================================================
--- uspace/drv/bus/usb/ohci/Makefile	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/ohci/Makefile	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -49,5 +49,5 @@
 	main.c \
 	ohci_batch.c \
-	ohci_endpoint.c \
+	ohci_bus.c \
 	ohci_rh.c \
 	hw_struct/endpoint_descriptor.c \
Index: uspace/drv/bus/usb/ohci/endpoint_list.h
===================================================================
--- uspace/drv/bus/usb/ohci/endpoint_list.h	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/ohci/endpoint_list.h	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -41,5 +41,5 @@
 #include <usb/host/utils/malloc32.h>
 
-#include "ohci_endpoint.h"
+#include "ohci_bus.h"
 #include "hw_struct/endpoint_descriptor.h"
 
Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -47,5 +47,5 @@
 #include <usb/usb.h>
 
-#include "ohci_endpoint.h"
+#include "ohci_bus.h"
 #include "ohci_batch.h"
 
@@ -287,5 +287,5 @@
 
 	/* Check for root hub communication */
-	if (batch->ep->address == ohci_rh_get_address(&instance->rh)) {
+	if (batch->ep->target.address == ohci_rh_get_address(&instance->rh)) {
 		usb_log_debug("OHCI root hub request.\n");
 		return ohci_rh_schedule(&instance->rh, batch);
Index: uspace/drv/bus/usb/ohci/hc.h
===================================================================
--- uspace/drv/bus/usb/ohci/hc.h	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/ohci/hc.h	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -52,4 +52,5 @@
 #include "ohci_regs.h"
 #include "ohci_rh.h"
+#include "ohci_bus.h"
 #include "endpoint_list.h"
 #include "hw_struct/hcca.h"
@@ -80,4 +81,7 @@
 	/** USB hub emulation structure */
 	ohci_rh_t rh;
+
+	/** USB bookkeeping */
+	ohci_bus_t bus;
 } hc_t;
 
Index: uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c
===================================================================
--- uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -79,6 +79,6 @@
 	/* Status: address, endpoint nr, direction mask and max packet size. */
 	OHCI_MEM32_WR(instance->status,
-	    ((ep->address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT)
-	    | ((ep->endpoint & ED_STATUS_EN_MASK) << ED_STATUS_EN_SHIFT)
+	    ((ep->target.address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT)
+	    | ((ep->target.endpoint & ED_STATUS_EN_MASK) << ED_STATUS_EN_SHIFT)
 	    | ((dir[ep->direction] & ED_STATUS_D_MASK) << ED_STATUS_D_SHIFT)
 	    | ((ep->max_packet_size & ED_STATUS_MPS_MASK)
Index: uspace/drv/bus/usb/ohci/main.c
===================================================================
--- uspace/drv/bus/usb/ohci/main.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/ohci/main.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -45,4 +45,5 @@
 
 #include "hc.h"
+#include "ohci_bus.h"
 
 #define NAME "ohci"
@@ -53,5 +54,4 @@
 
 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,
@@ -62,6 +62,4 @@
 	.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,
@@ -72,4 +70,6 @@
 static int ohci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res)
 {
+	int err;
+
 	assert(hcd);
 	assert(hcd_get_driver_data(hcd) == NULL);
@@ -79,11 +79,17 @@
 		return ENOMEM;
 
-	const int ret = hc_init(instance, res);
-	if (ret == EOK) {
-		hcd_set_implementation(hcd, instance, &ohci_hc_driver.ops);
-	} else {
-		free(instance);
-	}
-	return ret;
+	if ((err = hc_init(instance, res)) != EOK)
+		goto err;
+
+	if ((err = ohci_bus_init(&instance->bus, instance)))
+		goto err;
+
+	hcd_set_implementation(hcd, instance, &ohci_hc_driver.ops, &instance->bus.base.base);
+
+	return EOK;
+
+err:
+	free(instance);
+	return err;
 }
 
@@ -115,5 +121,5 @@
 		hc_fini(hc);
 
-	hcd_set_implementation(hcd, NULL, NULL);
+	hcd_set_implementation(hcd, NULL, NULL, NULL);
 	free(hc);
 }
Index: uspace/drv/bus/usb/ohci/ohci_batch.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_batch.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/ohci/ohci_batch.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -45,5 +45,5 @@
 
 #include "ohci_batch.h"
-#include "ohci_endpoint.h"
+#include "ohci_bus.h"
 
 static void (*const batch_setup[])(ohci_transfer_batch_t*, usb_direction_t);
Index: uspace/drv/bus/usb/ohci/ohci_bus.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_bus.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
+++ uspace/drv/bus/usb/ohci/ohci_bus.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbohci
+ * @{
+ */
+/** @file
+ * @brief OHCI driver
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <usb/host/utils/malloc32.h>
+#include <usb/host/bandwidth.h>
+
+#include "ohci_bus.h"
+#include "hc.h"
+
+/** Callback to set toggle on ED.
+ *
+ * @param[in] hcd_ep hcd endpoint structure
+ * @param[in] toggle new value of toggle bit
+ */
+static void ohci_ep_toggle_set(endpoint_t *ep, bool toggle)
+{
+	ohci_endpoint_t *instance = ohci_endpoint_get(ep);
+	assert(instance);
+	assert(instance->ed);
+	ep->toggle = toggle;
+	ed_toggle_set(instance->ed, toggle);
+}
+
+/** Callback to get value of toggle bit.
+ *
+ * @param[in] hcd_ep hcd endpoint structure
+ * @return Current value of toggle bit.
+ */
+static bool ohci_ep_toggle_get(endpoint_t *ep)
+{
+	ohci_endpoint_t *instance = ohci_endpoint_get(ep);
+	assert(instance);
+	assert(instance->ed);
+	return ed_toggle_get(instance->ed);
+}
+
+/** Creates new hcd endpoint representation.
+ */
+static endpoint_t *ohci_endpoint_create(bus_t *bus)
+{
+	assert(bus);
+
+	ohci_endpoint_t *ohci_ep = malloc(sizeof(ohci_endpoint_t));
+	if (ohci_ep == NULL)
+		return NULL;
+
+	ohci_ep->ed = malloc32(sizeof(ed_t));
+	if (ohci_ep->ed == NULL) {
+		free(ohci_ep);
+		return NULL;
+	}
+
+	ohci_ep->td = malloc32(sizeof(td_t));
+	if (ohci_ep->td == NULL) {
+		free32(ohci_ep->ed);
+		free(ohci_ep);
+		return NULL;
+	}
+
+	link_initialize(&ohci_ep->link);
+	return EOK;
+}
+
+/** Disposes hcd endpoint structure
+ *
+ * @param[in] hcd driver using this instance.
+ * @param[in] ep endpoint structure.
+ */
+static void ohci_endpoint_destroy(endpoint_t *ep)
+{
+	assert(ep);
+	ohci_endpoint_t *instance = ohci_endpoint_get(ep);
+
+	free32(instance->ed);
+	free32(instance->td);
+	free(instance);
+}
+
+
+static int ohci_register_ep(bus_t *bus_base, endpoint_t *ep)
+{
+	ohci_bus_t *bus = (ohci_bus_t *) bus_base;
+	ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
+
+	const int err = bus->parent_ops.register_endpoint(bus_base, ep);
+	if (err)
+		return err;
+
+	ed_init(ohci_ep->ed, ep, ohci_ep->td);
+	hc_enqueue_endpoint(bus->hc, ep);
+
+	return EOK;
+}
+
+static int ohci_release_ep(bus_t *bus_base, endpoint_t *ep)
+{
+	ohci_bus_t *bus = (ohci_bus_t *) bus_base;
+	assert(bus);
+	assert(ep);
+
+	const int err = bus->parent_ops.release_endpoint(bus_base, ep);
+	if (err)
+		return err;
+
+	hc_dequeue_endpoint(bus->hc, ep);
+	return EOK;
+
+}
+
+int ohci_bus_init(ohci_bus_t *bus, hc_t *hc)
+{
+	assert(hc);
+	assert(bus);
+
+	usb2_bus_init(&bus->base, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
+
+	bus_ops_t *ops = &bus->base.base.ops;
+	bus->parent_ops = *ops;
+	ops->create_endpoint = ohci_endpoint_create;
+	ops->destroy_endpoint = ohci_endpoint_destroy;
+	ops->endpoint_set_toggle = ohci_ep_toggle_set;
+	ops->endpoint_get_toggle = ohci_ep_toggle_get;
+
+	ops->register_endpoint = ohci_register_ep;
+	ops->release_endpoint = ohci_release_ep;
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/ohci/ohci_bus.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_bus.h	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
+++ uspace/drv/bus/usb/ohci/ohci_bus.h	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * Copyright (c) 2017 Ondrej Hlavaty <aearsis@eideo.cz>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @addtogroup drvusbohci
+ * @{
+ */
+/** @file
+ * @brief OHCI driver
+ */
+#ifndef DRV_OHCI_HCD_BUS_H
+#define DRV_OHCI_HCD_BUS_H
+
+#include <assert.h>
+#include <adt/list.h>
+#include <usb/host/usb2_bus.h>
+
+#include "hw_struct/endpoint_descriptor.h"
+#include "hw_struct/transfer_descriptor.h"
+
+/** Connector structure linking ED to to prepared TD. */
+typedef struct ohci_endpoint {
+	endpoint_t base;
+
+	/** OHCI endpoint descriptor */
+	ed_t *ed;
+	/** Currently enqueued transfer descriptor */
+	td_t *td;
+	/** Linked list used by driver software */
+	link_t link;
+} ohci_endpoint_t;
+
+typedef struct hc hc_t;
+
+typedef struct {
+	usb2_bus_t base;
+	hc_t *hc;
+
+	/* Stored original ops from base, they are called in our handlers */
+	bus_ops_t parent_ops;
+} ohci_bus_t;
+
+int ohci_bus_init(ohci_bus_t *, hc_t *);
+
+/** Get and convert assigned ohci_endpoint_t structure
+ * @param[in] ep USBD endpoint structure.
+ * @return Pointer to assigned hcd endpoint structure
+ */
+static inline ohci_endpoint_t * ohci_endpoint_get(const endpoint_t *ep)
+{
+	assert(ep);
+	return (ohci_endpoint_t *) ep;
+}
+
+#endif
+/**
+ * @}
+ */
Index: pace/drv/bus/usb/ohci/ohci_endpoint.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_endpoint.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ 	(revision )
@@ -1,123 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup drvusbohci
- * @{
- */
-/** @file
- * @brief OHCI driver
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <usb/host/utils/malloc32.h>
-
-#include "ohci_endpoint.h"
-#include "hc.h"
-
-/** Callback to set toggle on ED.
- *
- * @param[in] hcd_ep hcd endpoint structure
- * @param[in] toggle new value of toggle bit
- */
-static void ohci_ep_toggle_set(void *ohci_ep, int toggle)
-{
-	ohci_endpoint_t *instance = ohci_ep;
-	assert(instance);
-	assert(instance->ed);
-	ed_toggle_set(instance->ed, toggle);
-}
-
-/** Callback to get value of toggle bit.
- *
- * @param[in] hcd_ep hcd endpoint structure
- * @return Current value of toggle bit.
- */
-static int ohci_ep_toggle_get(void *ohci_ep)
-{
-	ohci_endpoint_t *instance = ohci_ep;
-	assert(instance);
-	assert(instance->ed);
-	return ed_toggle_get(instance->ed);
-}
-
-/** Creates new hcd endpoint representation.
- *
- * @param[in] ep USBD endpoint structure
- * @return Error code.
- */
-int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep)
-{
-	assert(ep);
-	ohci_endpoint_t *ohci_ep = malloc(sizeof(ohci_endpoint_t));
-	if (ohci_ep == NULL)
-		return ENOMEM;
-
-	ohci_ep->ed = malloc32(sizeof(ed_t));
-	if (ohci_ep->ed == NULL) {
-		free(ohci_ep);
-		return ENOMEM;
-	}
-
-	ohci_ep->td = malloc32(sizeof(td_t));
-	if (ohci_ep->td == NULL) {
-		free32(ohci_ep->ed);
-		free(ohci_ep);
-		return ENOMEM;
-	}
-
-	link_initialize(&ohci_ep->link);
-	ed_init(ohci_ep->ed, ep, ohci_ep->td);
-	endpoint_set_hc_data(
-	    ep, ohci_ep, ohci_ep_toggle_get, ohci_ep_toggle_set);
-	hc_enqueue_endpoint(hcd_get_driver_data(hcd), ep);
-	return EOK;
-}
-
-/** Disposes hcd endpoint structure
- *
- * @param[in] hcd driver using this instance.
- * @param[in] ep endpoint structure.
- */
-void ohci_endpoint_fini(hcd_t *hcd, endpoint_t *ep)
-{
-	assert(hcd);
-	assert(ep);
-	ohci_endpoint_t *instance = ohci_endpoint_get(ep);
-	hc_dequeue_endpoint(hcd_get_driver_data(hcd), ep);
-	endpoint_clear_hc_data(ep);
-	if (instance) {
-		free32(instance->ed);
-		free32(instance->td);
-		free(instance);
-	}
-}
-
-/**
- * @}
- */
Index: pace/drv/bus/usb/ohci/ohci_endpoint.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_endpoint.h	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ 	(revision )
@@ -1,71 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/** @addtogroup drvusbohci
- * @{
- */
-/** @file
- * @brief OHCI driver
- */
-#ifndef DRV_OHCI_HCD_ENDPOINT_H
-#define DRV_OHCI_HCD_ENDPOINT_H
-
-#include <assert.h>
-#include <adt/list.h>
-#include <usb/host/endpoint.h>
-#include <usb/host/hcd.h>
-
-#include "hw_struct/endpoint_descriptor.h"
-#include "hw_struct/transfer_descriptor.h"
-
-/** Connector structure linking ED to to prepared TD. */
-typedef struct ohci_endpoint {
-	/** OHCI endpoint descriptor */
-	ed_t *ed;
-	/** Currently enqueued transfer descriptor */
-	td_t *td;
-	/** Linked list used by driver software */
-	link_t link;
-} ohci_endpoint_t;
-
-int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep);
-void ohci_endpoint_fini(hcd_t *hcd, endpoint_t *ep);
-
-/** Get and convert assigned ohci_endpoint_t structure
- * @param[in] ep USBD endpoint structure.
- * @return Pointer to assigned hcd endpoint structure
- */
-static inline ohci_endpoint_t * ohci_endpoint_get(const endpoint_t *ep)
-{
-	assert(ep);
-	return ep->hc_data.data;
-}
-
-#endif
-/**
- * @}
- */
Index: uspace/drv/bus/usb/ohci/ohci_rh.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_rh.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/ohci/ohci_rh.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -178,8 +178,5 @@
 	assert(instance);
 	assert(batch);
-	const usb_target_t target = {{
-		.address = batch->ep->address,
-		.endpoint = batch->ep->endpoint,
-	}};
+	const usb_target_t target = batch->ep->target;
 	batch->error = virthub_base_request(&instance->base, target,
 	    usb_transfer_batch_direction(batch), (void*)batch->setup_buffer,
@@ -211,8 +208,5 @@
 	instance->unfinished_interrupt_transfer = NULL;
 	if (batch) {
-		const usb_target_t target = {{
-			.address = batch->ep->address,
-			.endpoint = batch->ep->endpoint,
-		}};
+		const usb_target_t target = batch->ep->target;
 		batch->error = virthub_base_request(&instance->base, target,
 		    usb_transfer_batch_direction(batch),
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -50,4 +50,5 @@
 #include <usb/usb.h>
 #include <usb/host/utils/malloc32.h>
+#include <usb/host/bandwidth.h>
 
 #include "uhci_batch.h"
@@ -320,5 +321,9 @@
 int hc_init_mem_structures(hc_t *instance)
 {
-	assert(instance);
+	int err;
+	assert(instance);
+
+	if ((err = usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11)))
+		return err;
 
 	/* Init USB frame list page */
Index: uspace/drv/bus/usb/uhci/main.c
===================================================================
--- uspace/drv/bus/usb/uhci/main.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/uhci/main.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -45,5 +45,4 @@
 #include <usb/debug.h>
 #include <usb/host/ddf_helpers.h>
-#include <usb/host/bandwidth.h>
 
 #include "hc.h"
@@ -82,7 +81,4 @@
 
 	if ((err = hc_init(instance, res)) != EOK)
-		goto err;
-
-	if ((err = usb2_bus_init(&instance->bus, hcd, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11)))
 		goto err;
 
Index: uspace/drv/bus/usb/xhci/bus.c
===================================================================
--- uspace/drv/bus/usb/xhci/bus.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/xhci/bus.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -171,11 +171,11 @@
 
 /* Endpoint ops, optional (have generic fallback) */
-static int endpoint_get_toggle(endpoint_t *ep)
-{
-	// TODO: Implement me!
-	return ENOTSUP;
-}
-
-static void endpoint_set_toggle(endpoint_t *ep, unsigned toggle)
+static bool endpoint_get_toggle(endpoint_t *ep)
+{
+	// TODO: Implement me!
+	return ENOTSUP;
+}
+
+static void endpoint_set_toggle(endpoint_t *ep, bool toggle)
 {
 	// TODO: Implement me!
@@ -227,9 +227,9 @@
 };
 
-int xhci_bus_init(xhci_bus_t *bus, hcd_t *hcd)
-{
-	assert(bus);
-
-	bus_init(&bus->base, hcd);
+int xhci_bus_init(xhci_bus_t *bus)
+{
+	assert(bus);
+
+	bus_init(&bus->base);
 
 	if (!hash_table_create(&bus->endpoints, 0, 0, &endpoint_ht_ops)) {
Index: uspace/drv/bus/usb/xhci/bus.h
===================================================================
--- uspace/drv/bus/usb/xhci/bus.h	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/xhci/bus.h	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -52,8 +52,8 @@
 	 */
 
- 	hash_table_t endpoints;
+	hash_table_t endpoints;
 } xhci_bus_t;
 
-int xhci_bus_init(xhci_bus_t *, hcd_t *);
+int xhci_bus_init(xhci_bus_t *);
 void xhci_bus_fini(xhci_bus_t *);
 
Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -216,6 +216,12 @@
 		goto err_cmd;
 
-	return EOK;
-
+	if ((err = xhci_bus_init(&hc->bus)))
+		goto err_rh;
+
+
+	return EOK;
+
+err_rh:
+	xhci_rh_fini(&hc->rh);
 err_cmd:
 	xhci_fini_commands(hc);
@@ -610,4 +616,5 @@
 void hc_fini(xhci_hc_t *hc)
 {
+	xhci_bus_fini(&hc->bus);
 	xhci_trb_ring_fini(&hc->command_ring);
 	xhci_event_ring_fini(&hc->event_ring);
Index: uspace/drv/bus/usb/xhci/main.c
===================================================================
--- uspace/drv/bus/usb/xhci/main.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/drv/bus/usb/xhci/main.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -81,7 +81,4 @@
 		goto err;
 
-	if ((err = xhci_bus_init(&hc->bus, hcd)))
-		goto err;
-
 	if ((err = hc_init_memory(hc)))
 		goto err;
@@ -151,7 +148,4 @@
 	hc_fini(hc);
 
-	// FIXME: Probably move init/fini of XHCI bus into HC.
-	xhci_bus_fini(&hc->bus);
-
 	free(hc);
 }
Index: uspace/lib/usbhost/include/usb/host/bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/bus.h	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/lib/usbhost/include/usb/host/bus.h	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -68,12 +68,10 @@
 	/* Endpoint ops, optional (have generic fallback) */
 	void (*destroy_endpoint)(endpoint_t *);
-	int (*endpoint_get_toggle)(endpoint_t *);
-	void (*endpoint_set_toggle)(endpoint_t *, unsigned);
+	bool (*endpoint_get_toggle)(endpoint_t *);
+	void (*endpoint_set_toggle)(endpoint_t *, bool);
 } bus_ops_t;
 
 /** Endpoint management structure */
 typedef struct bus {
-	hcd_t *hcd;
-
 	/* Synchronization of ops */
 	fibril_mutex_t guard;
@@ -85,5 +83,5 @@
 } bus_t;
 
-void bus_init(bus_t *, hcd_t *hcd);
+void bus_init(bus_t *);
 
 endpoint_t *bus_create_endpoint(bus_t *);
Index: uspace/lib/usbhost/include/usb/host/usb2_bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb2_bus.h	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/lib/usbhost/include/usb/host/usb2_bus.h	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -65,5 +65,5 @@
 } usb2_bus_t;
 
-extern int usb2_bus_init(usb2_bus_t *, hcd_t *, size_t, count_bw_func_t);
+extern int usb2_bus_init(usb2_bus_t *, size_t, count_bw_func_t);
 
 #endif
Index: uspace/lib/usbhost/src/bus.c
===================================================================
--- uspace/lib/usbhost/src/bus.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/lib/usbhost/src/bus.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -43,9 +43,8 @@
  * Initializes the bus structure.
  */
-void bus_init(bus_t *bus, hcd_t *hcd)
+void bus_init(bus_t *bus)
 {
 	memset(bus, 0, sizeof(bus_t));
 
-	bus->hcd = hcd;
 	fibril_mutex_initialize(&bus->guard);
 }
Index: uspace/lib/usbhost/src/usb2_bus.c
===================================================================
--- uspace/lib/usbhost/src/usb2_bus.c	(revision 0a5833d7deb1adc704e11ca192de1eb20dfecd6a)
+++ uspace/lib/usbhost/src/usb2_bus.c	(revision e6b91820ed239c638e2a7d99d66a324fe19e840f)
@@ -41,4 +41,5 @@
 #include <errno.h>
 #include <macros.h>
+#include <stdlib.h>
 #include <stdbool.h>
 
@@ -110,4 +111,14 @@
 }
 
+static endpoint_t *usb2_bus_create_ep(bus_t *bus)
+{
+	endpoint_t *ep = malloc(sizeof(endpoint_t));
+	if (!ep)
+		return NULL;
+
+	endpoint_init(ep, bus);
+	return ep;
+}
+
 /** Register an endpoint to the bus. Reserves bandwidth.
  * @param bus usb_bus structure, non-null.
@@ -271,4 +282,5 @@
 
 static const bus_ops_t usb2_bus_ops = {
+	.create_endpoint = usb2_bus_create_ep,
 	.find_endpoint = usb2_bus_find_ep,
 	.release_endpoint = usb2_bus_release_ep,
@@ -287,9 +299,9 @@
  * @return Error code.
  */
-int usb2_bus_init(usb2_bus_t *bus, hcd_t *hcd, size_t available_bandwidth, count_bw_func_t count_bw)
+int usb2_bus_init(usb2_bus_t *bus, size_t available_bandwidth, count_bw_func_t count_bw)
 {
 	assert(bus);
 
-	bus_init(&bus->base, hcd);
+	bus_init(&bus->base);
 
 	bus->base.ops = usb2_bus_ops;
