Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 026793d93499d089b36163093b5ef05e10ac1f12)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision 1ecc5de1d337ceff079d76dbbb6c1ce44a6dcc3c)
@@ -46,4 +46,14 @@
 #define OHCI_USED_INTERRUPTS \
     (I_SO | I_WDH | I_UE | I_RHSC)
+
+static const irq_cmd_t ohci_irq_commands[] =
+{
+	{ .cmd = CMD_MEM_READ_32, .dstarg = 1, .addr = NULL /*filled later*/ },
+	{ .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = OHCI_USED_INTERRUPTS },
+	{ .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 },
+	{ .cmd = CMD_MEM_WRITE_A_32, .srcarg = 1, .addr = NULL /*filled later*/ },
+	{ .cmd = CMD_ACCEPT },
+};
+
 static int interrupt_emulator(hc_t *instance);
 static void hc_gain_control(hc_t *instance);
@@ -150,5 +160,36 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Create end register endpoint structures
+size_t hc_irq_cmd_count(void)
+{
+	return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);
+}
+/*----------------------------------------------------------------------------*/
+int hc_get_irq_commands(
+    irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size)
+{
+	if (cmd_size < sizeof(ohci_irq_commands)
+	    || reg_size < sizeof(ohci_regs_t))
+		return EOVERFLOW;
+
+	/* Create register mapping to use in IRQ handler
+	 * this mapping should be present in kernel only.
+	 * Remove it from here when kernel knows how to create mappings
+	 * and accepts physical addresses in IRQ code.
+	 * TODO: remove */
+	void *registers;
+	const int ret = pio_enable((void*)regs, reg_size, &registers);
+
+	if (ret != EOK)
+		return ret;
+
+	memcpy(cmds, ohci_irq_commands, sizeof(ohci_irq_commands));
+
+	void *address = (void*)&(((ohci_regs_t*)registers)->interrupt_status);
+	cmds[0].addr = address;
+	cmds[3].addr = address;
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Create and register endpoint structures
  *
  * @param[in] instance OHCI driver structure.
@@ -621,4 +662,5 @@
 	return EOK;
 }
+
 /**
  * @}
Index: uspace/drv/bus/usb/ohci/hc.h
===================================================================
--- uspace/drv/bus/usb/ohci/hc.h	(revision 026793d93499d089b36163093b5ef05e10ac1f12)
+++ uspace/drv/bus/usb/ohci/hc.h	(revision 1ecc5de1d337ceff079d76dbbb6c1ce44a6dcc3c)
@@ -86,7 +86,10 @@
 } hc_t;
 
-int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
+size_t hc_irq_cmd_count(void);
+int hc_get_irq_commands(
+    irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
 void hc_start_hw(hc_t *instance);
+int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
 
 /** Safely dispose host controller internal structures
Index: uspace/drv/bus/usb/ohci/ohci.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci.c	(revision 026793d93499d089b36163093b5ef05e10ac1f12)
+++ uspace/drv/bus/usb/ohci/ohci.c	(revision 1ecc5de1d337ceff079d76dbbb6c1ce44a6dcc3c)
@@ -58,8 +58,6 @@
 {
 	assert(dev);
-	assert(dev->driver_data);
 	return dev->driver_data;
 }
-
 /** IRQ handling callback, identifies device
  *
@@ -71,5 +69,8 @@
 {
 	hc_t *hc = &dev_to_ohci(dev)->hc;
-	assert(hc);
+	if (!hc) {
+		usb_log_warning("IRQ on device that is not ready.\n");
+		return;
+	}
 	const uint16_t status = IPC_GET_ARG1(*call);
 	hc_interrupt(hc, status);
