Index: uspace/drv/bus/usb/ehci/ehci_bus.c
===================================================================
--- uspace/drv/bus/usb/ehci/ehci_bus.c	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/drv/bus/usb/ehci/ehci_bus.c	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -114,5 +114,5 @@
 
 
-static int ehci_register_ep(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc)
+static int ehci_register_ep(bus_t *bus_base, device_t *dev, endpoint_t *ep, const usb_endpoint_desc_t *desc)
 {
 	ehci_bus_t *bus = (ehci_bus_t *) bus_base;
@@ -121,5 +121,5 @@
 	// TODO utilize desc->usb2
 
-	const int err = bus->parent_ops.register_endpoint(bus_base, ep, desc);
+	const int err = bus->parent_ops.register_endpoint(bus_base, dev, ep, desc);
 	if (err)
 		return err;
Index: uspace/drv/bus/usb/ohci/ohci_bus.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_bus.c	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/drv/bus/usb/ohci/ohci_bus.c	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -115,10 +115,10 @@
 
 
-static int ohci_register_ep(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc)
+static int ohci_register_ep(bus_t *bus_base, device_t *dev, endpoint_t *ep, const usb_endpoint_desc_t *desc)
 {
 	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, desc);
+	const int err = bus->parent_ops.register_endpoint(bus_base, dev, ep, desc);
 	if (err)
 		return err;
Index: uspace/drv/bus/usb/xhci/bus.c
===================================================================
--- uspace/drv/bus/usb/xhci/bus.c	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/drv/bus/usb/xhci/bus.c	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -96,5 +96,4 @@
 	endpoint_add_ref(ep0_base);
 
-	ep0_base->device = &dev->base;
 	xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
 
@@ -102,16 +101,22 @@
 		goto err_ep;
 
+	/* Register EP0 */
+	if ((err = xhci_device_add_endpoint(dev, ep0)))
+		goto err_prepared;
+
 	/* Address device */
 	if ((err = hc_address_device(hc, dev, ep0)))
-		goto err_prepared_ep;
-
-	/* Register EP0, passing Temporary reference */
-	dev->endpoints[0] = ep0;
-
-	return EOK;
-
-err_prepared_ep:
+		goto err_added;
+
+	/* Temporary reference */
+	endpoint_del_ref(ep0_base);
+	return EOK;
+
+err_added:
+	xhci_device_remove_endpoint(ep0);
+err_prepared:
 	xhci_endpoint_free_transfer_ds(ep0);
 err_ep:
+	/* Temporary reference */
 	endpoint_del_ref(ep0_base);
 err_slot:
@@ -251,34 +256,56 @@
 }
 
-static int register_endpoint(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc)
+static int register_endpoint(bus_t *bus_base, device_t *device, endpoint_t *ep_base, const usb_endpoint_desc_t *desc)
 {
 	int err;
 	xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
-	assert(bus);
-
-	assert(ep->device);
-
-	xhci_device_t *xhci_dev = xhci_device_get(ep->device);
-	xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
-
-	if ((err = prepare_endpoint(xhci_ep, desc)))
+	xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
+
+	xhci_device_t *dev = xhci_device_get(device);
+
+	if ((err = prepare_endpoint(ep, desc)))
 		return err;
 
-	usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", ep->device->address, ep->endpoint);
-	return xhci_device_add_endpoint(bus->hc, xhci_dev, xhci_ep);
-}
-
-static int unregister_endpoint(bus_t *bus_base, endpoint_t *ep)
-{
+	if ((err = xhci_device_add_endpoint(dev, ep)))
+		goto err_prepared;
+
+	usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", dev->base.address, ep->base.endpoint);
+
+	xhci_ep_ctx_t ep_ctx;
+	xhci_setup_endpoint_context(ep, &ep_ctx);
+
+	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);
+err_prepared:
+	xhci_endpoint_free_transfer_ds(ep);
+	return err;
+}
+
+static int unregister_endpoint(bus_t *bus_base, endpoint_t *ep_base)
+{
+	int err;
 	xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
-	assert(bus);
-
-	usb_log_info("Endpoint(%d:%d) unregistered from XHCI bus.", ep->device->address, ep->endpoint);
-
-	xhci_device_t *xhci_dev = xhci_device_get(ep->device);
-	xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
-	const int res = xhci_device_remove_endpoint(bus->hc, xhci_dev, xhci_ep);
-	if (res != EOK)
-		return res;
+	xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
+	xhci_device_t *dev = xhci_device_get(ep_base->device);
+
+	usb_log_info("Endpoint(%d:%d) unregistered from XHCI bus.", dev->base.address, ep->base.endpoint);
+
+	xhci_device_remove_endpoint(ep);
+
+	/* Drop the endpoint. */
+	if ((err = hc_drop_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep)))) {
+		usb_log_error("Failed to drop endpoint: %s", str_error(err));
+	}
+
+	/* Tear down TRB ring / PSA. */
+	/* TODO: Make this method "noexcept" */
+	if ((err = xhci_endpoint_free_transfer_ds(ep))) {
+		usb_log_error("Failed to free resources of an endpoint.");
+	}
 
 	return EOK;
Index: uspace/drv/bus/usb/xhci/endpoint.c
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.c	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/drv/bus/usb/xhci/endpoint.c	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -189,5 +189,5 @@
 {
 
-	usb_log_debug2("Allocating main transfer ring for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
+	usb_log_debug2("Allocating main transfer ring for endpoint %u", xhci_ep->base.endpoint);
 
 	xhci_ep->primary_stream_ctx_array = NULL;
@@ -323,5 +323,5 @@
 }
 
-int xhci_device_add_endpoint(xhci_hc_t *hc, xhci_device_t *dev, xhci_endpoint_t *ep)
+int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep)
 {
 	assert(dev);
@@ -329,5 +329,5 @@
 
 	/* Offline devices don't create new endpoints other than EP0. */
-	if (!dev->online) {
+	if (!dev->online && ep->base.endpoint > 0) {
 		return EAGAIN;
 	}
@@ -335,60 +335,29 @@
 	const usb_endpoint_t ep_num = ep->base.endpoint;
 
-	assert(&dev->base == ep->base.device);
-
-	// TODO Do not fail hard on runtime conditions
-	assert(!dev->endpoints[ep_num]);
+	if (dev->endpoints[ep_num])
+		return EEXIST;
+
+	/* Device reference */
+	endpoint_add_ref(&ep->base);
+	ep->base.device = &dev->base;
 
 	dev->endpoints[ep_num] = ep;
 	++dev->active_endpoint_count;
 
-	if (ep_num == 0) {
-		/* EP 0 is initialized while setting up the device,
-		 * so we must not issue the command now. */
-		return EOK;
-	}
-
-	/* Add endpoint. */
-	xhci_ep_ctx_t ep_ctx;
-	xhci_setup_endpoint_context(ep, &ep_ctx);
-
-	return hc_add_endpoint(hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx);
-}
-
-int xhci_device_remove_endpoint(xhci_hc_t *hc, xhci_device_t *dev, xhci_endpoint_t *ep)
-{
-	assert(&dev->base == ep->base.device);
+	return EOK;
+}
+
+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]);
-
-	int err = ENOMEM;
-	const usb_endpoint_t ep_num = ep->base.endpoint;
 
 	dev->endpoints[ep->base.endpoint] = NULL;
 	--dev->active_endpoint_count;
-
-	if (ep_num == 0) {
-		/* EP 0 is finalized while releasing the device,
-		 * so we must not issue the command now. */
-		return EOK;
-	}
-
-	/* Drop the endpoint. */
-	if ((err = hc_drop_endpoint(hc, dev->slot_id, xhci_endpoint_index(ep)))) {
-		goto err;
-	}
-
-	/* Tear down TRB ring / PSA. */
-	/* FIXME: For some reason, this causes crash at xhci_trb_ring_fini.
-	if ((err = xhci_endpoint_free_transfer_ds(ep))) {
-		goto err_cmd;
-	}
-	*/
-
-	return EOK;
-
-err:
-	dev->endpoints[ep_num] = ep;
-	++dev->active_endpoint_count;
-	return err;
+	ep->base.device = NULL;
+
+	endpoint_del_ref(&ep->base);
 }
 
Index: uspace/drv/bus/usb/xhci/endpoint.h
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.h	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/drv/bus/usb/xhci/endpoint.h	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -139,6 +139,6 @@
 void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *);
 
-int xhci_device_add_endpoint(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *);
-int xhci_device_remove_endpoint(xhci_hc_t *, xhci_device_t *, xhci_endpoint_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/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/lib/c/generic/loc.c	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -276,12 +276,13 @@
 	sysarg_t retval = async_data_write_start(exch, fqsn, str_size(fqsn));
 	
-	loc_exchange_end(exch);
 	
 	if (retval != EOK) {
 		async_forget(req);
+		loc_exchange_end(exch);
 		return retval;
 	}
 	
 	async_wait_for(req, &retval);
+	loc_exchange_end(exch);
 	
 	if (retval != EOK) {
Index: uspace/lib/usbhost/include/usb/host/bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/bus.h	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/lib/usbhost/include/usb/host/bus.h	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -84,5 +84,5 @@
 	/* The following operations are protected by a bus guard. */
 	endpoint_t *(*create_endpoint)(bus_t *);
-	int (*register_endpoint)(bus_t *, endpoint_t *, const usb_endpoint_desc_t *);
+	int (*register_endpoint)(bus_t *, device_t *, endpoint_t *, const usb_endpoint_desc_t *);
 	int (*unregister_endpoint)(bus_t *, endpoint_t *);
 	endpoint_t *(*find_endpoint)(bus_t *, device_t*, usb_target_t, usb_direction_t);
Index: uspace/lib/usbhost/src/bus.c
===================================================================
--- uspace/lib/usbhost/src/bus.c	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/lib/usbhost/src/bus.c	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -117,6 +117,5 @@
 	endpoint_add_ref(ep);
 
-	ep->device = device;
-	if ((err = bus->ops.register_endpoint(bus, ep, desc)))
+	if ((err = bus->ops.register_endpoint(bus, device, ep, desc)))
 		goto err_ep;
 
Index: uspace/lib/usbhost/src/ddf_helpers.c
===================================================================
--- uspace/lib/usbhost/src/ddf_helpers.c	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/lib/usbhost/src/ddf_helpers.c	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -519,9 +519,4 @@
 	ddf_fun_set_name(dev->fun, "roothub");
 
-	dev->tt = (usb_tt_address_t) {
-		.address = -1,
-		.port = 0,
-	};
-
 	/* Assign an address to the device */
 	if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
Index: uspace/lib/usbhost/src/usb2_bus.c
===================================================================
--- uspace/lib/usbhost/src/usb2_bus.c	(revision 70108616235ce221aaa3a66cd84292e390a11def)
+++ uspace/lib/usbhost/src/usb2_bus.c	(revision 8b8c164397f69eeebe6f33b2ef55e23bfa483828)
@@ -110,9 +110,9 @@
 
 	/** Reserve address early, we want pretty log messages */
-	const usb_address_t address = bus_reserve_default_address(bus, dev->speed);
-	if (address < 0) {
+	usb_address_t address;
+	if ((err = bus_request_address(bus, &address, false, dev->speed))) {
 		usb_log_error("Failed to reserve new address: %s.",
-		    str_error(address));
-		return address;
+		    str_error(err));
+		return err;
 	}
 	usb_log_debug("Device(%d): Reserved new address.", address);
@@ -159,4 +159,11 @@
 	}
 
+	/* We need to remove ep before we change the address */
+	if ((err = bus_remove_endpoint(bus, default_ep))) {
+		usb_log_error("Device(%d): Failed to unregister default target: %s", address, str_error(err));
+		goto err_address;
+	}
+	endpoint_del_ref(default_ep);
+
 	dev->address = address;
 
@@ -175,13 +182,6 @@
 		usb_log_error("Device(%d): Failed to register EP0: %s",
 		    address, str_error(err));
-		goto err_default_control_ep;
-	}
-
-	err = bus_remove_endpoint(bus, default_ep);
-	assert(err == EOK);
-	endpoint_del_ref(default_ep);
-
-	err = bus_release_address(bus, address);
-	assert(err == EOK);
+		goto err_address;
+	}
 
 	return EOK;
@@ -210,14 +210,22 @@
 	usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed));
 
-	/* Manage TT */
-	if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) {
-		/* For LS devices under HS hub */
-		/* TODO: How about SS hubs? */
-		dev->tt.address = dev->hub->address;
-		dev->tt.port = dev->port;
+	if (dev->hub) {
+		/* Manage TT */
+		if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) {
+			/* For LS devices under HS hub */
+			/* TODO: How about SS hubs? */
+			dev->tt.address = dev->hub->address;
+			dev->tt.port = dev->port;
+		}
+		else {
+			/* Inherit hub's TT */
+			dev->tt = dev->hub->tt;
+		}
 	}
 	else {
-		/* Inherit hub's TT */
-		dev->tt = dev->hub->tt;
+		dev->tt = (usb_tt_address_t) {
+			.address = -1,
+			.port = 0,
+		};
 	}
 
@@ -310,10 +318,10 @@
  * @param endpoint USB endpoint number.
  */
-static int usb2_bus_register_ep(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc)
+static int usb2_bus_register_ep(bus_t *bus_base, device_t *device, endpoint_t *ep, const usb_endpoint_desc_t *desc)
 {
 	usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
 	assert(ep);
 
-	assert(ep->device);
+	ep->device = device;
 
 	/* Extract USB2-related information from endpoint_desc */
@@ -347,4 +355,7 @@
 	usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
 	assert(ep);
+
+	list_remove(&ep->link);
+	ep->device = NULL;
 
 	bus->free_bw += ep->bandwidth;
