Index: uspace/lib/usbvirt/src/stdreq.c
===================================================================
--- uspace/lib/usbvirt/src/stdreq.c	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/lib/usbvirt/src/stdreq.c	(revision 664a331cb566f574f706db9600d7dd570c9fa938)
@@ -1,70 +1,44 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+#include "private.h"
+#include <usb/request.h>
+#include <assert.h>
+#include <errno.h>
 
-/** @addtogroup libusbvirt
- * @{
- */
-/** @file
- * @brief Preprocessing of standard device requests.
- */
-#include <errno.h>
-#include <stdlib.h>
-#include <mem.h>
-#include <usb/request.h>
+void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *setup_packet,
+    uint8_t *data, size_t *act_size,
+    void *actual_data, size_t actual_data_size)
+{
+	size_t expected_size = setup_packet->length;
+	if (expected_size < actual_data_size) {
+		actual_data_size = expected_size;
+	}
 
-#include "private.h"
+	memcpy(data, actual_data, actual_data_size);
 
-/*
- * All sub handlers must return EFORWARD to inform the caller that
- * they were not able to process the request (yes, it is abuse of
- * this error code but such error code shall not collide with anything
- * else in this context).
- */
- 
+	if (act_size != NULL) {
+		*act_size = actual_data_size;
+	}
+}
+
 /** GET_DESCRIPTOR handler. */
-static int handle_get_descriptor(usbvirt_device_t *device,
-    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
+static int req_get_descriptor(usbvirt_device_t *device,
+    const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
 {
 	uint8_t type = setup_packet->value_high;
 	uint8_t index = setup_packet->value_low;
 
-	/* 
+	/*
 	 * Standard device descriptor.
 	 */
 	if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) {
 		if (device->descriptors && device->descriptors->device) {
-			return device->control_transfer_reply(device, 0,
+			usbvirt_control_reply_helper(setup_packet, data, act_size,
 			    device->descriptors->device,
 			    device->descriptors->device->length);
+			return EOK;
 		} else {
 			return EFORWARD;
 		}
 	}
-	
+
 	/*
 	 * Configuration descriptor together with interface, endpoint and
@@ -85,5 +59,5 @@
 			return ENOMEM;
 		}
-		
+
 		uint8_t *ptr = all_data;
 		memcpy(ptr, config->descriptor, config->descriptor->length);
@@ -96,19 +70,18 @@
 			ptr += extra->length;
 		}
-		
-		int rc = device->control_transfer_reply(device, 0,
+
+		usbvirt_control_reply_helper(setup_packet, data, act_size,
 		    all_data, config->descriptor->total_length);
-		
+
 		free(all_data);
-		
-		return rc;
+
+		return EOK;
 	}
-	
+
 	return EFORWARD;
 }
 
-/** SET_ADDRESS handler. */
-static int handle_set_address(usbvirt_device_t *device,
-    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
+static int req_set_address(usbvirt_device_t *device,
+    const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
 {
 	uint16_t new_address = setup_packet->value;
@@ -119,17 +92,16 @@
 		return EINVAL;
 	}
-	
+
 	if (new_address > 127) {
 		return EINVAL;
 	}
-	
-	device->new_address = new_address;
-	
+
+	device->address = new_address;
+
 	return EOK;
 }
 
-/** SET_CONFIGURATION handler. */
-static int handle_set_configuration(usbvirt_device_t *device,
-    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
+static int req_set_configuration(usbvirt_device_t *device,
+    const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
 {
 	uint16_t configuration_value = setup_packet->value;
@@ -140,5 +112,5 @@
 		return EINVAL;
 	}
-	
+
 	/*
 	 * Configuration value is 1 byte information.
@@ -147,5 +119,5 @@
 		return EINVAL;
 	}
-	
+
 	/*
 	 * Do nothing when in default state. According to specification,
@@ -155,60 +127,48 @@
 		return EOK;
 	}
-	
+
+	usbvirt_device_state_t new_state;
 	if (configuration_value == 0) {
-		if (DEVICE_HAS_OP(device, on_state_change)) {
-			device->ops->on_state_change(device, device->state,
-			    USBVIRT_STATE_ADDRESS);
-		}
-		device->state = USBVIRT_STATE_ADDRESS;
+		new_state = USBVIRT_STATE_ADDRESS;
 	} else {
-		/*
-		* TODO: browse provided configurations and verify that
-		* user selected existing configuration.
-		*/
-		if (DEVICE_HAS_OP(device, on_state_change)) {
-			device->ops->on_state_change(device, device->state,
-			    USBVIRT_STATE_CONFIGURED);
-		}
-		device->state = USBVIRT_STATE_CONFIGURED;
-		if (device->descriptors) {
-			device->descriptors->current_configuration
-			    = configuration_value;
-		}
+		// FIXME: check that this configuration exists
+		new_state = USBVIRT_STATE_CONFIGURED;
 	}
-		
+
+	if (device->ops && device->ops->state_changed) {
+		device->ops->state_changed(device, device->state, new_state);
+	}
+	device->state = new_state;
+
 	return EOK;
 }
 
-
-#define MAKE_BM_REQUEST(direction, recipient) \
-	USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \
-	    USBVIRT_REQUEST_TYPE_STANDARD, recipient)
-#define MAKE_BM_REQUEST_DEV(direction) \
-	MAKE_BM_REQUEST(direction, USBVIRT_REQUEST_RECIPIENT_DEVICE)
-
-usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[] = {
+usbvirt_control_request_handler_t library_handlers[] = {
 	{
-		.request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_IN),
-		.request = USB_DEVREQ_GET_DESCRIPTOR,
-		.name = "GetDescriptor()",
-		.callback = handle_get_descriptor
+		.req_direction = USB_DIRECTION_OUT,
+		.req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
+		.req_type = USB_REQUEST_TYPE_STANDARD,
+		.request = USB_DEVREQ_SET_ADDRESS,
+		.name = "SetAddress",
+		.callback = req_set_address
 	},
 	{
-		.request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT),
-		.request = USB_DEVREQ_SET_ADDRESS,
-		.name = "SetAddress()",
-		.callback = handle_set_address
+		.req_direction = USB_DIRECTION_IN,
+		.req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
+		.req_type = USB_REQUEST_TYPE_STANDARD,
+		.request = USB_DEVREQ_GET_DESCRIPTOR,
+		.name = "GetDescriptor",
+		.callback = req_get_descriptor
 	},
 	{
-		.request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT),
+		.req_direction = USB_DIRECTION_OUT,
+		.req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
+		.req_type = USB_REQUEST_TYPE_STANDARD,
 		.request = USB_DEVREQ_SET_CONFIGURATION,
-		.name = "SetConfiguration()",
-		.callback = handle_set_configuration
+		.name = "SetConfiguration",
+		.callback = req_set_configuration
 	},
-	USBVIRT_CONTROL_TRANSFER_HANDLER_LAST
+
+	{ .callback = NULL }
 };
 
-/**
- * @}
- */
