Index: uspace/drv/bus/usb/xhci/bus.c
===================================================================
--- uspace/drv/bus/usb/xhci/bus.c	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/bus.c	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -121,5 +121,5 @@
 	endpoint_del_ref(ep0_base);
 err_slot:
-	hc_disable_slot(hc, dev->slot_id);
+	hc_disable_slot(hc, dev);
 	return err;
 }
@@ -189,5 +189,5 @@
 
 	/* Block creation of new endpoints and transfers. */
-	usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev->fun));
+	usb_log_debug2("Device " XHCI_DEV_FMT " going offline.", XHCI_DEV_ARGS(*xhci_dev));
 	fibril_mutex_lock(&dev->guard);
 	xhci_dev->online = false;
@@ -195,5 +195,5 @@
 
 	/* Abort running transfers. */
-	usb_log_debug2("Aborting all active transfers to '%s'.", ddf_fun_get_name(dev->fun));
+	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];
@@ -203,8 +203,6 @@
 		/* FIXME: This is racy. */
 		if ((err = xhci_transfer_abort(&ep->active_transfer))) {
-			usb_log_warning("Failed to abort active %s transfer to "
-			    " endpoint %d of detached device '%s': %s",
-			    usb_str_transfer_type(ep->base.transfer_type),
-			    ep->base.endpoint, ddf_fun_get_name(dev->fun),
+			usb_log_warning("Failed to abort active transfer to "
+			    " endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep),
 			    str_error(err));
 		}
@@ -215,9 +213,18 @@
 	/* Make DDF (and all drivers) forget about the device. */
 	if ((err = ddf_fun_unbind(dev->fun))) {
-		usb_log_warning("Failed to unbind DDF function of device '%s': %s",
-		    ddf_fun_get_name(dev->fun), str_error(err));
-	}
-
-	/* Unregister remaining endpoints. */
+		usb_log_warning("Failed to unbind DDF function of device " XHCI_DEV_FMT ": %s",
+		    XHCI_DEV_ARGS(*xhci_dev), str_error(err));
+	}
+
+	/* Disable the slot, dropping all endpoints. */
+	const uint32_t slot_id = xhci_dev->slot_id;
+	if ((err = hc_disable_slot(hc, xhci_dev))) {
+		usb_log_warning("Failed to disable slot of device " XHCI_DEV_FMT ": %s",
+		    XHCI_DEV_ARGS(*xhci_dev), str_error(err));
+	}
+
+	bus->devices_by_slot[slot_id] = NULL;
+
+	/* Unregister remaining endpoints, freeing memory. */
 	for (unsigned i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {
 		if (!xhci_dev->endpoints[i])
@@ -225,18 +232,8 @@
 
 		if ((err = unregister_endpoint(&bus->base, &xhci_dev->endpoints[i]->base))) {
-			usb_log_warning("Failed to unregister EP (%u:%u): %s", dev->address, i, str_error(err));
+			usb_log_warning("Failed to unregister endpoint " XHCI_EP_FMT ": %s",
+			    XHCI_EP_ARGS(*xhci_dev->endpoints[i]), str_error(err));
 		}
 	}
-
-	// XXX: Ugly here. Move to device_destroy at endpoint.c?
-	if ((err = hc_disable_slot(hc, xhci_dev->slot_id))) {
-		usb_log_warning("Failed to disable slot %d for device '%s': %s",
-		    xhci_dev->slot_id, ddf_fun_get_name(dev->fun), str_error(err));
-	}
-
-	free32(xhci_dev->dev_ctx);
-	hc->dcbaa[xhci_dev->slot_id] = 0;
-
-	bus->devices_by_slot[xhci_dev->slot_id] = NULL;
 
 	/* Destroy DDF device. */
@@ -291,9 +288,9 @@
 	/* Transition the device from the Addressed to the Configured state. */
 	if ((err = hc_configure_device(hc, dev->slot_id))) {
-		usb_log_warning("Failed to configure device %d.", dev_base->address);
+		usb_log_warning("Failed to configure device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*dev));
 	}
 
 	/* Block creation of new endpoints and transfers. */
-	usb_log_debug2("Device '%s' going online.", ddf_fun_get_name(dev_base->fun));
+	usb_log_debug2("Device " XHCI_DEV_FMT " going online.", XHCI_DEV_ARGS(*dev));
 	fibril_mutex_lock(&dev_base->guard);
 	dev->online = true;
@@ -326,5 +323,5 @@
 
 	/* Block creation of new endpoints and transfers. */
-	usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev_base->fun));
+	usb_log_debug2("Device " XHCI_DEV_FMT " going offline.", XHCI_DEV_ARGS(*dev));
 	fibril_mutex_lock(&dev_base->guard);
 	dev->online = false;
@@ -347,16 +344,14 @@
 	/* Issue one HC command to simultaneously drop all endpoints except zero. */
 	if ((err = hc_deconfigure_device(hc, dev->slot_id))) {
-		usb_log_warning("Failed to deconfigure device %d.", dev_base->address);
+		usb_log_warning("Failed to deconfigure device " XHCI_DEV_FMT ".",
+		    XHCI_DEV_ARGS(*dev));
 	}
 
 	/* Tear down TRB ring / PSA. */
-	/* TODO: Make this method "noexcept" */
 	for (unsigned i = 1; i < ARRAY_SIZE(endpoints); ++i) {
 		if (!endpoints[i])
 			continue;
 
-		if ((err = xhci_endpoint_free_transfer_ds(endpoints[i]))) {
-			usb_log_warning("Failed to free resources of EP (%u:%u): %s", dev_base->address, i, str_error(err));
-		}
+		xhci_endpoint_free_transfer_ds(endpoints[i]);
 	}
 
@@ -404,5 +399,5 @@
 		goto err_prepared;
 
-	usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", dev->base.address, ep->base.endpoint);
+	usb_log_info("Endpoint " XHCI_EP_FMT " registered to XHCI bus.", XHCI_EP_ARGS(*ep));
 
 	xhci_ep_ctx_t ep_ctx;
@@ -428,18 +423,20 @@
 	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);
+	usb_log_info("Endpoint " XHCI_EP_FMT " unregistered from XHCI bus.", XHCI_EP_ARGS(*ep));
 
 	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));
+	/* If device slot is still available, drop the endpoint. */
+	if (dev->slot_id) {
+		if ((err = hc_drop_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep)))) {
+			usb_log_error("Failed to drop endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep), str_error(err));
+		}
+	} else {
+		usb_log_debug("Not going to drop endpoint " XHCI_EP_FMT " because"
+		    " the slot has already been disabled.", XHCI_EP_ARGS(*ep));
 	}
 
 	/* 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.");
-	}
+	xhci_endpoint_free_transfer_ds(ep);
 
 	return EOK;
Index: uspace/drv/bus/usb/xhci/endpoint.c
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.c	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/endpoint.c	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -188,6 +188,6 @@
 int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *xhci_ep)
 {
-
-	usb_log_debug2("Allocating main transfer ring for endpoint %u", xhci_ep->base.endpoint);
+	/* Can't use XHCI_EP_FMT because the endpoint may not have device. */
+	usb_log_debug2("Allocating main transfer ring for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
 
 	xhci_ep->primary_stream_ctx_array = NULL;
@@ -201,11 +201,8 @@
 }
 
-int xhci_endpoint_free_transfer_ds(xhci_endpoint_t *xhci_ep)
-{
-	/* FIXME: For some reason (possibly memory corruption), this crashes. */
-	return EOK;
-
+void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *xhci_ep)
+{
 	if (endpoint_using_streams(xhci_ep)) {
-		usb_log_debug2("Freeing primary stream context array for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
+		usb_log_debug2("Freeing primary stream context array of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
 
 		// maybe check if LSA, then skip?
@@ -223,13 +220,8 @@
 		free32(xhci_ep->primary_stream_ctx_array);
 	} else {
-		usb_log_debug2("Freeing main transfer ring for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
-
-		int err;
-		if ((err = xhci_trb_ring_fini(&xhci_ep->ring))) {
-			return err;
-		}
-	}
-
-	return EOK;
+		usb_log_debug2("Freeing main transfer ring of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
+
+		xhci_trb_ring_fini(&xhci_ep->ring);
+	}
 }
 
@@ -344,7 +336,5 @@
 	endpoint_add_ref(&ep->base);
 	ep->base.device = &dev->base;
-
 	dev->endpoints[ep_num] = ep;
-	++dev->active_endpoint_count;
 
 	return EOK;
@@ -357,7 +347,5 @@
 
 	assert(dev->endpoints[ep->base.endpoint]);
-
 	dev->endpoints[ep->base.endpoint] = NULL;
-	--dev->active_endpoint_count;
 	ep->base.device = NULL;
 
Index: uspace/drv/bus/usb/xhci/endpoint.h
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.h	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/endpoint.h	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -91,6 +91,7 @@
 
 #define XHCI_EP_FMT  "(%d:%d %s)"
+/* FIXME: "Device -1" messes up log messages, figure out a better way. */
 #define XHCI_EP_ARGS(ep)		\
-	((ep).base.device->address),	\
+	((ep).base.device ? (ep).base.device->address : -1),	\
 	((ep).base.endpoint),		\
 	(usb_str_transfer_type((ep).base.transfer_type))
@@ -114,9 +115,6 @@
 	xhci_device_ctx_t *dev_ctx;
 
-	/** All endpoints of the device. Inactive ones are NULL */
+	/** All endpoints of the device. Dropped ones are NULL */
 	xhci_endpoint_t *endpoints[XHCI_EP_COUNT];
-
-	/** Number of non-NULL endpoints. Reference count of sorts. */
-	uint8_t active_endpoint_count;
 
 	/** Flag indicating whether the device is USB3 (it's USB2 otherwise). */
@@ -127,8 +125,11 @@
 } xhci_device_t;
 
+#define XHCI_DEV_FMT  "(%s, slot %d)"
+#define XHCI_DEV_ARGS(dev)		 ddf_fun_get_name((dev).base.fun), (dev).slot_id
+
 int xhci_endpoint_init(xhci_endpoint_t *, xhci_bus_t *);
 void xhci_endpoint_fini(xhci_endpoint_t *);
 int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *);
-int xhci_endpoint_free_transfer_ds(xhci_endpoint_t *);
+void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *);
 
 int xhci_endpoint_request_streams(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *, unsigned);
Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -617,8 +617,24 @@
 }
 
-int hc_disable_slot(xhci_hc_t *hc, uint32_t slot_id)
-{
+int hc_disable_slot(xhci_hc_t *hc, xhci_device_t *dev)
+{
+	int err;
 	assert(hc);
-	return xhci_cmd_sync_inline(hc, DISABLE_SLOT, .slot_id = slot_id);
+
+	if ((err = xhci_cmd_sync_inline(hc, DISABLE_SLOT, .slot_id = dev->slot_id))) {
+		return err;
+	}
+
+	/* Free the device context. */
+	hc->dcbaa[dev->slot_id] = 0;
+	if (dev->dev_ctx) {
+		free32(dev->dev_ctx);
+		dev->dev_ctx = NULL;
+	}
+
+	/* Mark the slot as invalid. */
+	dev->slot_id = 0;
+
+	return EOK;
 }
 
@@ -654,5 +670,5 @@
 	 * we have to rely on reverse mapping on others. */
 	if (!hc->speed_to_psiv[dev->base.speed]) {
-		usb_log_error("Device reported an usb speed that cannot be mapped to HC port speed.");
+		usb_log_error("Device reported an USB speed that cannot be mapped to HC port speed.");
 		return EINVAL;
 	}
Index: uspace/drv/bus/usb/xhci/hc.h
===================================================================
--- uspace/drv/bus/usb/xhci/hc.h	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/hc.h	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -102,5 +102,5 @@
 int hc_ring_doorbell(xhci_hc_t *, unsigned, unsigned);
 int hc_enable_slot(xhci_hc_t *, uint32_t *);
-int hc_disable_slot(xhci_hc_t *, uint32_t);
+int hc_disable_slot(xhci_hc_t *, xhci_device_t *);
 int hc_address_device(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *);
 int hc_configure_device(xhci_hc_t *, uint32_t);
Index: uspace/drv/bus/usb/xhci/rh.c
===================================================================
--- uspace/drv/bus/usb/xhci/rh.c	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/rh.c	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -119,5 +119,6 @@
 
 	if ((err = ddf_fun_bind(dev->fun))) {
-		usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err));
+		usb_log_error("Failed to register device " XHCI_DEV_FMT " DDF function: %s.",
+		    XHCI_DEV_ARGS(*xhci_dev), str_error(err));
 		goto err_usb_dev;
 	}
@@ -185,5 +186,6 @@
 	}
 
-	usb_log_info("Device '%s' at port %u has been disconnected.", ddf_fun_get_name(dev->base.fun), port_id);
+	usb_log_info("Device " XHCI_DEV_FMT " at port %u has been disconnected.",
+	    XHCI_DEV_ARGS(*dev), port_id);
 
 	/* Mark the device as detached. */
@@ -195,6 +197,6 @@
 	/* Remove device from XHCI bus. */
 	if ((err = xhci_bus_remove_device(&rh->hc->bus, rh->hc, &dev->base))) {
-		usb_log_warning("Failed to remove device '%s' from XHCI bus: %s",
-		    ddf_fun_get_name(dev->base.fun), str_error(err));
+		usb_log_warning("Failed to remove device " XHCI_DEV_FMT " from XHCI bus: %s",
+		    XHCI_DEV_ARGS(*dev), str_error(err));
 	}
 
Index: uspace/drv/bus/usb/xhci/transfers.c
===================================================================
--- uspace/drv/bus/usb/xhci/transfers.c	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/transfers.c	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -265,5 +265,5 @@
 	xhci_device_t *dev = hc->bus.devices_by_slot[slot_id];
 	if (!dev) {
-		usb_log_error("Transfer event on unknown device slot %u!", slot_id);
+		usb_log_error("Transfer event on disabled slot %u", slot_id);
 		return ENOENT;
 	}
@@ -272,5 +272,6 @@
 	xhci_endpoint_t *ep = xhci_device_get_endpoint(dev, ep_num);
 	if (!ep) {
-		usb_log_error("Transfer event on unknown endpoint num %u, device slot %u!", ep_num, slot_id);
+		usb_log_error("Transfer event on dropped endpoint %u of device "
+		    XHCI_DEV_FMT, ep_num, XHCI_DEV_ARGS(*dev));
 		return ENOENT;
 	}
@@ -322,5 +323,6 @@
 	// FIXME: find a better way to check if the ring is not initialized
 	if (!xhci_ep->ring.segment_count) {
-		usb_log_error("Ring not initialized for endpoint num %u!", xhci_ep->base.endpoint);
+		usb_log_error("Ring not initialized for endpoint " XHCI_EP_FMT,
+                    XHCI_EP_ARGS(*xhci_ep));
 		return EINVAL;
 	}
Index: uspace/drv/bus/usb/xhci/trb_ring.c
===================================================================
--- uspace/drv/bus/usb/xhci/trb_ring.c	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/trb_ring.c	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -121,5 +121,5 @@
 }
 
-int xhci_trb_ring_fini(xhci_trb_ring_t *ring)
+void xhci_trb_ring_fini(xhci_trb_ring_t *ring)
 {
 	assert(ring);
@@ -129,6 +129,4 @@
 		dmamem_unmap_anonymous(segment);
 	}
-
-	return EOK;
 }
 
@@ -292,5 +290,5 @@
 }
 
-int xhci_event_ring_fini(xhci_event_ring_t *ring)
+void xhci_event_ring_fini(xhci_event_ring_t *ring)
 {
 	list_foreach_safe(ring->segments, cur, next) {
@@ -301,6 +299,4 @@
 	if (ring->erst)
 		free32(ring->erst);
-
-	return EOK;
 }
 
Index: uspace/drv/bus/usb/xhci/trb_ring.h
===================================================================
--- uspace/drv/bus/usb/xhci/trb_ring.h	(revision 62f802523b41e74b299ba42124cacd5321011b0a)
+++ uspace/drv/bus/usb/xhci/trb_ring.h	(revision 9620a545d9cf4723bd1a65704744dfc37020bdbe)
@@ -74,5 +74,5 @@
 
 int xhci_trb_ring_init(xhci_trb_ring_t *);
-int xhci_trb_ring_fini(xhci_trb_ring_t *);
+void xhci_trb_ring_fini(xhci_trb_ring_t *);
 int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t *, uintptr_t *);
 int xhci_trb_ring_enqueue_multiple(xhci_trb_ring_t *, xhci_trb_t *, size_t, uintptr_t *);
@@ -112,5 +112,5 @@
 
 int xhci_event_ring_init(xhci_event_ring_t *);
-int xhci_event_ring_fini(xhci_event_ring_t *);
+void xhci_event_ring_fini(xhci_event_ring_t *);
 int xhci_event_ring_dequeue(xhci_event_ring_t *, xhci_trb_t *);
 
