Index: uspace/drv/vhc/hub/virthubops.c
===================================================================
--- uspace/drv/vhc/hub/virthubops.c	(revision bd8c753d552e6b0ff878d0bbc41a00ff515f345c)
+++ uspace/drv/vhc/hub/virthubops.c	(revision 3d4aa05551843bc5de66e78e0dd0dbc2c4a21801)
@@ -35,9 +35,10 @@
 #include <errno.h>
 #include <usb/classes/hub.h>
+#include <usbvirt/device.h>
 #include "virthub.h"
 #include "hub.h"
 
 /** Callback when device changes states. */
-static void on_state_change(struct usbvirt_device *dev,
+static void on_state_change(usbvirt_device_t *dev,
     usbvirt_device_state_t old_state, usbvirt_device_state_t new_state)
 {
@@ -61,24 +62,38 @@
 
 /** Callback for data request. */
-static int req_on_data(struct usbvirt_device *dev,
-    usb_endpoint_t endpoint,
-    void *buffer, size_t size, size_t *actual_size)
+static int req_on_status_change_pipe(usbvirt_device_t *dev,
+    usb_endpoint_t endpoint, usb_transfer_type_t tr_type,
+    void *buffer, size_t buffer_size, size_t *actual_size)
 {
 	if (endpoint != HUB_STATUS_CHANGE_PIPE) {
-		return EINVAL;
+		return ESTALL;
+	}
+	if (tr_type != USB_TRANSFER_INTERRUPT) {
+		return ESTALL;
 	}
 	
-	hub_t *hub = (hub_t *)dev->device_data;
+	hub_t *hub = dev->device_data;
 
 	hub_acquire(hub);
 
+	if (!hub->signal_changes) {
+		hub_release(hub);
+
+		return ENAK;
+	}
+
+
 	uint8_t change_map = hub_get_status_change_bitmap(hub);
-		
+
 	uint8_t *b = (uint8_t *) buffer;
-	if (size > 0) {
+	if (buffer_size > 0) {
 		*b = change_map;
 		*actual_size = 1;
+	} else {
+		*actual_size = 0;
 	}
 	
+	hub->signal_changes = false;
+
 	hub_release(hub);
 
@@ -94,6 +109,6 @@
  */
 static int req_clear_hub_feature(usbvirt_device_t *dev,
-    usb_device_request_setup_packet_t *request,
-    uint8_t *data)
+    const usb_device_request_setup_packet_t *request, uint8_t *data,
+    size_t *act_size)
 {
 	return ENOTSUP;
@@ -108,6 +123,6 @@
  */
 static int req_clear_port_feature(usbvirt_device_t *dev,
-    usb_device_request_setup_packet_t *request,
-    uint8_t *data)
+    const usb_device_request_setup_packet_t *request, uint8_t *data,
+    size_t *act_size)
 {
 	int rc;
@@ -188,6 +203,6 @@
  */
 static int req_get_bus_state(usbvirt_device_t *dev,
-    usb_device_request_setup_packet_t *request,
-    uint8_t *data)
+    const usb_device_request_setup_packet_t *request, uint8_t *data,
+    size_t *act_size)
 {
 	return ENOTSUP;
@@ -202,12 +217,12 @@
  */
 static int req_get_descriptor(usbvirt_device_t *dev,
-    usb_device_request_setup_packet_t *request,
-    uint8_t *data)
+    const usb_device_request_setup_packet_t *request, uint8_t *data,
+    size_t *act_size)
 {
 	if (request->value_high == USB_DESCTYPE_HUB) {
-		int rc = dev->control_transfer_reply(dev, 0,
+		usbvirt_control_reply_helper(request, data, act_size,
 		    &hub_descriptor, hub_descriptor.length);
 
-		return rc;
+		return EOK;
 	}
 	/* Let the framework handle all the rest. */
@@ -223,11 +238,13 @@
  */
 static int req_get_hub_status(usbvirt_device_t *dev,
-    usb_device_request_setup_packet_t *request,
-    uint8_t *data)
+    const usb_device_request_setup_packet_t *request, uint8_t *data,
+    size_t *act_size)
 {
 	uint32_t hub_status = 0;
 
-	return dev->control_transfer_reply(dev, 0,
+	usbvirt_control_reply_helper(request, data, act_size,
 	    &hub_status, sizeof(hub_status));
+
+	return EOK;
 }
 
@@ -240,6 +257,6 @@
  */
 static int req_get_port_status(usbvirt_device_t *dev,
-    usb_device_request_setup_packet_t *request,
-    uint8_t *data)
+    const usb_device_request_setup_packet_t *request, uint8_t *data,
+    size_t *act_size)
 {
 	hub_t *hub = (hub_t *) dev->device_data;
@@ -251,5 +268,8 @@
 	hub_release(hub);
 
-	return dev->control_transfer_reply(dev, 0, &status, 4);
+	usbvirt_control_reply_helper(request, data, act_size,
+	    &status, sizeof(status));
+
+	return EOK;
 }
 
@@ -262,6 +282,6 @@
  */
 static int req_set_hub_feature(usbvirt_device_t *dev,
-    usb_device_request_setup_packet_t *request,
-    uint8_t *data)
+    const usb_device_request_setup_packet_t *request, uint8_t *data,
+    size_t *act_size)
 {
 	return ENOTSUP;
@@ -276,6 +296,6 @@
  */
 static int req_set_port_feature(usbvirt_device_t *dev,
-    usb_device_request_setup_packet_t *request,
-    uint8_t *data)
+    const usb_device_request_setup_packet_t *request, uint8_t *data,
+    size_t *act_size)
 {
 	int rc;
@@ -330,7 +350,7 @@
 
 /** Recipient: other. */
-#define REC_OTHER USBVIRT_REQUEST_RECIPIENT_OTHER
+#define REC_OTHER USB_REQUEST_RECIPIENT_OTHER
 /** Recipient: device. */
-#define REC_DEVICE USBVIRT_REQUEST_RECIPIENT_DEVICE
+#define REC_DEVICE USB_REQUEST_RECIPIENT_DEVICE
 /** Direction: in. */
 #define DIR_IN USB_DIRECTION_IN
@@ -338,4 +358,5 @@
 #define DIR_OUT USB_DIRECTION_OUT
 
+
 /** Create a class request.
  *
@@ -345,6 +366,7 @@
  */
 #define CLASS_REQ(direction, recipient, req) \
-	.request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \
-	    USBVIRT_REQUEST_TYPE_CLASS, recipient), \
+	.req_direction = direction, \
+	.req_recipient = recipient, \
+	.req_type = USB_REQUEST_TYPE_CLASS, \
 	.request = req
 
@@ -356,10 +378,11 @@
  */
 #define STD_REQ(direction, recipient, req) \
-	.request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \
-	    USBVIRT_REQUEST_TYPE_STANDARD, recipient), \
+	.req_direction = direction, \
+	.req_recipient = recipient, \
+	.req_type = USB_REQUEST_TYPE_STANDARD, \
 	.request = req
 
 /** Hub operations on control endpoint zero. */
-static usbvirt_control_transfer_handler_t endpoint_zero_handlers[] = {
+static usbvirt_control_request_handler_t endpoint_zero_handlers[] = {
 	{
 		STD_REQ(DIR_IN, REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
@@ -417,5 +440,7 @@
 		.callback = req_set_port_feature
 	},
-	USBVIRT_CONTROL_TRANSFER_HANDLER_LAST
+	{
+		.callback = NULL
+	}
 };
 
@@ -423,8 +448,7 @@
 /** Hub operations. */
 usbvirt_device_ops_t hub_ops = {
-	.control_transfer_handlers = endpoint_zero_handlers,
-	.on_data = NULL,
-	.on_data_request = req_on_data,
-	.on_state_change = on_state_change,
+	.control = endpoint_zero_handlers,
+	.data_in[HUB_STATUS_CHANGE_PIPE] = req_on_status_change_pipe,
+	.state_changed = on_state_change,
 };
 
