Index: uspace/drv/bus/usb/usbhub/port.c
===================================================================
--- uspace/drv/bus/usb/usbhub/port.c	(revision babcc423363b75aff661f7e9c4810eb399a87a34)
+++ uspace/drv/bus/usb/usbhub/port.c	(revision 0f79283b7df80ab620570d6d06d69dc4e747cdac)
@@ -134,5 +134,5 @@
 	port_log(debug, port, "Port reset, enumerating device.");
 
-	if ((err = usbhc_device_enumerate(exch, port->port_number, port->base.speed))) {
+	if ((err = usbhc_device_enumerate(exch, port->port_number, port->speed))) {
 		port_log(error, port, "Failed to enumerate device: %s", str_error(err));
 		/* Disable the port */
@@ -200,7 +200,10 @@
 	const bool enabled = !!(status & USB_HUB_PORT_STATUS_ENABLED);
 
-	if (enabled)
-		usb_port_enabled(&port->base, usb_port_speed(status));
-	else
+	if (enabled) {
+		// The connecting fibril do not touch speed until the port is enabled,
+		// so we do not have to lock
+		port->speed = usb_port_speed(status);
+		usb_port_enabled(&port->base);
+	} else
 		usb_port_disabled(&port->base, &remove_device);
 }
Index: uspace/drv/bus/usb/usbhub/port.h
===================================================================
--- uspace/drv/bus/usb/usbhub/port.h	(revision babcc423363b75aff661f7e9c4810eb399a87a34)
+++ uspace/drv/bus/usb/usbhub/port.h	(revision 0f79283b7df80ab620570d6d06d69dc4e747cdac)
@@ -52,4 +52,6 @@
 	/** Port number as reported in descriptors. */
 	unsigned int port_number;
+	/** Speed at the time of enabling the port */
+	usb_speed_t speed;
 } usb_hub_port_t;
 
Index: uspace/drv/bus/usb/xhci/rh.c
===================================================================
--- uspace/drv/bus/usb/xhci/rh.c	(revision babcc423363b75aff661f7e9c4810eb399a87a34)
+++ uspace/drv/bus/usb/xhci/rh.c	(revision 0f79283b7df80ab620570d6d06d69dc4e747cdac)
@@ -136,5 +136,19 @@
 	}
 
-	device_t *dev = hcd_ddf_fun_create(&port->rh->hc->base, port->base.speed);
+	/*
+	 * We cannot know in advance, whether the speed in the status register
+	 * is valid - it depends on the protocol. So we read it later, but then
+	 * we have to check if the port is still enabled.
+	 */
+	uint32_t status = XHCI_REG_RD_FIELD(&port->regs->portsc, 32);
+
+	bool enabled = !!(status & XHCI_REG_MASK(XHCI_PORT_PED));
+	if (!enabled)
+		return ENOENT;
+
+	unsigned psiv = (status & XHCI_REG_MASK(XHCI_PORT_PS)) >> XHCI_REG_SHIFT(XHCI_PORT_PS);
+	const usb_speed_t speed = port->rh->hc->speeds[psiv].usb_speed;
+
+	device_t *dev = hcd_ddf_fun_create(&port->rh->hc->base, speed);
 	if (!dev) {
 		usb_log_error("Failed to create USB device function.");
@@ -223,7 +237,5 @@
 
 			if (enabled) {
-				unsigned psiv = (status & XHCI_REG_MASK(XHCI_PORT_PS)) >> XHCI_REG_SHIFT(XHCI_PORT_PS);
-				const usb_speed_t speed = rh->hc->speeds[psiv].usb_speed;
-				usb_port_enabled(&port->base, speed);
+				usb_port_enabled(&port->base);
 			} else {
 				usb_port_disabled(&port->base, &rh_remove_device);
Index: uspace/lib/usb/include/usb/port.h
===================================================================
--- uspace/lib/usb/include/usb/port.h	(revision babcc423363b75aff661f7e9c4810eb399a87a34)
+++ uspace/lib/usb/include/usb/port.h	(revision 0f79283b7df80ab620570d6d06d69dc4e747cdac)
@@ -41,6 +41,6 @@
  *
  * This subsystem abstracts the rather complicated state machine, and offers
- * a simple call interface to announce events, and a callback structure for
- * implementations to supply the hardware-dependent part.
+ * a simple interface to announce events and leave the fibril management on the
+ * library.
  */
 
@@ -65,6 +65,4 @@
 	/** Current state of the port */
 	usb_port_state_t state;
-	/** A speed of the device connected (if any). Valid unless state == PORT_DISABLED. */
-	usb_speed_t speed;
 	/** CV signalled on fibril exit. */
 	fibril_condvar_t finished_cv;
@@ -87,5 +85,5 @@
 void usb_port_init(usb_port_t *);
 int usb_port_connected(usb_port_t *, usb_port_enumerate_t);
-void usb_port_enabled(usb_port_t *, usb_speed_t);
+void usb_port_enabled(usb_port_t *);
 void usb_port_disabled(usb_port_t *, usb_port_remove_t);
 void usb_port_fini(usb_port_t *);
Index: uspace/lib/usb/src/port.c
===================================================================
--- uspace/lib/usb/src/port.c	(revision babcc423363b75aff661f7e9c4810eb399a87a34)
+++ uspace/lib/usb/src/port.c	(revision 0f79283b7df80ab620570d6d06d69dc4e747cdac)
@@ -41,6 +41,6 @@
  *
  * This subsystem abstracts the rather complicated state machine, and offers
- * a simple call interface to announce events, and a callback structure for
- * implementations to supply the hardware-dependent part.
+ * a simple interface to announce events and leave the fibril management on the
+ * library.
  */
 
@@ -127,10 +127,9 @@
 }
 
-void usb_port_enabled(usb_port_t *port, usb_speed_t speed)
-{
-	assert(port);
-
-	fibril_mutex_lock(&port->guard);
-	port->speed = speed;
+void usb_port_enabled(usb_port_t *port)
+{
+	assert(port);
+
+	fibril_mutex_lock(&port->guard);
 	fibril_condvar_broadcast(&port->enabled_cv);
 	fibril_mutex_unlock(&port->guard);
