Index: uspace/drv/bus/usb/xhci/Makefile
===================================================================
--- uspace/drv/bus/usb/xhci/Makefile	(revision 05aeee0e2df025a83c9a5ed163b0b302eec1b8e6)
+++ uspace/drv/bus/usb/xhci/Makefile	(revision 7bd99bfae7aabeabefaa09fab2ced431b9975c0d)
@@ -47,4 +47,5 @@
 	scratchpad.c \
 	commands.c \
+    rh.c \
 	main.c
 
Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision 05aeee0e2df025a83c9a5ed163b0b302eec1b8e6)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision 7bd99bfae7aabeabefaa09fab2ced431b9975c0d)
@@ -40,4 +40,5 @@
 #include "debug.h"
 #include "hc.h"
+#include "rh.h"
 #include "hw_struct/trb.h"
 #include "commands.h"
@@ -360,7 +361,11 @@
 static void hc_handle_event(xhci_hc_t *hc, xhci_trb_t *trb)
 {
+	usb_log_debug2("TRB event encountered.");
 	switch (TRB_TYPE(*trb)) {
 		case XHCI_TRB_TYPE_COMMAND_COMPLETION_EVENT:
 			xhci_handle_command_completion(hc, trb);
+			break;
+		case XHCI_TRB_TYPE_PORT_STATUS_CHANGE_EVENT:
+			xhci_handle_port_status_change_event(hc, trb);
 			break;
 		default:
Index: uspace/drv/bus/usb/xhci/hw_struct/regs.h
===================================================================
--- uspace/drv/bus/usb/xhci/hw_struct/regs.h	(revision 05aeee0e2df025a83c9a5ed163b0b302eec1b8e6)
+++ uspace/drv/bus/usb/xhci/hw_struct/regs.h	(revision 7bd99bfae7aabeabefaa09fab2ced431b9975c0d)
@@ -286,5 +286,6 @@
 #define XHCI_PORT_PLS           portsc, 32, RANGE,  8,  5
 #define XHCI_PORT_PP            portsc, 32,  FLAG,  9
-#define XHCI_PORT_PIC           portsc, 32, RANGE, 13, 10
+#define XHCI_PORT_PS            portsc, 32, RANGE, 13, 10
+#define XHCI_PORT_PIC           portsc, 32, RANGE, 15, 14
 #define XHCI_PORT_LWS           portsc, 32,  FLAG, 16
 #define XHCI_PORT_CSC           portsc, 32,  FLAG, 17
Index: uspace/drv/bus/usb/xhci/rh.c
===================================================================
--- uspace/drv/bus/usb/xhci/rh.c	(revision 7bd99bfae7aabeabefaa09fab2ced431b9975c0d)
+++ uspace/drv/bus/usb/xhci/rh.c	(revision 7bd99bfae7aabeabefaa09fab2ced431b9975c0d)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017 Michal Staruch
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbxhci
+ * @{
+ */
+/** @file
+ * @brief The roothub structures abstraction.
+ */
+ 
+#include <errno.h>
+#include <str_error.h>
+#include <usb/debug.h>
+#include "debug.h"
+#include "hc.h"
+#include "rh.h"
+
+#include "hw_struct/trb.h"
+
+static int handle_connected_device(xhci_hc_t* hc, xhci_port_regs_t* regs, uint8_t port_id) {
+    uint8_t link_state = XHCI_REG_RD(regs, XHCI_PORT_PLS);
+    if(link_state == 0) {
+        // USB3 is automatically advance 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);
+        // TODO: Assign device slot (specification 4.3.2) 
+    }
+    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) {
+        usb_log_debug("USB 2 device attached, issuing reset.");
+        xhci_reset_hub_port(hc, port_id);
+    }
+
+    return EOK;
+}
+
+int xhci_handle_port_status_change_event(xhci_hc_t *hc, xhci_trb_t *trb) {
+    uint8_t port_id = xhci_get_hub_port(trb);
+    usb_log_debug("Port status change event detected for port %u.", port_id);
+    xhci_port_regs_t* regs = &hc->op_regs->portrs[port_id];
+
+    // Port reset change
+    if(XHCI_REG_RD(regs, XHCI_PORT_PRC)) {
+        // Clear the flag
+        XHCI_REG_WR(regs, XHCI_PORT_PRC, 1);
+
+        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);
+        // TODO: Assign device slot (specification 4.3.2) 
+    }
+
+    // Connection status change
+    if(XHCI_REG_RD(regs, XHCI_PORT_CSC)) {
+        XHCI_REG_WR(regs, XHCI_PORT_CSC, 1);
+
+        if(XHCI_REG_RD(regs, XHCI_PORT_CCS) == 1) {
+            handle_connected_device(hc, regs, port_id);
+        }
+        else {
+            // Device disconnected
+        }
+    }
+    return EOK;
+}
+
+int xhci_get_hub_port(xhci_trb_t *trb) {
+    assert(trb);
+    uint8_t port_id = XHCI_QWORD_EXTRACT(trb->parameter, 63, 56);
+    return port_id;   
+}
+
+int xhci_reset_hub_port(xhci_hc_t* hc, uint8_t port) {
+    usb_log_debug2("Resetting port %u.", port);
+    xhci_port_regs_t regs = hc->op_regs->portrs[port];
+    XHCI_REG_WR(&regs, XHCI_PORT_PR, 1);
+    return EOK;
+}
+
Index: uspace/drv/bus/usb/xhci/rh.h
===================================================================
--- uspace/drv/bus/usb/xhci/rh.h	(revision 7bd99bfae7aabeabefaa09fab2ced431b9975c0d)
+++ uspace/drv/bus/usb/xhci/rh.h	(revision 7bd99bfae7aabeabefaa09fab2ced431b9975c0d)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 Michal Staruch
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbxhci
+ * @{
+ */
+/** @file
+ * @brief The roothub structures abstraction.
+ */
+
+#ifndef XHCI_RH_H
+#define XHCI_RH_H
+
+int xhci_handle_port_status_change_event(xhci_hc_t *, xhci_trb_t *);
+int xhci_get_hub_port(xhci_trb_t *);
+int xhci_reset_hub_port(xhci_hc_t *, uint8_t);
+
+#endif
