Index: uspace/drv/vhc/hubops.c
===================================================================
--- uspace/drv/vhc/hubops.c	(revision 100962316f11f4d28cc4be7eaf39ac3705dc69ca)
+++ uspace/drv/vhc/hubops.c	(revision 5d4eb2dff8020193df5ee5b309ed8a3b5207400b)
@@ -59,4 +59,6 @@
 static int on_get_descriptor(struct usbvirt_device *dev,
     usb_device_request_setup_packet_t *request, uint8_t *data);
+static int on_set_configuration(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data);
 static int on_class_request(struct usbvirt_device *dev,
     usb_device_request_setup_packet_t *request, uint8_t *data);
@@ -64,4 +66,5 @@
     usb_endpoint_t endpoint,
     void *buffer, size_t size, size_t *actual_size);
+static void set_port_state(hub_port_t *, hub_port_state_t);
 
 /** Standard USB requests. */
@@ -74,5 +77,5 @@
 	.on_set_descriptor = NULL,
 	.on_get_configuration = NULL,
-	.on_set_configuration = NULL,
+	.on_set_configuration = on_set_configuration,
 	.on_get_interface = NULL,
 	.on_set_interface = NULL,
@@ -102,9 +105,68 @@
 }
 
+/** Callback for SET_CONFIGURATION request. */
+int on_set_configuration(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data)
+{
+	/* We must suspend power source to all ports. */
+	size_t i;
+	for (i = 0; i < HUB_PORT_COUNT; i++) {
+		hub_port_t *port = &hub_dev.ports[i];
+		
+		set_port_state(port, HUB_PORT_STATE_POWERED_OFF);
+	}
+	
+	/* Let the framework handle the rest of the job. */
+	return EFORWARD;
+}
+
+struct delay_port_state_change {
+	suseconds_t delay;
+	hub_port_state_t old_state;
+	hub_port_state_t new_state;
+	hub_port_t *port;
+};
+
+static int set_port_state_delayed_fibril(void *arg)
+{
+	struct delay_port_state_change *change
+	    = (struct delay_port_state_change *) arg;
+	
+	async_usleep(change->delay);
+	
+	if (change->port->state == change->old_state) {
+		set_port_state(change->port, change->new_state);
+	}
+	
+	free(change);
+	
+	return EOK;
+}
+
+static void set_port_state_delayed(hub_port_t *port,
+    suseconds_t delay_time,
+    hub_port_state_t old_state, hub_port_state_t new_state)
+{
+	struct delay_port_state_change *change
+	    = malloc(sizeof(struct delay_port_state_change));
+	change->port = port;
+	change->delay = delay_time;
+	change->old_state = old_state;
+	change->new_state = new_state;
+	fid_t fibril = fibril_create(set_port_state_delayed_fibril, change);
+	if (fibril == 0) {
+		printf("Failed to create fibril\n");
+		return;
+	}
+	fibril_add_ready(fibril);
+}
+
 /** Change port status and updates status change status fields.
  */
-static void set_port_state(hub_port_t *port, hub_port_state_t state)
-{
-	port->state = state;
+void set_port_state(hub_port_t *port, hub_port_state_t state)
+{
+	dprintf(1, "setting port %d state to %d (%c)", port->index,
+	    state, hub_port_state_as_char(state));
+	
 	if (state == HUB_PORT_STATE_POWERED_OFF) {
 		clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
@@ -113,16 +175,17 @@
 	}
 	if (state == HUB_PORT_STATE_RESUMING) {
-		async_usleep(10*1000);
-		if (port->state == state) {
-			set_port_state(port, HUB_PORT_STATE_ENABLED);
-		}
+		set_port_state_delayed(port, 10*1000,
+		    HUB_PORT_STATE_RESUMING, HUB_PORT_STATE_ENABLED);
 	}
 	if (state == HUB_PORT_STATE_RESETTING) {
-		async_usleep(10*1000);
-		if (port->state == state) {
-			set_port_status_change(port, HUB_STATUS_C_PORT_RESET);
-			set_port_state(port, HUB_PORT_STATE_ENABLED);
-		}
-	}
+		set_port_state_delayed(port, 10*1000,
+		    HUB_PORT_STATE_RESETTING, HUB_PORT_STATE_ENABLED);
+	}
+	if ((port->state == HUB_PORT_STATE_RESETTING)
+	    && (state == HUB_PORT_STATE_ENABLED)) {
+		set_port_status_change(port, HUB_STATUS_C_PORT_RESET);
+	}
+	
+	port->state = state;
 }
 
@@ -249,4 +312,6 @@
 	status |= (port->status_change << 16);
 	
+	dprintf(2, "GetPortStatus(port=%d, status=%u)\n", (int)portindex,
+	    (unsigned int) status);
 	return virthub_dev.control_transfer_reply(&virthub_dev, 0, &status, 4);
 }
@@ -291,5 +356,5 @@
     usb_device_request_setup_packet_t *request, uint8_t *data)
 {	
-	dprintf(2, "hub class request (%d)\n", (int) request->request);
+	dprintf(2, "hub class request (%d)", (int) request->request);
 	
 	uint8_t recipient = request->request_type & 31;
@@ -340,4 +405,6 @@
 			
 		default:
+			dprintf(0, "WARN: unknown request (%d)!\n",
+			    request->request);
 			break;
 	}
