Index: uspace/drv/bus/usb/xhci/commands.c
===================================================================
--- uspace/drv/bus/usb/xhci/commands.c	(revision 60f7c590bbc1ec04360ad92a8caca24d962ef986)
+++ uspace/drv/bus/usb/xhci/commands.c	(revision 3dc519fae143b4a3212bd24ad85ee5cc268678df)
@@ -155,4 +155,34 @@
 
 	return cmd;
+}
+
+void xhci_stop_command_ring(xhci_hc_t *hc)
+{
+	assert(hc);
+
+	XHCI_REG_SET(hc->op_regs, XHCI_OP_CS, 1);
+
+	/**
+	 * Note: There is a bug in qemu that checks CS only when CRCR_HI
+	 *       is written, this (and the read/write in abort) ensures
+	 *       the command rings stops.
+	 */
+	XHCI_REG_WR(hc->op_regs, XHCI_OP_CRCR_HI, XHCI_REG_RD(hc->op_regs, XHCI_OP_CRCR_HI));
+}
+
+void xhci_abort_command_ring(xhci_hc_t *hc)
+{
+	assert(hc);
+
+	XHCI_REG_WR(hc->op_regs, XHCI_OP_CA, 1);
+	XHCI_REG_WR(hc->op_regs, XHCI_OP_CRCR_HI, XHCI_REG_RD(hc->op_regs, XHCI_OP_CRCR_HI));
+}
+
+void xhci_start_command_ring(xhci_hc_t *hc)
+{
+	assert(hc);
+
+	XHCI_REG_WR(hc->op_regs, XHCI_OP_CRR, 1);
+	ring_doorbell(hc, 0, 0);
 }
 
@@ -390,4 +420,6 @@
 	assert(trb);
 
+	// TODO: STOP & ABORT may not have command structs in the list!
+
 	usb_log_debug("HC(%p) Command completed.", hc);
 
Index: uspace/drv/bus/usb/xhci/commands.h
===================================================================
--- uspace/drv/bus/usb/xhci/commands.h	(revision 60f7c590bbc1ec04360ad92a8caca24d962ef986)
+++ uspace/drv/bus/usb/xhci/commands.h	(revision 3dc519fae143b4a3212bd24ad85ee5cc268678df)
@@ -62,4 +62,8 @@
 void xhci_free_command(xhci_cmd_t *);
 
+void xhci_stop_command_ring(xhci_hc_t *);
+void xhci_abort_command_ring(xhci_hc_t *);
+void xhci_start_command_ring(xhci_hc_t *);
+
 int xhci_send_no_op_command(xhci_hc_t *, xhci_cmd_t *);
 int xhci_send_enable_slot_command(xhci_hc_t *, xhci_cmd_t *);
