Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision fb154e13f03886faa39a7130005a9be6ac27e7dc)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision 0e7380fb7ecbcb4160f4599df7588d5b37a362f7)
@@ -387,7 +387,9 @@
 		return EOK;
 
-	/* TODO: Test this with USB3-aware BIOS */
+	if (xhci_reg_wait(&hc->op_regs->usbsts, XHCI_REG_MASK(XHCI_OP_CNR), 0))
+		return ETIMEOUT;
+
 	usb_log_debug2("LEGSUP: bios: %x, os: %x", hc->legsup->sem_bios, hc->legsup->sem_os);
-	XHCI_REG_WR(hc->legsup, XHCI_LEGSUP_SEM_OS, 1);
+	XHCI_REG_SET(hc->legsup, XHCI_LEGSUP_SEM_OS, 1);
 	for (int i = 0; i <= (XHCI_LEGSUP_BIOS_TIMEOUT_US / XHCI_LEGSUP_POLLING_DELAY_1MS); i++) {
 		usb_log_debug2("LEGSUP: elapsed: %i ms, bios: %x, os: %x", i,
@@ -395,6 +397,5 @@
 			XHCI_REG_RD(hc->legsup, XHCI_LEGSUP_SEM_OS));
 		if (XHCI_REG_RD(hc->legsup, XHCI_LEGSUP_SEM_BIOS) == 0) {
-			assert(XHCI_REG_RD(hc->legsup, XHCI_LEGSUP_SEM_OS) == 1);
-			return EOK;
+			return XHCI_REG_RD(hc->legsup, XHCI_LEGSUP_SEM_OS) == 1 ? EOK : EIO;
 		}
 		async_usleep(XHCI_LEGSUP_POLLING_DELAY_1MS);
@@ -410,10 +411,13 @@
 static int hc_reset(xhci_hc_t *hc)
 {
+	if (xhci_reg_wait(&hc->op_regs->usbsts, XHCI_REG_MASK(XHCI_OP_CNR), 0))
+		return ETIMEOUT;
+
 	/* Stop the HC: set R/S to 0 */
 	XHCI_REG_CLR(hc->op_regs, XHCI_OP_RS, 1);
 
-	/* Wait 16 ms until the HC is halted */
-	async_usleep(16000);
-	assert(XHCI_REG_RD(hc->op_regs, XHCI_OP_HCH));
+	/* Wait until the HC is halted - it shall take at most 16 ms */
+	if (xhci_reg_wait(&hc->op_regs->usbsts, XHCI_REG_MASK(XHCI_OP_HCH), XHCI_REG_MASK(XHCI_OP_HCH)))
+		return ETIMEOUT;
 
 	/* Reset */
@@ -421,6 +425,6 @@
 
 	/* Wait until the reset is complete */
-	while (XHCI_REG_RD(hc->op_regs, XHCI_OP_HCRST))
-		async_usleep(1000);
+	if (xhci_reg_wait(&hc->op_regs->usbcmd, XHCI_REG_MASK(XHCI_OP_HCRST), 0))
+		return ETIMEOUT;
 
 	return EOK;
@@ -437,7 +441,6 @@
 		return err;
 
-	// FIXME: Waiting forever.
-	while (XHCI_REG_RD(hc->op_regs, XHCI_OP_CNR))
-		async_usleep(1000);
+	if (xhci_reg_wait(&hc->op_regs->usbsts, XHCI_REG_MASK(XHCI_OP_CNR), 0))
+		return ETIMEOUT;
 
 	uint64_t dcbaaptr = hc->dcbaa_dma.phys;
Index: uspace/drv/bus/usb/xhci/hw_struct/common.h
===================================================================
--- uspace/drv/bus/usb/xhci/hw_struct/common.h	(revision fb154e13f03886faa39a7130005a9be6ac27e7dc)
+++ uspace/drv/bus/usb/xhci/hw_struct/common.h	(revision 0e7380fb7ecbcb4160f4599df7588d5b37a362f7)
@@ -42,6 +42,7 @@
 #include <assert.h>
 #include <bitops.h>
+#include <byteorder.h>
 #include <ddi.h>
-#include <byteorder.h>
+#include <errno.h>
 
 #define host2xhci(size, val) host2uint##size##_t_le((val))
@@ -88,4 +89,20 @@
 }
 
+static inline int xhci_reg_wait(xhci_dword_t *reg, uint32_t mask, uint32_t expected)
+{
+	mask = host2xhci(32, mask);
+	expected = host2xhci(32, expected);
+
+	unsigned retries = 100;
+	uint32_t value = *reg & mask;
+
+	for (; retries > 0 && value != expected; --retries) {
+		async_usleep(10000);
+		value = *reg & mask;
+	}
+
+	return value == expected ? EOK : ETIMEOUT;
+}
+
 #endif
 
