Index: uspace/drv/bus/usb/xhci/bus.c
===================================================================
--- uspace/drv/bus/usb/xhci/bus.c	(revision d1d7a9224fd43f2b1810083927b68b44d7e95e5f)
+++ uspace/drv/bus/usb/xhci/bus.c	(revision 8ea7459db801b3b4eb7340519158b2f47b54d14b)
@@ -94,24 +94,37 @@
 }
 
-static int enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev)
+int xhci_bus_remove_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev)
+{
+	// TODO: Implement me!
+	return ENOTSUP;
+}
+
+/** Ops receive generic bus_t pointer. */
+static inline xhci_bus_t *bus_to_xhci_bus(bus_t *bus_base)
+{
+	assert(bus_base);
+	return (xhci_bus_t *) bus_base;
+}
+
+static int enumerate_device(bus_t *bus_base, hcd_t *hcd, device_t *dev)
 {
 	xhci_hc_t *hc = hcd_get_driver_data(hcd);
 	assert(hc);
 
-	return xhci_bus_enumerate_device((xhci_bus_t *) bus, hc, dev);
-}
-
-static int remove_device(bus_t *bus, hcd_t *hcd, device_t *dev)
-{
-	// TODO: Implement me!
-
-	return ENOTSUP;
-}
-
-/** Ops receive generic bus_t pointer. */
-static inline xhci_bus_t *bus_to_xhci_bus(bus_t *bus_base)
-{
-	assert(bus_base);
-	return (xhci_bus_t *) bus_base;
+	xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
+	assert(bus);
+
+	return xhci_bus_enumerate_device(bus, hc, dev);
+}
+
+static int remove_device(bus_t *bus_base, hcd_t *hcd, device_t *dev)
+{
+	xhci_hc_t *hc = hcd_get_driver_data(hcd);
+	assert(hc);
+
+	xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
+	assert(bus);
+
+	return xhci_bus_remove_device(bus, hc, dev);
 }
 
@@ -246,5 +259,7 @@
 		return res;
 
-	xhci_device_remove_endpoint(hashed_dev->device, xhci_endpoint_get(ep));
+	res = xhci_device_remove_endpoint(hashed_dev->device, xhci_endpoint_get(ep));
+	if (res != EOK)
+		return res;
 
 	if (hashed_dev->device->active_endpoint_count == 0) {
Index: uspace/drv/bus/usb/xhci/bus.h
===================================================================
--- uspace/drv/bus/usb/xhci/bus.h	(revision d1d7a9224fd43f2b1810083927b68b44d7e95e5f)
+++ uspace/drv/bus/usb/xhci/bus.h	(revision 8ea7459db801b3b4eb7340519158b2f47b54d14b)
@@ -61,4 +61,5 @@
 
 int xhci_bus_enumerate_device(xhci_bus_t *, xhci_hc_t *, device_t *);
+int xhci_bus_remove_device(xhci_bus_t *, xhci_hc_t *, device_t *);
 
 #endif
Index: uspace/drv/bus/usb/xhci/endpoint.c
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.c	(revision d1d7a9224fd43f2b1810083927b68b44d7e95e5f)
+++ uspace/drv/bus/usb/xhci/endpoint.c	(revision 8ea7459db801b3b4eb7340519158b2f47b54d14b)
@@ -137,5 +137,4 @@
 	xhci_trb_ring_t *ring, usb_superspeed_endpoint_companion_descriptor_t *ss_desc)
 {
-
 	XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(ep));
 	XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, ep->base.max_packet_size);
@@ -153,5 +152,4 @@
 	} else {
 		XHCI_EP_MAX_P_STREAMS_SET(*ctx, 0);
-		/* FIXME physical pointer? */
 		XHCI_EP_TR_DPTR_SET(*ctx, ring->dequeue);
 		XHCI_EP_DCS_SET(*ctx, 1);
@@ -168,5 +166,4 @@
 	XHCI_EP_MULT_SET(*ctx, 0);
 	XHCI_EP_ERROR_COUNT_SET(*ctx, 0);
-	/* FIXME physical pointer? */
 	XHCI_EP_TR_DPTR_SET(*ctx, ring->dequeue);
 	XHCI_EP_DCS_SET(*ctx, 1);
@@ -182,5 +179,4 @@
 	XHCI_EP_MULT_SET(*ctx, 0);
 	XHCI_EP_ERROR_COUNT_SET(*ctx, 3);
-	/* FIXME physical pointer? */
 	XHCI_EP_TR_DPTR_SET(*ctx, ring->dequeue);
 	XHCI_EP_DCS_SET(*ctx, 1);
Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision d1d7a9224fd43f2b1810083927b68b44d7e95e5f)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision 8ea7459db801b3b4eb7340519158b2f47b54d14b)
@@ -636,4 +636,45 @@
 }
 
+int hc_enable_slot(xhci_hc_t *hc, uint32_t *slot_id)
+{
+	assert(hc);
+
+	int err;
+	xhci_cmd_t cmd;
+	xhci_cmd_init(&cmd);
+
+	if ((err = xhci_send_enable_slot_command(hc, &cmd)) != EOK)
+		return err;
+
+	if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT)) != EOK)
+		return err;
+
+	if (slot_id)
+		*slot_id = cmd.slot_id;
+
+	xhci_cmd_fini(&cmd);
+	return EOK;
+}
+
+int hc_address_device(xhci_hc_t *hc, uint32_t slot_id, xhci_input_ctx_t *ictx)
+{
+	assert(hc);
+	
+	int err;
+	xhci_cmd_t cmd;
+	xhci_cmd_init(&cmd);
+
+	cmd.slot_id = slot_id;
+
+	if ((err = xhci_send_address_device_command(hc, &cmd, ictx)) != EOK)
+		return err;
+
+	if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT)) != EOK)
+		return err;
+
+	xhci_cmd_fini(&cmd);
+	return EOK;
+}
+
 /**
  * @}
Index: uspace/drv/bus/usb/xhci/hc.h
===================================================================
--- uspace/drv/bus/usb/xhci/hc.h	(revision d1d7a9224fd43f2b1810083927b68b44d7e95e5f)
+++ uspace/drv/bus/usb/xhci/hc.h	(revision 8ea7459db801b3b4eb7340519158b2f47b54d14b)
@@ -98,4 +98,6 @@
 void hc_fini(xhci_hc_t *);
 int hc_ring_doorbell(xhci_hc_t *, unsigned, unsigned);
+int hc_enable_slot(xhci_hc_t *, uint32_t *);
+int hc_address_device(xhci_hc_t *, uint32_t, xhci_input_ctx_t *);
 
 #endif
Index: uspace/drv/bus/usb/xhci/rh.c
===================================================================
--- uspace/drv/bus/usb/xhci/rh.c	(revision d1d7a9224fd43f2b1810083927b68b44d7e95e5f)
+++ uspace/drv/bus/usb/xhci/rh.c	(revision 8ea7459db801b3b4eb7340519158b2f47b54d14b)
@@ -73,4 +73,20 @@
 }
 
+static void setup_control_ep0_ctx(xhci_ep_ctx_t *ctx, xhci_trb_ring_t *ring,
+		const xhci_port_speed_t *speed)
+{
+	XHCI_EP_TYPE_SET(*ctx, EP_TYPE_CONTROL);
+	// TODO: must be changed with a command after USB descriptor is read
+	// See 4.6.5 in XHCI specification, first note
+	XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, speed->major == 3 ? 512 : 8);
+	XHCI_EP_MAX_BURST_SIZE_SET(*ctx, 0);
+	XHCI_EP_TR_DPTR_SET(*ctx, ring->dequeue);
+	XHCI_EP_DCS_SET(*ctx, 1);
+	XHCI_EP_INTERVAL_SET(*ctx, 0);
+	XHCI_EP_MAX_P_STREAMS_SET(*ctx, 0);
+	XHCI_EP_MULT_SET(*ctx, 0);
+	XHCI_EP_ERROR_COUNT_SET(*ctx, 3);
+}
+
 // TODO: Check device deallocation, we free device_ctx in hc.c, not
 //       sure about the other structs.
@@ -79,29 +95,21 @@
 int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev, xhci_bus_t *bus)
 {
+	/* FIXME: Certainly not generic solution. */
+	const uint32_t route_str = 0;
+
 	int err;
 	xhci_hc_t *hc = rh->hc;
-
-	xhci_cmd_t cmd;
-	xhci_cmd_init(&cmd);
-
-	/* XXX Certainly not generic solution. */
-	uint32_t route_str = 0;
-
 	const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port);
 
-	xhci_send_enable_slot_command(hc, &cmd);
-	if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT)) != EOK)
+	/* Enable new slot */
+	uint32_t slot_id;
+	if ((err = hc_enable_slot(hc, &slot_id)) != EOK)
 		return err;
-
-	uint32_t slot_id = cmd.slot_id;
-
 	usb_log_debug2("Obtained slot ID: %u.\n", slot_id);
-	xhci_cmd_fini(&cmd);
-
+
+	/* Setup input context */
 	xhci_input_ctx_t *ictx = malloc(sizeof(xhci_input_ctx_t));
-	if (!ictx) {
+	if (!ictx)
 		return ENOMEM;
-	}
-
 	memset(ictx, 0, sizeof(xhci_input_ctx_t));
 
@@ -124,19 +132,7 @@
 	if (err)
 		goto err_ring;
-
-	XHCI_EP_TYPE_SET(ictx->endpoint_ctx[0], EP_TYPE_CONTROL);
-	// TODO: must be changed with a command after USB descriptor is read
-	// See 4.6.5 in XHCI specification, first note
-	XHCI_EP_MAX_PACKET_SIZE_SET(ictx->endpoint_ctx[0],
-	    speed->major == 3 ? 512 : 8);
-	XHCI_EP_MAX_BURST_SIZE_SET(ictx->endpoint_ctx[0], 0);
-	/* FIXME physical pointer? */
-	XHCI_EP_TR_DPTR_SET(ictx->endpoint_ctx[0], ep_ring->dequeue);
-	XHCI_EP_DCS_SET(ictx->endpoint_ctx[0], 1);
-	XHCI_EP_INTERVAL_SET(ictx->endpoint_ctx[0], 0);
-	XHCI_EP_MAX_P_STREAMS_SET(ictx->endpoint_ctx[0], 0);
-	XHCI_EP_MULT_SET(ictx->endpoint_ctx[0], 0);
-	XHCI_EP_ERROR_COUNT_SET(ictx->endpoint_ctx[0], 3);
-
+	setup_control_ep0_ctx(&ictx->endpoint_ctx[0], ep_ring, speed);
+
+	/* Setup and register device context */
 	xhci_device_ctx_t *dctx = malloc32(sizeof(xhci_device_ctx_t));
 	if (!dctx) {
@@ -145,5 +141,4 @@
 	}
 	memset(dctx, 0, sizeof(xhci_device_ctx_t));
-
 	hc->dcbaa[slot_id] = addr_to_phys(dctx);
 
@@ -152,12 +147,7 @@
 	hc->dcbaa_virt[slot_id].trs[0] = ep_ring;
 
-	xhci_cmd_init(&cmd);
-	cmd.slot_id = slot_id;
-	xhci_send_address_device_command(hc, &cmd, ictx);
-	if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT)) != EOK)
+	/* Address device */
+	if ((err = hc_address_device(hc, slot_id, ictx)) != EOK)
 		goto err_dctx;
-
-	xhci_cmd_fini(&cmd);
-
 	dev->address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx);
 	usb_log_debug2("Obtained USB address: %d.\n", dev->address);
