Index: uspace/drv/bus/usb/xhci/debug.c
===================================================================
--- uspace/drv/bus/usb/xhci/debug.c	(revision 4688350b86a249553314c54ec06ed218cc3dba29)
+++ uspace/drv/bus/usb/xhci/debug.c	(revision 370a1c8fbf927799b3280418d76d4816d3adfb0d)
@@ -287,5 +287,5 @@
 			name.packed = host2uint32_t_le(XHCI_REG_RD(ec, XHCI_EC_SP_NAME));
 			ports_from = XHCI_REG_RD(ec, XHCI_EC_SP_CP_OFF);
-			ports_to = ports_from + XHCI_REG_RD(ec, XHCI_EC_SP_CP_OFF) - 1;
+			ports_to = ports_from + XHCI_REG_RD(ec, XHCI_EC_SP_CP_COUNT) - 1;
 			usb_log_debug("\tProtocol %4s%u.%u, ports %u-%u", name.str,
 			    XHCI_REG_RD(ec, XHCI_EC_SP_MAJOR),
Index: uspace/drv/bus/usb/xhci/endpoint.h
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.h	(revision 4688350b86a249553314c54ec06ed218cc3dba29)
+++ uspace/drv/bus/usb/xhci/endpoint.h	(revision 370a1c8fbf927799b3280418d76d4816d3adfb0d)
@@ -43,4 +43,15 @@
 #include <usb/host/hcd.h>
 
+enum {
+	EP_TYPE_INVALID = 0,
+	EP_TYPE_ISOCH_OUT = 1,
+	EP_TYPE_BULK_OUT = 2,
+	EP_TYPE_INTERRUPT_OUT = 3,
+	EP_TYPE_CONTROL = 4,
+	EP_TYPE_ISOCH_IN = 5,
+	EP_TYPE_BULK_IN = 6,
+	EP_TYPE_INTERRUPT_IN = 7
+};
+
 /** Connector structure linking endpoint context to the endpoint. */
 typedef struct xhci_endpoint {
Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision 4688350b86a249553314c54ec06ed218cc3dba29)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision 370a1c8fbf927799b3280418d76d4816d3adfb0d)
@@ -83,10 +83,19 @@
 				 * == 0.
 				 */
+
+	 			unsigned ports_from = XHCI_REG_RD(ec, XHCI_EC_SP_CP_OFF);
+	 			unsigned ports_to = ports_from
+					+ XHCI_REG_RD(ec, XHCI_EC_SP_CP_COUNT) - 1;
+
 				if (major == 2) {
 					hc->speeds[1] = ps_default_full;
 					hc->speeds[2] = ps_default_low;
 					hc->speeds[3] = ps_default_high;
+					hc->rh.usb2_port_start = ports_from;
+					hc->rh.usb2_port_end = ports_to;
 				} else if (major == 3) {
 					hc->speeds[4] = ps_default_super;
+					hc->rh.usb3_port_start = ports_from;
+					hc->rh.usb3_port_end = ports_to;
 				} else {
 					return EINVAL;
Index: uspace/drv/bus/usb/xhci/hw_struct/context.h
===================================================================
--- uspace/drv/bus/usb/xhci/hw_struct/context.h	(revision 4688350b86a249553314c54ec06ed218cc3dba29)
+++ uspace/drv/bus/usb/xhci/hw_struct/context.h	(revision 370a1c8fbf927799b3280418d76d4816d3adfb0d)
@@ -109,4 +109,6 @@
 #define XHCI_SLOT_CTX_ENTRIES_SET(ctx, val) \
     xhci_dword_set_bits(&(ctx).data[0], val, 31, 27)
+#define XHCI_SLOT_ROUTE_STRING_SET(ctx, val) \
+	xhci_dword_set_bits(&(ctx).data[0], (val & 0xFFFFF), 19, 0)
 
 #define XHCI_SLOT_ROUTE_STRING(ctx)     XHCI_DWORD_EXTRACT((ctx).data[0], 19,  0)
Index: uspace/drv/bus/usb/xhci/rh.c
===================================================================
--- uspace/drv/bus/usb/xhci/rh.c	(revision 4688350b86a249553314c54ec06ed218cc3dba29)
+++ uspace/drv/bus/usb/xhci/rh.c	(revision 370a1c8fbf927799b3280418d76d4816d3adfb0d)
@@ -40,4 +40,5 @@
 #include "debug.h"
 #include "commands.h"
+#include "endpoint.h"
 #include "hc.h"
 #include "hw_struct/trb.h"
@@ -58,5 +59,5 @@
 // TODO: Check device deallocation, we free device_ctx in hc.c, not
 //       sure about the other structs.
-static int alloc_dev(xhci_hc_t *hc, uint8_t port)
+static int alloc_dev(xhci_hc_t *hc, uint8_t port, uint32_t route_str)
 {
 	int err;
@@ -67,6 +68,8 @@
 
 	xhci_send_enable_slot_command(hc, cmd);
-	if ((err = xhci_wait_for_command(cmd, 100000)) != EOK)
+	if ((err = xhci_wait_for_command(cmd, 100000)) != EOK) {
+		usb_log_error("Failed to enable a slot for the device.");
 		goto err_command;
+	}
 
 	uint32_t slot_id = cmd->slot_id;
@@ -91,6 +94,6 @@
 	XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, port);
 	XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1);
-
-	// TODO: where do we save this? the ring should be associated with device structure somewhere
+	XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, route_str);
+
 	xhci_trb_ring_t *ep_ring = malloc32(sizeof(xhci_trb_ring_t));
 	if (!ep_ring) {
@@ -103,11 +106,11 @@
 		goto err_ring;
 
-	xhci_port_regs_t *regs = &hc->op_regs->portrs[port - 1];
-	uint8_t port_speed_id = XHCI_REG_RD(regs, XHCI_PORT_PS);
-
-	XHCI_EP_TYPE_SET(ictx->endpoint_ctx[0], 4);
+	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],
-	    hc->speeds[port_speed_id].tx_bps);
+	    xhci_is_usb3_port(&hc->rh, port) ? 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);
@@ -139,5 +142,5 @@
 	ictx = NULL;
 
-        // TODO: Issue configure endpoint commands (sec 4.3.5).
+ 	// TODO: Issue configure endpoint commands (sec 4.3.5).
 
 	return EOK;
@@ -171,16 +174,28 @@
 	uint8_t link_state = XHCI_REG_RD(regs, XHCI_PORT_PLS);
 	// FIXME: do we have a better way to detect if this is usb2 or usb3 device?
-	if (link_state == 0) {
-		/* USB3 is automatically advanced to enabled. */
-		uint8_t port_speed = XHCI_REG_RD(regs, XHCI_PORT_PS);
-		usb_log_debug2("Detected new device on port %u, port speed id %u.", port_id, port_speed);
-
-		alloc_dev(hc, port_id);
-	} else if (link_state == 5) {
-		/* USB 3 failed to enable. */
-		usb_log_debug("USB 3 port couldn't be enabled.");
-	} else if (link_state == 7) {
+	if (xhci_is_usb3_port(&hc->rh, port_id)) {
+		if(link_state == 0) {
+			/* USB3 is automatically advanced to enabled. */
+			uint8_t port_speed = XHCI_REG_RD(regs, XHCI_PORT_PS);
+			usb_log_debug("Detected new device on port %u, port speed id %u.", port_id, port_speed);
+
+			alloc_dev(hc, port_id, 0);
+		}
+		else if (link_state == 5) {
+			/* USB 3 failed to enable. */
+			usb_log_error("USB 3 port couldn't be enabled.");
+		}
+		else {
+			usb_log_error("USB 3 port is in invalid state %u.", link_state);
+		}
+	}
+	else {
 		usb_log_debug("USB 2 device attached, issuing reset.");
 		xhci_reset_hub_port(hc, port_id);
+		/*
+			FIXME: we need to wait for the event triggered by the reset
+			and then alloc_dev()... can't it be done directly instead of
+			going around?
+		*/
 	}
 
@@ -201,5 +216,6 @@
 		uint8_t port_speed = XHCI_REG_RD(regs, XHCI_PORT_PS);
 		usb_log_debug2("Detected port reset on port %u, port speed id %u.", port_id, port_speed);
-		alloc_dev(hc, port_id);
+		/** FIXME: only if that port is not yet initialized */
+		alloc_dev(hc, port_id, 0);
 	}
 
Index: uspace/drv/bus/usb/xhci/rh.h
===================================================================
--- uspace/drv/bus/usb/xhci/rh.h	(revision 4688350b86a249553314c54ec06ed218cc3dba29)
+++ uspace/drv/bus/usb/xhci/rh.h	(revision 370a1c8fbf927799b3280418d76d4816d3adfb0d)
@@ -55,4 +55,9 @@
 	/** Interrupt transfer waiting for an actual interrupt to occur */
 	usb_transfer_batch_t *unfinished_interrupt_transfer;
+
+	uint8_t usb2_port_start;
+	uint8_t usb2_port_end;
+	uint8_t usb3_port_start;
+	uint8_t usb3_port_end;
 } xhci_rh_t;
 
@@ -77,4 +82,8 @@
 }
 
+static inline bool xhci_is_usb3_port(xhci_rh_t* rh, uint8_t port) {
+	return port >= rh->usb3_port_start && port <= rh->usb3_port_end;
+}
+
 #endif
 
