Index: uspace/drv/ohci/root_hub.c
===================================================================
--- uspace/drv/ohci/root_hub.c	(revision 9b78020f900914b95047e29225a3b98c5fbd31bb)
+++ uspace/drv/ohci/root_hub.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -217,4 +217,5 @@
 	instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
 	instance->unfinished_interrupt_transfer = NULL;
+	instance->interrupt_buffer = malloc((instance->port_count + 8)/8);
 	usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
 	return EOK;
@@ -471,7 +472,7 @@
 	size_t * buffer_size) {
 	int bit_count = instance->port_count + 1;
-	(*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1);
-
-	(*buffer) = malloc(*buffer_size);
+	(*buffer_size) = (bit_count+7 / 8);
+
+	(*buffer) = instance->interrupt_buffer;//malloc(*buffer_size);
 	uint8_t * bitmap = (uint8_t*) (*buffer);
 	uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16))
Index: uspace/drv/ohci/root_hub.h
===================================================================
--- uspace/drv/ohci/root_hub.h	(revision 9b78020f900914b95047e29225a3b98c5fbd31bb)
+++ uspace/drv/ohci/root_hub.h	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -56,4 +56,10 @@
 	/** interrupt transfer waiting for an actual interrupt to occur */
 	usb_transfer_batch_t * unfinished_interrupt_transfer;
+	/** pre-allocated interrupt mask
+	 *
+	 * This is allocated when initializing instance, so that memory
+	 * allocation is not needed when processing request.
+	 */
+	uint8_t * interrupt_buffer;
 } rh_t;
 
Index: uspace/drv/uhci-hcd/hc.c
===================================================================
--- uspace/drv/uhci-hcd/hc.c	(revision 9b78020f900914b95047e29225a3b98c5fbd31bb)
+++ uspace/drv/uhci-hcd/hc.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -44,20 +44,10 @@
 #include "hc.h"
 
-static irq_cmd_t uhci_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_16,
-		.addr = NULL, /* patched for every instance */
-		.dstarg = 1
-	},
-	{
-		.cmd = CMD_PIO_WRITE_16,
-		.addr = NULL, /* pathed for every instance */
-		.value = 0x1f
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-/*----------------------------------------------------------------------------*/
+#define UHCI_INTR_ALLOW_INTERRUPTS \
+    (UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET)
+#define UHCI_STATUS_USED_INTERRUPTS \
+    (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
+
+
 static int hc_init_transfer_lists(hc_t *instance);
 static int hc_init_mem_structures(hc_t *instance);
@@ -151,5 +141,5 @@
 		/* Enable all interrupts, but resume interrupt */
 		pio_write_16(&instance->registers->usbintr,
-		    UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
+		    UHCI_INTR_ALLOW_INTERRUPTS);
 	}
 
@@ -177,32 +167,46 @@
 {
 	assert(instance);
-#define CHECK_RET_DEST_CMDS_RETURN(ret, message...) \
+#define CHECK_RET_RETURN(ret, message...) \
 	if (ret != EOK) { \
 		usb_log_error(message); \
-		if (instance->interrupt_code.cmds != NULL) \
-			free(instance->interrupt_code.cmds); \
 		return ret; \
 	} else (void) 0
 
 	/* Init interrupt code */
-	instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds));
-	int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK;
-	CHECK_RET_DEST_CMDS_RETURN(ret,
-	    "Failed to allocate interrupt cmds space.\n");
-
+	instance->interrupt_code.cmds = instance->interrupt_commands;
 	{
-		irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds;
-		memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
-		interrupt_commands[0].addr =
-		    (void*)&instance->registers->usbsts;
-		interrupt_commands[1].addr =
-		    (void*)&instance->registers->usbsts;
-		instance->interrupt_code.cmdcount =
-		    sizeof(uhci_cmds) / sizeof(irq_cmd_t);
+		/* Read status register */
+		instance->interrupt_commands[0].cmd = CMD_PIO_READ_16;
+		instance->interrupt_commands[0].dstarg = 1;
+		instance->interrupt_commands[0].addr =
+		    &instance->registers->usbsts;
+
+		/* Test whether we are the interrupt cause */
+		instance->interrupt_commands[1].cmd = CMD_BTEST;
+		instance->interrupt_commands[1].value =
+		    UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_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_PIO_WRITE_A_16;
+		instance->interrupt_commands[3].srcarg = 1;
+		instance->interrupt_commands[3].addr =
+		    &instance->registers->usbsts;
+
+		/* Accept interrupt */
+		instance->interrupt_commands[4].cmd = CMD_ACCEPT;
+
+		instance->interrupt_code.cmdcount = UHCI_NEEDED_IRQ_COMMANDS;
 	}
 
 	/* Init transfer lists */
-	ret = hc_init_transfer_lists(instance);
-	CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n");
+	int ret = hc_init_transfer_lists(instance);
+	CHECK_RET_RETURN(ret, "Failed to init transfer lists.\n");
 	usb_log_debug("Initialized transfer lists.\n");
 
@@ -210,11 +214,10 @@
 	instance->frame_list = get_page();
 	ret = instance ? EOK : ENOMEM;
-	CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");
+	CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
 	usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
 
 	/* Set all frames to point to the first queue head */
-	const uint32_t queue =
-	    LINK_POINTER_QH(addr_to_phys(
-	        instance->transfers_interrupt.queue_head));
+	const uint32_t queue = LINK_POINTER_QH(
+	        addr_to_phys(instance->transfers_interrupt.queue_head));
 
 	unsigned i = 0;
@@ -229,8 +232,9 @@
 	ret = usb_endpoint_manager_init(&instance->ep_manager,
 	    BANDWIDTH_AVAILABLE_USB11);
-	assert(ret == EOK);
-
-	return EOK;
-#undef CHECK_RET_DEST_CMDS_RETURN
+	CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
+	    str_error(ret));
+
+	return EOK;
+#undef CHECK_RET_RETURN
 }
 /*----------------------------------------------------------------------------*/
@@ -277,5 +281,5 @@
 #ifdef FSBR
 	transfer_list_set_next(&instance->transfers_bulk_full,
-		&instance->transfers_control_full);
+	    &instance->transfers_control_full);
 #endif
 
@@ -330,5 +334,4 @@
 {
 	assert(instance);
-	status |= 1; //Uncomment to work around qemu hang
 	/* Lower 2 bits are transaction error and transaction complete */
 	if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
@@ -352,4 +355,7 @@
 	}
 	/* Resume interrupts are not supported */
+	if (status & UHCI_STATUS_RESUME) {
+		usb_log_error("Resume interrupt!\n");
+	}
 
 	/* Bits 4 and 5 indicate hc error */
@@ -380,13 +386,17 @@
 {
 	usb_log_debug("Started interrupt emulator.\n");
-	hc_t *instance = (hc_t*)arg;
+	hc_t *instance = arg;
 	assert(instance);
 
 	while (1) {
-		/* Readd and clear status register */
+		/* Read and clear status register */
 		uint16_t status = pio_read_16(&instance->registers->usbsts);
 		pio_write_16(&instance->registers->usbsts, status);
 		if (status != 0)
 			usb_log_debug2("UHCI status: %x.\n", status);
+// Qemu fails to report stalled communication
+// see https://bugs.launchpad.net/qemu/+bug/757654
+// This is a simple workaround to force queue processing every time
+	//	status |= 1;
 		hc_interrupt(instance, status);
 		async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
@@ -402,5 +412,5 @@
 int hc_debug_checker(void *arg)
 {
-	hc_t *instance = (hc_t*)arg;
+	hc_t *instance = arg;
 	assert(instance);
 
Index: uspace/drv/uhci-hcd/hc.h
===================================================================
--- uspace/drv/uhci-hcd/hc.h	(revision 9b78020f900914b95047e29225a3b98c5fbd31bb)
+++ uspace/drv/uhci-hcd/hc.h	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -69,4 +69,6 @@
 #define UHCI_STATUS_ERROR_INTERRUPT (1 << 1)
 #define UHCI_STATUS_INTERRUPT (1 << 0)
+#define UHCI_STATUS_NM_INTERRUPTS \
+    (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)
 
 	/** Interrupt enabled registers */
@@ -91,4 +93,5 @@
 #define UHCI_DEBUGER_TIMEOUT 5000000
 #define UHCI_ALLOWED_HW_FAIL 5
+#define UHCI_NEEDED_IRQ_COMMANDS 5
 
 /* Main HC driver structure */
@@ -119,4 +122,7 @@
 	/** Code to be executed in kernel interrupt handler */
 	irq_code_t interrupt_code;
+
+	/** Commands that form interrupt code */
+	irq_cmd_t interrupt_commands[UHCI_NEEDED_IRQ_COMMANDS];
 
 	/** Fibril periodically checking status register*/
Index: uspace/drv/uhci-hcd/pci.c
===================================================================
--- uspace/drv/uhci-hcd/pci.c	(revision 9b78020f900914b95047e29225a3b98c5fbd31bb)
+++ uspace/drv/uhci-hcd/pci.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -146,5 +146,5 @@
 	 * write all WC bits in USB legacy register */
 	sysarg_t address = 0xc0;
-	sysarg_t value = 0x8f00;
+	sysarg_t value = 0xaf00;
 
 	int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
Index: uspace/drv/uhci-hcd/uhci-hcd.ma
===================================================================
--- uspace/drv/uhci-hcd/uhci-hcd.ma	(revision 9b78020f900914b95047e29225a3b98c5fbd31bb)
+++ uspace/drv/uhci-hcd/uhci-hcd.ma	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -20,2 +20,6 @@
 10 pci/ven=8086&dev=2938
 10 pci/ven=8086&dev=2939
+
+10 pci/ven=8086&dev=24c2
+10 pci/ven=8086&dev=24c4
+10 pci/ven=8086&dev=24c7
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision 9b78020f900914b95047e29225a3b98c5fbd31bb)
+++ uspace/drv/usbhub/usbhub.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -105,5 +105,4 @@
 	}
 
-	//usb_pipe_start_session(hub_info->control_pipe);
 	//set hub configuration
 	opResult = usb_hub_set_configuration(hub_info);
@@ -122,6 +121,4 @@
 		return opResult;
 	}
-	//usb_pipe_end_session(hub_info->control_pipe);
-
 
 	usb_log_debug("Creating 'hub' function in DDF.\n");
@@ -176,5 +173,5 @@
 leave:
 	/* FIXME: proper interval. */
-	async_usleep(1000 * 1000 * 10);
+	async_usleep(1000 * 250);
 
 	return true;
@@ -218,5 +215,4 @@
 	// get hub descriptor
 	usb_log_debug("creating serialized descriptor\n");
-	//void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
 	uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE];
 	usb_hub_descriptor_t * descriptor;
@@ -253,20 +249,20 @@
 	    sizeof (usb_hub_port_t) * (hub_info->port_count + 1));
 	size_t port;
-	for (port = 0; port < hub_info->port_count + 1; port++) {
+	for (port = 0; port < hub_info->port_count + 1; ++port) {
 		usb_hub_port_init(&hub_info->ports[port]);
 	}
 	if(is_power_switched){
 		usb_log_debug("is_power_switched\n");
-		if(has_individual_port_powering){
-			usb_log_debug("has_individual_port_powering\n");
-			for (port = 0; port < hub_info->port_count; port++) {
-				opResult = usb_hub_set_port_feature(hub_info->control_pipe,
-				    port+1, USB_HUB_FEATURE_PORT_POWER);
-				if (opResult != EOK) {
-					usb_log_error("cannot power on port %zu: %s.\n",
-					    port+1, str_error(opResult));
-				}
+		
+		for (port = 1; port <= hub_info->port_count; ++port) {
+			usb_log_debug("powering port %d\n",port);
+			opResult = usb_hub_set_port_feature(hub_info->control_pipe,
+			    port, USB_HUB_FEATURE_PORT_POWER);
+			if (opResult != EOK) {
+				usb_log_error("cannot power on port %zu: %s.\n",
+				    port, str_error(opResult));
 			}
-		}else{
+		}
+		if(!has_individual_port_powering){
 			usb_log_debug("!has_individual_port_powering\n");
 			opResult = usb_hub_set_feature(hub_info->control_pipe,
@@ -281,6 +277,4 @@
 	}
 	usb_log_debug2("freeing data\n");
-	//free(serialized_descriptor);
-	//free(descriptor->devices_removable);
 	free(descriptor);
 	return EOK;
@@ -415,5 +409,5 @@
     usb_hub_status_t status) {
 	int opResult;
-	if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
+	if (!usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
 		//restart power on hub
 		opResult = usb_hub_set_feature(hub_info->control_pipe,
@@ -425,5 +419,5 @@
 	} else {//power reestablished on hub- restart ports
 		size_t port;
-		for (port = 0; port < hub_info->port_count; ++port) {
+		for (port = 1; port <= hub_info->port_count; ++port) {
 			opResult = usb_hub_set_port_feature(
 			    hub_info->control_pipe,
@@ -434,4 +428,11 @@
 			}
 		}
+		opResult = usb_hub_clear_feature(hub_info->control_pipe,
+		    USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
+		if (opResult != EOK) {
+			usb_log_error("cannnot clear hub power change flag: "
+			    "%d\n",
+			    opResult);
+		}
 	}
 	return opResult;
