Index: uspace/app/vuhid/virthid.h
===================================================================
--- uspace/app/vuhid/virthid.h	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/app/vuhid/virthid.h	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -40,5 +40,5 @@
 #include <fibril_synch.h>
 
-#define VUHID_ENDPOINT_MAX USB11_ENDPOINT_MAX
+#define VUHID_ENDPOINT_MAX USB_ENDPOINT_MAX
 #define VUHID_INTERFACE_MAX 8
 
Index: uspace/drv/bus/usb/ehci/ehci_bus.c
===================================================================
--- uspace/drv/bus/usb/ehci/ehci_bus.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/drv/bus/usb/ehci/ehci_bus.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -48,31 +48,13 @@
  * @param[in] toggle new value of toggle bit
  */
-static void ehci_ep_toggle_set(endpoint_t *ep, bool toggle)
+static void ehci_ep_toggle_reset(endpoint_t *ep)
 {
 	ehci_endpoint_t *instance = ehci_endpoint_get(ep);
-	assert(instance);
-	assert(instance->qh);
-	ep->toggle = toggle;
 	if (qh_toggle_from_td(instance->qh))
-		usb_log_warning("EP(%p): Setting toggle bit for transfer "
-		    "directed EP", instance);
-	qh_toggle_set(instance->qh, toggle);
+		usb_log_warning("EP(%p): Resetting toggle bit for transfer directed EP", instance);
+	qh_toggle_set(instance->qh, 0);
+	ep->toggle = 0;
 }
 
-/** Callback to get value of toggle bit.
- *
- * @param[in] hcd_ep hcd endpoint structure
- * @return Current value of toggle bit.
- */
-static bool ehci_ep_toggle_get(endpoint_t *ep)
-{
-	ehci_endpoint_t *instance = ehci_endpoint_get(ep);
-	assert(instance);
-	assert(instance->qh);
-
-	if (qh_toggle_from_td(instance->qh))
-		usb_log_warning("EP(%p): Reading useless toggle bit", instance);
-	return qh_toggle_get(instance->qh);
-}
 
 /** Creates new hcd endpoint representation.
@@ -166,6 +148,5 @@
 	.endpoint_register = ehci_register_ep,
 	.endpoint_unregister = ehci_unregister_ep,
-	.endpoint_set_toggle = ehci_ep_toggle_set,
-	.endpoint_get_toggle = ehci_ep_toggle_get,
+	.endpoint_toggle_reset = ehci_ep_toggle_reset,
 	.endpoint_count_bw = bandwidth_count_usb11,
 	.batch_create = ehci_create_batch,
Index: uspace/drv/bus/usb/ohci/ohci_bus.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_bus.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/drv/bus/usb/ohci/ohci_bus.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -43,29 +43,16 @@
 #include "hc.h"
 
-/** Callback to set toggle on ED.
+/** Callback to reset 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)
+static void ohci_ep_toggle_reset(endpoint_t *ep)
 {
 	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);
+	ep->toggle = 0;
+	ed_toggle_set(instance->ed, 0);
 }
 
@@ -166,6 +153,5 @@
 	.endpoint_unregister = ohci_unregister_ep,
 	.endpoint_count_bw = bandwidth_count_usb11,
-	.endpoint_set_toggle = ohci_ep_toggle_set,
-	.endpoint_get_toggle = ohci_ep_toggle_get,
+	.endpoint_toggle_reset = ohci_ep_toggle_reset,
 	.batch_create = ohci_create_batch,
 	.batch_destroy = ohci_destroy_batch,
Index: uspace/drv/bus/usb/uhci/uhci_batch.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci_batch.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/drv/bus/usb/uhci/uhci_batch.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -178,6 +178,5 @@
 			td_print_status(&uhci_batch->tds[i]);
 
-			endpoint_toggle_set(batch->ep,
-			    td_toggle(&uhci_batch->tds[i]));
+			batch->ep->toggle = td_toggle(&uhci_batch->tds[i]);
 			if (i > 0)
 				goto substract_ret;
@@ -195,5 +194,4 @@
 
 	fibril_mutex_lock(&batch->ep->guard);
-	usb_transfer_batch_reset_toggle(batch);
 	endpoint_deactivate_locked(batch->ep);
 	fibril_mutex_unlock(&batch->ep->guard);
@@ -236,5 +234,5 @@
 	const size_t mps = uhci_batch->base.ep->max_packet_size;
 
-	int toggle = endpoint_toggle_get(uhci_batch->base.ep);
+	int toggle = uhci_batch->base.ep->toggle;
 	assert(toggle == 0 || toggle == 1);
 
@@ -260,5 +258,5 @@
 	}
 	td_set_ioc(&uhci_batch->tds[td - 1]);
-	endpoint_toggle_set(uhci_batch->base.ep, toggle);
+	uhci_batch->base.ep->toggle = toggle;
 	usb_log_debug2(
 	    "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \
Index: uspace/drv/bus/usb/xhci/bus.c
===================================================================
--- uspace/drv/bus/usb/xhci/bus.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/drv/bus/usb/xhci/bus.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -77,31 +77,25 @@
 		goto err_slot;
 
-	/* Temporary reference */
+	/* Bus reference */
 	endpoint_add_ref(ep0_base);
+	dev->base.endpoints[0] = ep0_base;
 
 	xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
 
 	if ((err = xhci_endpoint_alloc_transfer_ds(ep0)))
-		goto err_ep;
-
-	/* Register EP0 */
-	if ((err = xhci_device_add_endpoint(dev, ep0)))
-		goto err_prepared;
+		goto err_added;
 
 	/* Address device */
 	if ((err = hc_address_device(bus->hc, dev, ep0)))
-		goto err_added;
-
-	/* Temporary reference */
-	endpoint_del_ref(ep0_base);
-	return EOK;
-
-err_added:
-	xhci_device_remove_endpoint(ep0);
+		goto err_prepared;
+
+	return EOK;
+
 err_prepared:
 	xhci_endpoint_free_transfer_ds(ep0);
-err_ep:
-	/* Temporary reference */
+err_added:
+	/* Bus reference */
 	endpoint_del_ref(ep0_base);
+	dev->base.endpoints[0] = NULL;
 err_slot:
 	hc_disable_slot(bus->hc, dev);
@@ -123,5 +117,5 @@
 		return err;
 
-	xhci_endpoint_t *ep0 = dev->endpoints[0];
+	xhci_endpoint_t *ep0 = xhci_device_get_endpoint(dev, 0);
 	assert(ep0);
 
@@ -218,6 +212,6 @@
 	/* Abort running transfers. */
 	usb_log_debug2("Aborting all active transfers to device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*xhci_dev));
-	for (size_t i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {
-		xhci_endpoint_t *ep = xhci_dev->endpoints[i];
+	for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) {
+		xhci_endpoint_t *ep = xhci_device_get_endpoint(xhci_dev, i);
 		if (!ep)
 			continue;
@@ -244,11 +238,11 @@
 
 	/* Unregister remaining endpoints, freeing memory. */
-	for (unsigned i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {
-		if (!xhci_dev->endpoints[i])
+	for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) {
+		if (!dev->endpoints[i])
 			continue;
 
-		if ((err = endpoint_unregister(&xhci_dev->endpoints[i]->base))) {
+		if ((err = endpoint_unregister(dev->endpoints[i]))) {
 			usb_log_warning("Failed to unregister endpoint " XHCI_EP_FMT ": %s",
-			    XHCI_EP_ARGS(*xhci_dev->endpoints[i]), str_error(err));
+			    XHCI_EP_ARGS(*xhci_device_get_endpoint(xhci_dev, i)), str_error(err));
 		}
 	}
@@ -332,15 +326,10 @@
 
 	/* We will need the endpoint array later for DS deallocation. */
-	xhci_endpoint_t *endpoints[ARRAY_SIZE(dev->endpoints)];
-	memcpy(endpoints, dev->endpoints, sizeof(dev->endpoints));
-
-	/* Remove all endpoints except zero. */
-	for (unsigned i = 1; i < ARRAY_SIZE(endpoints); ++i) {
-		if (!endpoints[i])
-			continue;
-
+	endpoint_t *endpoints[USB_ENDPOINT_MAX];
+	memcpy(endpoints, dev->base.endpoints, sizeof(endpoints));
+
+	for (usb_endpoint_t i = 1; i < USB_ENDPOINT_MAX; ++i) {
 		/* FIXME: Asserting here that the endpoint is not active. If not, EBUSY? */
-
-		xhci_device_remove_endpoint(endpoints[i]);
+		dev->base.endpoints[i] = NULL;
 	}
 
@@ -356,8 +345,8 @@
 			continue;
 
-		xhci_endpoint_free_transfer_ds(endpoints[i]);
-	}
-
-	/* FIXME: What happens to unregistered endpoints now? Destroy them? */
+		xhci_endpoint_free_transfer_ds(xhci_endpoint_get(endpoints[i]));
+		/* Bus reference */
+		endpoint_del_ref(endpoints[i]);
+	}
 
 	return EOK;
@@ -397,7 +386,4 @@
 		return err;
 
-	if ((err = xhci_device_add_endpoint(dev, ep)))
-		goto err_prepared;
-
 	usb_log_info("Endpoint " XHCI_EP_FMT " registered to XHCI bus.", XHCI_EP_ARGS(*ep));
 
@@ -406,10 +392,8 @@
 
 	if ((err = hc_add_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx)))
-		goto err_added;
-
-	return EOK;
-
-err_added:
-	xhci_device_remove_endpoint(ep);
+		goto err_prepared;
+
+	return EOK;
+
 err_prepared:
 	xhci_endpoint_free_transfer_ds(ep);
@@ -425,6 +409,4 @@
 
 	usb_log_info("Endpoint " XHCI_EP_FMT " unregistered from XHCI bus.", XHCI_EP_ARGS(*ep));
-
-	xhci_device_remove_endpoint(ep);
 
 	/* If device slot is still available, drop the endpoint. */
@@ -444,33 +426,4 @@
 }
 
-static endpoint_t* device_find_endpoint(device_t *dev_base, usb_target_t target, usb_direction_t direction)
-{
-	xhci_device_t *dev = xhci_device_get(dev_base);
-
-	xhci_endpoint_t *ep = xhci_device_get_endpoint(dev, target.endpoint);
-	if (!ep)
-		return NULL;
-
-	return &ep->base;
-}
-
-static int reset_toggle(bus_t *bus_base, usb_target_t target, toggle_reset_mode_t mode)
-{
-	// TODO: Implement me!
-	return ENOTSUP;
-}
-
-/* Endpoint ops, optional (have generic fallback) */
-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!
-}
-
 static int reserve_default_address(bus_t *bus_base, usb_speed_t speed)
 {
@@ -510,5 +463,4 @@
 	BIND_OP(reserve_default_address)
 	BIND_OP(release_default_address)
-	BIND_OP(reset_toggle)
 
 	BIND_OP(device_enumerate)
@@ -516,5 +468,4 @@
 	BIND_OP(device_online)
 	BIND_OP(device_offline)
-	BIND_OP(device_find_endpoint)
 
 	BIND_OP(endpoint_create)
@@ -522,6 +473,4 @@
 	BIND_OP(endpoint_register)
 	BIND_OP(endpoint_unregister)
-	BIND_OP(endpoint_get_toggle)
-	BIND_OP(endpoint_set_toggle)
 
 	BIND_OP(batch_create)
Index: uspace/drv/bus/usb/xhci/endpoint.c
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/drv/bus/usb/xhci/endpoint.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -469,47 +469,4 @@
 }
 
-/** Add a new XHCI endpoint to a device. The device must be online unless
- * the added endpoint is number 0.
- * @param[in] dev XHCI device, to which to add the endpoint
- * @param[in] ep XHCI endpoint to add.
- *
- * @return Error code.
- */
-int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep)
-{
-	assert(dev);
-	assert(ep);
-
-	/* Offline devices don't create new endpoints other than EP0. */
-	if (!dev->base.online && ep->base.endpoint > 0) {
-		return EAGAIN;
-	}
-
-	const usb_endpoint_t ep_num = ep->base.endpoint;
-
-	if (dev->endpoints[ep_num])
-		return EEXIST;
-
-	/* Device reference */
-	endpoint_add_ref(&ep->base);
-	ep->base.device = &dev->base;
-	dev->endpoints[ep_num] = ep;
-
-	return EOK;
-}
-
-/** Remove XHCI endpoint from a device.
- * @param[in] ep XHCI endpoint to remove.
- */
-void xhci_device_remove_endpoint(xhci_endpoint_t *ep)
-{
-	assert(ep);
-	xhci_device_t *dev = xhci_device_get(ep->base.device);
-
-	assert(dev->endpoints[ep->base.endpoint]);
-	dev->endpoints[ep->base.endpoint] = NULL;
-	ep->base.device = NULL;
-}
-
 /** Retrieve XHCI endpoint from a device by the endpoint number.
  * @param[in] dev XHCI device to query.
@@ -520,5 +477,5 @@
 xhci_endpoint_t *xhci_device_get_endpoint(xhci_device_t *dev, usb_endpoint_t ep)
 {
-	return dev->endpoints[ep];
+	return xhci_endpoint_get(dev->base.endpoints[ep]);
 }
 
Index: uspace/drv/bus/usb/xhci/endpoint.h
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.h	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/drv/bus/usb/xhci/endpoint.h	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -139,7 +139,4 @@
 	dma_buffer_t dev_ctx;
 
-	/** All endpoints of the device. Dropped ones are NULL */
-	xhci_endpoint_t *endpoints[XHCI_EP_COUNT];
-
 	/** Flag indicating whether the device is USB3 (it's USB2 otherwise). */
 	bool usb3;
@@ -161,6 +158,4 @@
 void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *);
 
-int xhci_device_add_endpoint(xhci_device_t *, xhci_endpoint_t *);
-void xhci_device_remove_endpoint(xhci_endpoint_t *);
 xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t);
 
Index: uspace/drv/bus/usb/xhci/transfers.c
===================================================================
--- uspace/drv/bus/usb/xhci/transfers.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/drv/bus/usb/xhci/transfers.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -513,5 +513,4 @@
 	}
 
-	usb_transfer_batch_reset_toggle(batch);
 	endpoint_deactivate_locked(&ep->base);
 	fibril_mutex_unlock(&ep->base.guard);
Index: uspace/lib/usb/include/usb/usb.h
===================================================================
--- uspace/lib/usb/include/usb/usb.h	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usb/include/usb/usb.h	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -103,6 +103,6 @@
 #define USB_ENDPOINT_DEFAULT_CONTROL 0
 
-/** Maximum endpoint number in USB 1.1. */
-#define USB11_ENDPOINT_MAX 16
+/** Maximum endpoint number in USB */
+#define USB_ENDPOINT_MAX 16
 
 /** Check USB endpoint for allowed values.
@@ -116,5 +116,5 @@
 {
 	return (ep >= USB_ENDPOINT_DEFAULT_CONTROL) &&
-	    (ep < USB11_ENDPOINT_MAX);
+	    (ep < USB_ENDPOINT_MAX);
 }
 
Index: uspace/lib/usbhost/include/usb/host/bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/bus.h	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/include/usb/host/bus.h	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -76,4 +76,5 @@
 	usb_speed_t speed;
 	usb_address_t address;
+	endpoint_t *endpoints [USB_ENDPOINT_MAX];
 
 	/* Managing bus */
@@ -101,5 +102,4 @@
 	int (*reserve_default_address)(bus_t *, usb_speed_t);
 	int (*release_default_address)(bus_t *);
-	int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t);
 
 	/* Operations on device */
@@ -108,5 +108,4 @@
 	int (*device_online)(device_t *);			/**< Optional */
 	int (*device_offline)(device_t *);			/**< Optional */
-	endpoint_t *(*device_find_endpoint)(device_t*, usb_target_t, usb_direction_t);
 	endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_descriptors_t *);
 
@@ -115,7 +114,6 @@
 	int (*endpoint_unregister)(endpoint_t *);
 	void (*endpoint_destroy)(endpoint_t *);			/**< Optional */
-	bool (*endpoint_get_toggle)(endpoint_t *);		/**< Optional */
-	void (*endpoint_set_toggle)(endpoint_t *, bool);	/**< Optional */
-	ssize_t (*endpoint_count_bw) (endpoint_t *, size_t);
+	void (*endpoint_toggle_reset)(endpoint_t *);		/**< Optional */
+	ssize_t (*endpoint_count_bw) (endpoint_t *, size_t);	/**< Optional */
 	usb_transfer_batch_t *(*batch_create)(endpoint_t *);	/**< Optional */
 
@@ -164,5 +162,5 @@
 
 int bus_endpoint_add(device_t *, const usb_endpoint_descriptors_t *, endpoint_t **);
-endpoint_t *bus_find_endpoint(device_t *, usb_target_t, usb_direction_t);
+endpoint_t *bus_find_endpoint(device_t *, usb_endpoint_t);
 int bus_endpoint_remove(endpoint_t *);
 
@@ -170,6 +168,4 @@
 int bus_release_default_address(bus_t *);
 
-int bus_reset_toggle(bus_t *, usb_target_t, bool);
-
 #endif
 /**
Index: uspace/lib/usbhost/include/usb/host/endpoint.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -62,5 +62,5 @@
 	/** Reserved bandwidth. */
 	size_t bandwidth;
-	/** Value of the toggle bit. */
+	/** Value of the toggle bit. Untouched by the library. */
 	unsigned toggle:1;
 	/** The currently active transfer batch. Write using methods, read under guard. */
@@ -107,8 +107,4 @@
 void endpoint_abort(endpoint_t *);
 
-/* Manage the toggle bit */
-extern int endpoint_toggle_get(endpoint_t *);
-extern void endpoint_toggle_set(endpoint_t *, bool);
-
 /* Calculate bandwidth */
 ssize_t endpoint_count_bw(endpoint_t *, size_t);
Index: uspace/lib/usbhost/include/usb/host/usb2_bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb2_bus.h	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/include/usb/host/usb2_bus.h	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -50,16 +50,14 @@
 	bus_t base;			/**< Inheritance - keep this first */
 
-	/* Device bookkeeping */
-	struct {
-		usb_speed_t speed;      /**< Device speed */
-		bool occupied;          /**< The address is in use. */
-		// TODO: This can be stored in usb2_bus-specific device_t
-		list_t endpoint_list;   /**< Store endpoint_t instances */
-	} devices[USB_ADDRESS_COUNT];
+	/** The speed which reserved default address. Invalid unless reserved. */
+	usb_speed_t default_address_speed;
+
+	/** Map of occupied addresses */
+	bool address_occupied [USB_ADDRESS_COUNT];
+	/** The last reserved address */
+	usb_address_t last_address;
 
 	/** Size of the bandwidth pool */
 	size_t free_bw;
-	/** The last reserved address */
-	usb_address_t last_address;
 } usb2_bus_t;
 
Index: uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -111,7 +111,4 @@
 void usb_transfer_batch_init(usb_transfer_batch_t *, endpoint_t *);
 
-/** Call after status is known, but before releasing endpoint */
-int usb_transfer_batch_reset_toggle(usb_transfer_batch_t *);
-
 /** Batch finalization. */
 void usb_transfer_batch_abort(usb_transfer_batch_t *);
Index: uspace/lib/usbhost/src/bus.c
===================================================================
--- uspace/lib/usbhost/src/bus.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/src/bus.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -99,5 +99,4 @@
 
 	const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_remove);
-
 	if (!ops)
 		return ENOTSUP;
@@ -162,6 +161,18 @@
 
 	fibril_mutex_lock(&bus->guard);
-	err = register_ops->endpoint_register(ep);
-	fibril_mutex_unlock(&bus->guard);
+	if (!device->online && ep->endpoint != 0) {
+		err = EAGAIN;
+	} else if (device->endpoints[ep->endpoint] != NULL) {
+		err = EEXIST;
+	} else {
+		err = register_ops->endpoint_register(ep);
+		if (!err)
+			device->endpoints[ep->endpoint] = ep;
+	}
+	fibril_mutex_unlock(&bus->guard);
+	if (err) {
+		endpoint_del_ref(ep);
+		return err;
+	}
 
 	if (out_ep) {
@@ -171,10 +182,10 @@
 	}
 
-	return err;
+	return EOK;
 }
 
 /** Searches for an endpoint. Returns a reference.
  */
-endpoint_t *bus_find_endpoint(device_t *device, usb_target_t endpoint, usb_direction_t dir)
+endpoint_t *bus_find_endpoint(device_t *device, usb_endpoint_t endpoint)
 {
 	assert(device);
@@ -182,15 +193,10 @@
 	bus_t *bus = device->bus;
 
-	const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, device_find_endpoint);
-	if (!ops)
-		return NULL;
-
-	fibril_mutex_lock(&bus->guard);
-	endpoint_t *ep = ops->device_find_endpoint(device, endpoint, dir);
+	fibril_mutex_lock(&bus->guard);
+	endpoint_t *ep = device->endpoints[endpoint];
 	if (ep) {
 		/* Exporting reference */
 		endpoint_add_ref(ep);
 	}
-
 	fibril_mutex_unlock(&bus->guard);
 	return ep;
@@ -201,6 +207,4 @@
 	assert(ep);
 	assert(ep->device);
-	assert(ep->device->bus);
-	assert(ep->device->bus->ops);
 
 	bus_t *bus = endpoint_get_bus(ep);
@@ -218,4 +222,6 @@
 	fibril_mutex_lock(&bus->guard);
 	const int r = ops->endpoint_unregister(ep);
+	if (!r)
+		ep->device->endpoints[ep->endpoint] = NULL;
 	fibril_mutex_unlock(&bus->guard);
 
@@ -253,18 +259,4 @@
 	fibril_mutex_lock(&bus->guard);
 	const int r = ops->release_default_address(bus);
-	fibril_mutex_unlock(&bus->guard);
-	return r;
-}
-
-int bus_reset_toggle(bus_t *bus, usb_target_t target, bool all)
-{
-	assert(bus);
-
-	const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reset_toggle);
-	if (!ops)
-		return ENOTSUP;
-
-	fibril_mutex_lock(&bus->guard);
-	const int r = ops->reset_toggle(bus, target, all);
 	fibril_mutex_unlock(&bus->guard);
 	return r;
@@ -288,5 +280,5 @@
 
 	/* Temporary reference */
-	endpoint_t *ep = bus_find_endpoint(device, target, direction);
+	endpoint_t *ep = bus_find_endpoint(device, target.endpoint);
 	if (ep == NULL) {
 		usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
Index: uspace/lib/usbhost/src/ddf_helpers.c
===================================================================
--- uspace/lib/usbhost/src/ddf_helpers.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/src/ddf_helpers.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -106,10 +106,5 @@
 	assert(dev);
 
-	const usb_target_t target = {{
-		.address = dev->address,
-		.endpoint = endpoint_desc->endpoint_no
-	}};
-
-	endpoint_t *ep = bus_find_endpoint(dev, target, endpoint_desc->direction);
+	endpoint_t *ep = bus_find_endpoint(dev, endpoint_desc->endpoint_no);
 	if (!ep)
 		return ENOENT;
Index: uspace/lib/usbhost/src/endpoint.c
===================================================================
--- uspace/lib/usbhost/src/endpoint.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/src/endpoint.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -108,4 +108,6 @@
 }
 
+static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode);
+
 /** Mark the endpoint as active and block access for further fibrils.
  * @param ep endpoint_t structure.
@@ -132,5 +134,5 @@
 
 	if (ep->active_batch && ep->active_batch->error == EOK)
-		usb_transfer_batch_reset_toggle(ep->active_batch);
+		endpoint_toggle_reset(ep, ep->active_batch->toggle_reset_mode);
 
 	ep->active_batch = NULL;
@@ -155,32 +157,24 @@
 }
 
-/** Get the value of toggle bit. Either uses the toggle_get op, or just returns
- * the value of the toggle.
- * @param ep endpoint_t structure.
- */
-int endpoint_toggle_get(endpoint_t *ep)
-{
-	assert(ep);
-
-	const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_get_toggle);
-	return ops
-	    ? ops->endpoint_get_toggle(ep)
-	    : ep->toggle;
-}
-
-/** Set the value of toggle bit. Either uses the toggle_set op, or just sets
- * the toggle inside.
- * @param ep endpoint_t structure.
- */
-void endpoint_toggle_set(endpoint_t *ep, bool toggle)
-{
-	assert(ep);
-
-	const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_set_toggle);
-	if (ops) {
-		ops->endpoint_set_toggle(ep, toggle);
-	}
-	else {
-		ep->toggle = toggle;
+static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode)
+{
+	assert(ep);
+
+	if (mode == RESET_NONE)
+		return;
+
+	const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_toggle_reset);
+	if (!ops)
+		return;
+
+	device_t *dev = ep->device;
+
+	if (mode == RESET_ALL) {
+		for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) {
+			if (dev->endpoints[i])
+				ops->endpoint_toggle_reset(dev->endpoints[i]);
+		}
+	} else {
+		ops->endpoint_toggle_reset(ep);
 	}
 }
Index: uspace/lib/usbhost/src/usb2_bus.c
===================================================================
--- uspace/lib/usbhost/src/usb2_bus.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/src/usb2_bus.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -57,37 +57,4 @@
 }
 
-/** Get list that holds endpoints for given address.
- * @param bus usb2_bus structure, non-null.
- * @param addr USB address, must be >= 0.
- * @return Pointer to the appropriate list.
- */
-static list_t * get_list(usb2_bus_t *bus, usb_address_t addr)
-{
-	assert(bus);
-	assert(addr >= 0);
-	return &bus->devices[addr % ARRAY_SIZE(bus->devices)].endpoint_list;
-}
-
-/** Get speed assigned to USB address.
- *
- * @param[in] bus Device manager structure to use.
- * @param[in] address Address the caller wants to find.
- * @param[out] speed Assigned speed.
- * @return Error code.
- */
-static int get_speed(usb2_bus_t *bus, usb_address_t address, usb_speed_t *speed)
-{
-	if (!usb_address_is_valid(address))
-		return EINVAL;
-
-	if (!bus->devices[address].occupied)
-		return ENOENT;
-
-	if (speed)
-		*speed = bus->devices[address].speed;
-
-	return EOK;
-}
-
 /** Get a free USB address
  *
@@ -104,5 +71,5 @@
 		if (new_address == bus->last_address)
 			return ENOSPC;
-	} while (bus->devices[new_address].occupied);
+	} while (bus->address_occupied[new_address]);
 
 	assert(new_address != USB_ADDRESS_DEFAULT);
@@ -125,22 +92,6 @@
 		return EINVAL;
 
-	const int ret = bus->devices[address].occupied ? EOK : ENOENT;
-	bus->devices[address].occupied = false;
-
-	list_t *list = get_list(bus, address);
-	for (link_t *link = list_first(list); link != NULL; ) {
-		endpoint_t *ep = list_get_instance(link, endpoint_t, link);
-		link = list_next(link, list);
-
-		assert(ep->device->address == address);
-		list_remove(&ep->link);
-
-		usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
-		    address, ep->endpoint, usb_str_direction(ep->direction));
-
-		/* Drop bus reference */
-		endpoint_del_ref(ep);
-	}
-
+	const int ret = bus->address_occupied[address] ? EOK : ENOENT;
+	bus->address_occupied[address] = false;
 	return ret;
 }
@@ -153,5 +104,5 @@
  * @note Default address is only available in strict mode.
  */
-static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict, usb_speed_t speed)
+static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict)
 {
 	int err;
@@ -168,5 +119,5 @@
 			return err;
 	}
-	else if (bus->devices[*addr].occupied) {
+	else if (bus->address_occupied[*addr]) {
 		if (strict) {
 			return ENOENT;
@@ -177,9 +128,8 @@
 
 	assert(usb_address_is_valid(*addr));
-	assert(bus->devices[*addr].occupied == false);
+	assert(bus->address_occupied[*addr] == false);
 	assert(*addr != USB_ADDRESS_DEFAULT || strict);
 
-	bus->devices[*addr].occupied = true;
-	bus->devices[*addr].speed = speed;
+	bus->address_occupied[*addr] = true;
 
 	return EOK;
@@ -202,5 +152,5 @@
 	/** Reserve address early, we want pretty log messages */
 	usb_address_t address = USB_ADDRESS_DEFAULT;
-	if ((err = request_address(bus, &address, false, dev->speed))) {
+	if ((err = request_address(bus, &address, false))) {
 		usb_log_error("Failed to reserve new address: %s.",
 		    str_error(err));
@@ -281,8 +231,5 @@
 	 * default address.
 	 */
-	if ((err = get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) {
-		usb_log_error("Failed to verify speed: %s.", str_error(err));
-		return err;
-	}
+	dev->speed = bus->default_address_speed;
 	usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed));
 
@@ -313,28 +260,4 @@
 }
 
-/** Find endpoint.
- * @param bus usb_bus structure, non-null.
- * @param target Endpoint address.
- * @param direction Communication direction.
- * @return Pointer to endpoint_t structure representing given communication
- * target, NULL if there is no such endpoint registered.
- * @note Assumes that the internal mutex is locked.
- */
-static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction)
-{
-	usb2_bus_t *bus = bus_to_usb2_bus(device->bus);
-
-	assert(device->address == target.address);
-
-	list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) {
-		if (((direction == ep->direction)
-		       || (ep->direction == USB_DIRECTION_BOTH)
-		       || (direction == USB_DIRECTION_BOTH))
-		    && (target.endpoint == ep->endpoint))
-			return ep;
-	}
-	return NULL;
-}
-
 static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_descriptors_t *desc)
 {
@@ -347,15 +270,4 @@
 }
 
-static usb_target_t usb2_ep_to_target(endpoint_t *ep)
-{
-	assert(ep);
-	assert(ep->device);
-
-	return (usb_target_t) {{
-		.address = ep->device->address,
-		.endpoint = ep->endpoint,
-	}};
-}
-
 /** Register an endpoint to the bus. Reserves bandwidth.
  * @param bus usb_bus structure, non-null.
@@ -368,14 +280,8 @@
 	assert(ep);
 
-	/* Check for existence */
-	if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction))
-		return EEXIST;
-
 	/* Check for available bandwidth */
 	if (ep->bandwidth > bus->free_bw)
 		return ENOSPC;
 
-	endpoint_add_ref(ep);
-	list_append(&ep->link, get_list(bus, ep->device->address));
 	bus->free_bw -= ep->bandwidth;
 
@@ -390,33 +296,7 @@
 	assert(ep);
 
-	list_remove(&ep->link);
-
 	bus->free_bw += ep->bandwidth;
-	endpoint_del_ref(ep);
-
-	return EOK;
-}
-
-static int usb2_bus_reset_toggle(bus_t *bus_base, usb_target_t target, toggle_reset_mode_t mode)
-{
-	usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
-
-	if (!usb_target_is_valid(target))
-		return EINVAL;
-
-	if (mode == RESET_NONE)
-		return EOK;
-
-	int ret = ENOENT;
-
-	list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) {
-		assert(ep->device->address == target.address);
-
-		if (mode == RESET_ALL || ep->endpoint == target.endpoint) {
-			endpoint_toggle_set(ep, 0);
-			ret = EOK;
-		}
-	}
-	return ret;
+
+	return EOK;
 }
 
@@ -425,5 +305,9 @@
 	usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
 	usb_address_t addr = USB_ADDRESS_DEFAULT;
-	return request_address(bus, &addr, true, speed);
+	const int err = request_address(bus, &addr, true);
+	if (err)
+		return err;
+	bus->default_address_speed = speed;
+	return EOK;
 }
 
@@ -437,7 +321,5 @@
 	.reserve_default_address = usb2_bus_register_default_address,
 	.release_default_address = usb2_bus_release_default_address,
-	.reset_toggle = usb2_bus_reset_toggle,
 	.device_enumerate = usb2_bus_device_enumerate,
-	.device_find_endpoint = usb2_bus_find_ep,
 	.endpoint_create = usb2_bus_create_ep,
 	.endpoint_register = usb2_bus_register_ep,
@@ -460,10 +342,5 @@
 
 	bus->free_bw = available_bandwidth;
-	bus->last_address = 0;
-	for (unsigned i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
-		list_initialize(&bus->devices[i].endpoint_list);
-		bus->devices[i].speed = USB_SPEED_MAX;
-		bus->devices[i].occupied = false;
-	}
+
 	return EOK;
 }
Index: uspace/lib/usbhost/src/usb_transfer_batch.c
===================================================================
--- uspace/lib/usbhost/src/usb_transfer_batch.c	(revision 9efad54470c08d7d51f40a9febdaa103916aec6f)
+++ uspace/lib/usbhost/src/usb_transfer_batch.c	(revision 56257bacb801bcdf1177e596773f80cf4e253e5d)
@@ -71,22 +71,4 @@
 }
 
-/** Resolve resetting toggle.
- *
- * @param[in] batch Batch structure to use.
- */
-int usb_transfer_batch_reset_toggle(usb_transfer_batch_t *batch)
-{
-	assert(batch);
-
-	if (batch->error != EOK || batch->toggle_reset_mode == RESET_NONE)
-		return EOK;
-
-	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " resets %s",
-	    batch, USB_TRANSFER_BATCH_ARGS(*batch),
-	    batch->toggle_reset_mode == RESET_ALL ? "all EPs toggle" : "EP toggle");
-
-	return bus_reset_toggle(endpoint_get_bus(batch->ep), batch->target, batch->toggle_reset_mode);
-}
-
 /** Destroy the batch.
  *
