Index: kernel/generic/include/ddi/irq.h
===================================================================
--- kernel/generic/include/ddi/irq.h	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ kernel/generic/include/ddi/irq.h	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -77,5 +77,26 @@
 	 */
 	CMD_PIO_WRITE_A_32,
-	
+
+	/** Read 1 byte from the memory space. */
+	CMD_MEM_READ_8,
+	/** Read 2 bytes from the memory space. */
+	CMD_MEM_READ_16,
+	/** Read 4 bytes from the memory space. */
+	CMD_MEM_READ_32,
+
+	/** Write 1 byte to the memory space. */
+	CMD_MEM_WRITE_8,
+	/** Write 2 bytes to the memory space. */
+	CMD_MEM_WRITE_16,
+	/** Write 4 bytes to the memory space. */
+	CMD_MEM_WRITE_32,
+
+	/** Write 1 byte from the source argument to the memory space. */
+	CMD_MEM_WRITE_A_8,
+	/** Write 2 bytes from the source argument to the memory space. */
+	CMD_MEM_WRITE_A_16,
+	/** Write 4 bytes from the source argument to the memory space. */
+	CMD_MEM_WRITE_A_32,
+
 	/**
 	 * Perform a bit masking on the source argument
@@ -203,4 +224,6 @@
 	/** Notification configuration structure. */
 	ipc_notif_cfg_t notif_cfg; 
+
+	as_t *driver_as;
 } irq_t;
 
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ kernel/generic/src/ipc/irq.c	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -174,4 +174,5 @@
 	irq->notif_cfg.code = code;
 	irq->notif_cfg.counter = 0;
+	irq->driver_as = AS;
 	
 	/*
@@ -364,4 +365,25 @@
 		return IRQ_DECLINE;
 	
+#define CMD_MEM_READ(target) \
+do { \
+	void *va = code->cmds[i].addr; \
+	if (AS != irq->driver_as) \
+		as_switch(AS, irq->driver_as); \
+	printf("Copying data from address: %p.\n", va); \
+	memcpy_from_uspace(&target, va, (sizeof(target))); \
+	if (dstarg) \
+		scratch[dstarg] = target; \
+} while(0)
+
+#define CMD_MEM_WRITE(val) \
+do { \
+	void *va = code->cmds[i].addr; \
+	if (AS != irq->driver_as) \
+		as_switch(AS, irq->driver_as); \
+	printf("Writing data to address: %p.\n", va); \
+	memcpy_to_uspace(va, &val, sizeof(val)); \
+} while (0)
+
+	as_t *current_as = AS;
 	size_t i;
 	for (i = 0; i < code->cmdcount; i++) {
@@ -422,4 +444,53 @@
 			}
 			break;
+		case CMD_MEM_READ_8: {
+			uint8_t val;
+			CMD_MEM_READ(val);
+			break;
+			}
+		case CMD_MEM_READ_16: {
+			uint16_t val;
+			CMD_MEM_READ(val);
+			break;
+			}
+		case CMD_MEM_READ_32: {
+			uint32_t val;
+			CMD_MEM_READ(val);
+			printf("mem READ value: %x.\n", val);
+			break;
+			}
+		case CMD_MEM_WRITE_8: {
+			uint8_t val = code->cmds[i].value;
+			CMD_MEM_WRITE(val);
+			break;
+			}
+		case CMD_MEM_WRITE_16: {
+			uint16_t val = code->cmds[i].value;
+			CMD_MEM_WRITE(val);
+			break;
+			}
+		case CMD_MEM_WRITE_32: {
+			uint32_t val = code->cmds[i].value;
+			CMD_MEM_WRITE(val);
+			break;
+			}
+		case CMD_MEM_WRITE_A_8:
+			if (srcarg) {
+				uint8_t val = scratch[srcarg];
+				CMD_MEM_WRITE(val);
+			}
+			break;
+		case CMD_MEM_WRITE_A_16:
+			if (srcarg) {
+				uint16_t val = scratch[srcarg];
+				CMD_MEM_WRITE(val);
+			}
+			break;
+		case CMD_MEM_WRITE_A_32:
+			if (srcarg) {
+				uint32_t val = scratch[srcarg];
+				CMD_MEM_WRITE(val);
+			}
+			break;
 		case CMD_BTEST:
 			if ((srcarg) && (dstarg)) {
@@ -435,10 +506,16 @@
 			break;
 		case CMD_ACCEPT:
+			if (AS != current_as)
+				as_switch(AS, current_as);
 			return IRQ_ACCEPT;
 		case CMD_DECLINE:
 		default:
+			if (AS != current_as)
+				as_switch(AS, current_as);
 			return IRQ_DECLINE;
 		}
 	}
+	if (AS != current_as)
+		as_switch(AS, current_as);
 	
 	return IRQ_DECLINE;
Index: uspace/drv/ehci-hcd/pci.c
===================================================================
--- uspace/drv/ehci-hcd/pci.c	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ uspace/drv/ehci-hcd/pci.c	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -186,5 +186,6 @@
 	CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read PCI config space.\n",
 	    ret);
-	usb_log_info("Register space BAR at %p:%" PRIxn ".\n", (void *) address, value);
+	usb_log_info("Register space BAR at %p:%" PRIxn ".\n",
+	    (void *) address, value);
 
 	/* clear lower byte, it's not part of the BASE address */
Index: uspace/drv/ohci/hc.c
===================================================================
--- uspace/drv/ohci/hc.c	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ uspace/drv/ohci/hc.c	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -45,4 +45,6 @@
 #include "hcd_endpoint.h"
 
+#define OHCI_USED_INTERRUPTS \
+    (I_SO | I_WDH | I_UE | I_RHSC)
 static int interrupt_emulator(hc_t *instance);
 static void hc_gain_control(hc_t *instance);
@@ -285,12 +287,12 @@
 {
 	assert(instance);
-	if ((status & ~IS_SF) == 0) /* ignore sof status */
+	usb_log_debug("OHCI interrupt: %x.\n", status);
+	if ((status & ~I_SF) == 0) /* ignore sof status */
 		return;
-	if (status & IS_RHSC)
+	if (status & I_RHSC)
 		rh_interrupt(&instance->rh);
 
-	usb_log_debug("OHCI interrupt: %x.\n", status);
-
-	if (status & IS_WDH) {
+
+	if (status & I_WDH) {
 		fibril_mutex_lock(&instance->guard);
 		usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca,
@@ -421,11 +423,9 @@
 	    instance->registers->control);
 
-	/* Disable interrupts */
-	instance->registers->interrupt_disable = I_SF | I_OC;
-	usb_log_debug2("Disabling interrupts: %x.\n",
-	    instance->registers->interrupt_disable);
-	instance->registers->interrupt_disable = I_MI;
+	/* Enable interrupts */
+	instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS;
 	usb_log_debug2("Enabled interrupts: %x.\n",
 	    instance->registers->interrupt_enable);
+	instance->registers->interrupt_enable = I_MI;
 
 	/* Set periodic start to 90% */
@@ -492,4 +492,37 @@
 	    instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
 
+	/* Init interrupt code */
+	instance->interrupt_code.cmds = instance->interrupt_commands;
+	{
+		/* Read status register */
+		instance->interrupt_commands[0].cmd = CMD_MEM_READ_32;
+		instance->interrupt_commands[0].dstarg = 1;
+		instance->interrupt_commands[0].addr =
+		    (void*)&instance->registers->interrupt_status;
+
+		/* Test whether we are the interrupt cause */
+		instance->interrupt_commands[1].cmd = CMD_BTEST;
+		instance->interrupt_commands[1].value =
+		    OHCI_USED_INTERRUPTS;
+		instance->interrupt_commands[1].srcarg = 1;
+		instance->interrupt_commands[1].dstarg = 2;
+
+		/* Predicate cleaning and accepting */
+		instance->interrupt_commands[2].cmd = CMD_PREDICATE;
+		instance->interrupt_commands[2].value = 2;
+		instance->interrupt_commands[2].srcarg = 2;
+
+		/* Write clean status register */
+		instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32;
+		instance->interrupt_commands[3].srcarg = 1;
+		instance->interrupt_commands[3].addr =
+		    (void*)&instance->registers->interrupt_status;
+
+		/* Accept interrupt */
+		instance->interrupt_commands[4].cmd = CMD_ACCEPT;
+
+		instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
+	}
+
 	return EOK;
 }
Index: uspace/drv/ohci/hc.h
===================================================================
--- uspace/drv/ohci/hc.h	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ uspace/drv/ohci/hc.h	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -51,4 +51,6 @@
 #include "hw_struct/hcca.h"
 
+#define OHCI_NEEDED_IRQ_COMMANDS 5
+
 typedef struct hc {
 	ohci_regs_t *registers;
@@ -65,4 +67,10 @@
 	fid_t interrupt_emulator;
 	fibril_mutex_t guard;
+
+	/** Code to be executed in kernel interrupt handler */
+	irq_code_t interrupt_code;
+
+	/** Commands that form interrupt code */
+	irq_cmd_t interrupt_commands[OHCI_NEEDED_IRQ_COMMANDS];
 } hc_t;
 
Index: uspace/drv/ohci/ohci.c
===================================================================
--- uspace/drv/ohci/ohci.c	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ uspace/drv/ohci/ohci.c	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -202,5 +202,6 @@
 
 	/* It does no harm if we register this on polling */
-	ret = register_interrupt_handler(device, irq, irq_handler, NULL);
+	ret = register_interrupt_handler(device, irq, irq_handler,
+	    &instance->hc.interrupt_code);
 	CHECK_RET_FINI_RETURN(ret,
 	    "Failed(%d) to register interrupt handler.\n", ret);
Index: uspace/drv/ohci/ohci_regs.h
===================================================================
--- uspace/drv/ohci/ohci_regs.h	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ uspace/drv/ohci/ohci_regs.h	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -72,16 +72,9 @@
 #define CS_SOC_SHIFT (16)
 
+	/** Interupt enable/disable/status,
+	 * reads give the same value,
+	 * writing causes enable/disable,
+	 * status is write-clean (writing 1 clears the bit*/
 	volatile uint32_t interrupt_status;
-#define IS_SO   (1 << 0)  /* Scheduling overrun */
-#define IS_WDH  (1 << 1)  /* Write-back done head */
-#define IS_SF   (1 << 2)  /* Start of frame */
-#define IS_RD   (1 << 3)  /* Resume detected */
-#define IS_UE   (1 << 4)  /* Unrecoverable error */
-#define IS_FNO  (1 << 5)  /* Frame number overflow */
-#define IS_RHSC (1 << 6)  /* Root hub status change */
-#define IS_OC   (1 << 30) /* Ownership change */
-
-	/** Interupt enable/disable, reads give the same value, writing causes
-	 * enable/disable */
 	volatile uint32_t interrupt_enable;
 	volatile uint32_t interrupt_disable;
Index: uspace/drv/ohci/pci.c
===================================================================
--- uspace/drv/ohci/pci.c	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ uspace/drv/ohci/pci.c	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -146,5 +146,4 @@
 int pci_enable_interrupts(ddf_dev_t *device)
 {
-	return ENOTSUP;
 	int parent_phone =
 	    devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
Index: uspace/lib/usb/src/host/batch.c
===================================================================
--- uspace/lib/usb/src/host/batch.c	(revision 310c4df529c9952b47aac9b498fcf8e46e2ba15d)
+++ uspace/lib/usb/src/host/batch.c	(revision 075c1eb6b65db833403311b1521d009b0e4265bf)
@@ -128,9 +128,10 @@
 	memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);
 
-	usb_log_debug("Batch %p done (T%d.%d, %s %s in, %zuB): %s (%d).\n",
+	usb_log_debug("Batch(%p) done (T%d.%d, %s %s in, %zuB): %s (%d).\n",
 	    instance, instance->ep->address, instance->ep->endpoint,
 	    usb_str_speed(instance->ep->speed),
 	    usb_str_transfer_type_short(instance->ep->transfer_type),
-	    instance->transfered_size, str_error(instance->error), instance->error);
+	    instance->transfered_size, str_error(instance->error),
+	    instance->error);
 
 	instance->callback_in(instance->fun, instance->error,
@@ -147,5 +148,5 @@
 	assert(instance->callback_out);
 
-	usb_log_debug("Batch %p done (T%d.%d, %s %s out): %s (%d).\n",
+	usb_log_debug("Batch(%p) done (T%d.%d, %s %s out): %s (%d).\n",
 	    instance, instance->ep->address, instance->ep->endpoint,
 	    usb_str_speed(instance->ep->speed),
