Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 30e8ab4aca2907c8cfce26fe7f77013ae5083be8)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision 6210a33343b1115d76fd228ca78e85283b526ee6)
@@ -42,4 +42,5 @@
 #include <usb/usb.h>
 
+#include "macros.h"
 #include "hc.h"
 #include "ohci_endpoint.h"
@@ -87,20 +88,4 @@
 static int hc_init_memory(hc_t *instance);
 static int interrupt_emulator(hc_t *instance);
-
-/** Get number of PIO ranges used in IRQ code.
- * @return Number of ranges.
- */
-size_t hc_irq_pio_range_count(void)
-{
-	return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
-}
-
-/** Get number of commands used in IRQ code.
- * @return Number of commands.
- */
-size_t hc_irq_cmd_count(void)
-{
-	return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);
-}
 
 /** Generate IRQ code.
@@ -113,21 +98,31 @@
  * @return Error code.
  */
-int
-hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
-    size_t cmds_size, addr_range_t *regs)
-{
-	if ((ranges_size < sizeof(ohci_pio_ranges)) ||
-	    (cmds_size < sizeof(ohci_irq_commands)) ||
-	    (RNGSZ(*regs) < sizeof(ohci_regs_t)))
+int hc_gen_irq_code(irq_code_t *code, addr_range_t *regs)
+{
+	assert(code);
+	if (RNGSZ(*regs) < sizeof(ohci_regs_t))
 		return EOVERFLOW;
 
-	memcpy(ranges, ohci_pio_ranges, sizeof(ohci_pio_ranges));
-	ranges[0].base = RNGABS(*regs);
-
-	memcpy(cmds, ohci_irq_commands, sizeof(ohci_irq_commands));
+	code->ranges = malloc(sizeof(ohci_pio_ranges));
+	if (code->ranges == NULL)
+		return ENOMEM;
+
+	code->cmds = malloc(sizeof(ohci_irq_commands));
+	if (code->cmds == NULL) {
+		free(code->ranges);
+		return ENOMEM;
+	}
+
+	code->rangecount = ARRAY_SIZE(ohci_pio_ranges);
+	code->cmdcount = ARRAY_SIZE(ohci_irq_commands);
+
+	memcpy(code->ranges, ohci_pio_ranges, sizeof(ohci_pio_ranges));
+	code->ranges[0].base = RNGABS(*regs);
+
+	memcpy(code->cmds, ohci_irq_commands, sizeof(ohci_irq_commands));
 	ohci_regs_t *registers = (ohci_regs_t *) RNGABSPTR(*regs);
-	cmds[0].addr = (void *) &registers->interrupt_status;
-	cmds[3].addr = (void *) &registers->interrupt_status;
-	OHCI_WR(cmds[1].value, OHCI_USED_INTERRUPTS);
+	code->cmds[0].addr = (void *) &registers->interrupt_status;
+	code->cmds[3].addr = (void *) &registers->interrupt_status;
+	OHCI_WR(code->cmds[1].value, OHCI_USED_INTERRUPTS);
 
 	return EOK;
@@ -146,30 +141,21 @@
     interrupt_handler_t handler)
 {
-	int rc;
-
-	irq_pio_range_t irq_ranges[hc_irq_pio_range_count()];
-	irq_cmd_t irq_cmds[hc_irq_cmd_count()];
-
-	irq_code_t irq_code = {
-		.rangecount = hc_irq_pio_range_count(),
-		.ranges = irq_ranges,
-		.cmdcount = hc_irq_cmd_count(),
-		.cmds = irq_cmds
-	};
-
-	rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
-	    sizeof(irq_cmds), regs);
-	if (rc != EOK) {
+	irq_code_t irq_code = { 0 };
+
+	int ret = hc_gen_irq_code(&irq_code, regs);
+	if (ret != EOK) {
 		usb_log_error("Failed to generate IRQ code: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
+		    str_error(ret));
+		return ret;
+	}
+
+	//TODO we leak memory here
 
 	/* Register handler to avoid interrupt lockup */
-	rc = register_interrupt_handler(device, irq, handler, &irq_code);
-	if (rc != EOK) {
+	ret = register_interrupt_handler(device, irq, handler, &irq_code);
+	if (ret != EOK) {
 		usb_log_error("Failed to register interrupt handler: %s.\n",
-		    str_error(rc));
-		return rc;
+		    str_error(ret));
+		return ret;
 	}
 
Index: uspace/drv/bus/usb/ohci/hc.h
===================================================================
--- uspace/drv/bus/usb/ohci/hc.h	(revision 30e8ab4aca2907c8cfce26fe7f77013ae5083be8)
+++ uspace/drv/bus/usb/ohci/hc.h	(revision 6210a33343b1115d76fd228ca78e85283b526ee6)
@@ -72,8 +72,5 @@
 } hc_t;
 
-size_t hc_irq_pio_range_count(void);
-size_t hc_irq_cmd_count(void);
-int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t,
-    addr_range_t *);
+int hc_gen_irq_code(irq_code_t *code, addr_range_t *regs);
 int hc_register_irq_handler(ddf_dev_t *, addr_range_t *, int,
     interrupt_handler_t);
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision 30e8ab4aca2907c8cfce26fe7f77013ae5083be8)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision 6210a33343b1115d76fd228ca78e85283b526ee6)
@@ -90,45 +90,37 @@
 
 
-/** Get number of PIO ranges used in IRQ code.
- * @return Number of ranges.
- */
-size_t hc_irq_pio_range_count(void)
-{
-	return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t);
-}
-
-/** Get number of commands used in IRQ code.
- * @return Number of commands.
- */
-size_t hc_irq_cmd_count(void)
-{
-	return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t);
-}
-
 /** Generate IRQ code.
- * @param[out] ranges PIO ranges buffer.
- * @param[in] ranges_size Size of the ranges buffer (bytes).
- * @param[out] cmds Commands buffer.
- * @param[in] cmds_size Size of the commands buffer (bytes).
+ * @param[out] code IRQ code structure.
  * @param[in] regs Device's register range.
  *
  * @return Error code.
  */
-int
-hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
-    size_t cmds_size, addr_range_t *regs)
-{
-	if ((ranges_size < sizeof(uhci_irq_pio_ranges)) ||
-	    (cmds_size < sizeof(uhci_irq_commands)) ||
-	    (RNGSZ(*regs) < sizeof(uhci_regs_t)))
+int hc_gen_irq_code(irq_code_t *code, addr_range_t *regs)
+{
+	assert(code);
+
+	if (RNGSZ(*regs) < sizeof(uhci_regs_t))
 		return EOVERFLOW;
 
-	memcpy(ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges));
-	ranges[0].base = RNGABS(*regs);
-
-	memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands));
+	code->ranges = malloc(sizeof(uhci_irq_pio_ranges));
+	if (code->ranges == NULL)
+		return ENOMEM;
+
+	code->cmds = malloc(sizeof(uhci_irq_commands));
+	if (code->cmds == NULL) {
+		free(code->ranges);
+		return ENOMEM;
+	}
+
+	code->rangecount = ARRAY_SIZE(uhci_irq_pio_ranges);
+	code->cmdcount = ARRAY_SIZE(uhci_irq_commands);
+
+	memcpy(code->ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges));
+	code->ranges[0].base = RNGABS(*regs);
+
+	memcpy(code->cmds, uhci_irq_commands, sizeof(uhci_irq_commands));
 	uhci_regs_t *registers = (uhci_regs_t *) RNGABSPTR(*regs);
-	cmds[0].addr = (void*)&registers->usbsts;
-	cmds[3].addr = (void*)&registers->usbsts;
+	code->cmds[0].addr = (void*)&registers->usbsts;
+	code->cmds[3].addr = (void*)&registers->usbsts;
 
 	return EOK;
@@ -148,9 +140,8 @@
 {
 	assert(device);
-	irq_pio_range_t irq_ranges[hc_irq_pio_range_count()];
-	irq_cmd_t irq_cmds[hc_irq_cmd_count()];
-
-	int ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
-	    sizeof(irq_cmds), regs);
+
+	irq_code_t irq_code = { 0 };
+
+	int ret = hc_gen_irq_code(&irq_code, regs);
 	if (ret != EOK) {
 		usb_log_error("Failed to generate IRQ commands: %s.\n",
@@ -158,11 +149,5 @@
 		return ret;
 	}
-
-	irq_code_t irq_code = {
-		.rangecount = hc_irq_pio_range_count(),
-		.ranges = irq_ranges,
-		.cmdcount = hc_irq_cmd_count(),
-		.cmds = irq_cmds
-	};
+	//TODO we leak memory here
 
         /* Register handler to avoid interrupt lockup */
Index: uspace/drv/bus/usb/uhci/hc.h
===================================================================
--- uspace/drv/bus/usb/uhci/hc.h	(revision 30e8ab4aca2907c8cfce26fe7f77013ae5083be8)
+++ uspace/drv/bus/usb/uhci/hc.h	(revision 6210a33343b1115d76fd228ca78e85283b526ee6)
@@ -124,10 +124,7 @@
 } hc_t;
 
-size_t hc_irq_pio_range_count(void);
-size_t hc_irq_cmd_count(void);
 int hc_register_irq_handler(ddf_dev_t *, addr_range_t *, int,
     interrupt_handler_t);
-int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t,
-    addr_range_t *);
+int hc_gen_irq_code(irq_code_t *code, addr_range_t *regs);
 void hc_interrupt(hc_t *instance, uint16_t status);
 int hc_init(hc_t *instance, addr_range_t *regs, bool interupts);
