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.
  *
