Index: uspace/drv/vhc/hub.c
===================================================================
--- uspace/drv/vhc/hub.c	(revision 8f8ae1fd40abf46fa26616612cd5c3ff31aee970)
+++ uspace/drv/vhc/hub.c	(revision 11658b6402ef30f4b33c870d53939c869485ae26)
@@ -42,113 +42,31 @@
 #include <usb/usbdrv.h>
 
+#include "hub.h"
+#include "hub/virthub.h"
 #include "vhcd.h"
-#include "hub.h"
-#include "hubintern.h"
-#include "conn.h"
 
+usbvirt_device_t virtual_hub_device;
 
-/** Standard device descriptor. */
-usb_standard_device_descriptor_t std_device_descriptor = {
-	.length = sizeof(usb_standard_device_descriptor_t),
-	.descriptor_type = USB_DESCTYPE_DEVICE,
-	.usb_spec_version = 0x110,
-	.device_class = USB_CLASS_HUB,
-	.device_subclass = 0,
-	.device_protocol = 0,
-	.max_packet_size = 64,
-	.configuration_count = 1
-};
+static int hub_register_in_devman_fibril(void *arg);
 
-/** Standard interface descriptor. */
-usb_standard_interface_descriptor_t std_interface_descriptor = {
-	.length = sizeof(usb_standard_interface_descriptor_t),
-	.descriptor_type = USB_DESCTYPE_INTERFACE,
-	.interface_number = 0,
-	.alternate_setting = 0,
-	.endpoint_count = 1,
-	.interface_class = USB_CLASS_HUB,
-	.interface_subclass = 0,
-	.interface_protocol = 0,
-	.str_interface = 0
-};
+void virtual_hub_device_init(device_t *hc_dev)
+{
+	virthub_init(&virtual_hub_device);
 
-hub_descriptor_t hub_descriptor = {
-	.length = sizeof(hub_descriptor_t),
-	.type = USB_DESCTYPE_HUB,
-	.port_count = HUB_PORT_COUNT,
-	.characteristics = 0, 
-	.power_on_warm_up = 50, /* Huh? */
-	.max_current = 100, /* Huh again. */
-	.removable_device = { 0 },
-	.port_power = { 0xFF }
-};
+	/*
+	 * We need to register the root hub.
+	 * This must be done in separate fibril because the device
+	 * we are connecting to are ourselves and we cannot connect
+	 * before leaving the add_device() function.
+	 */
+	fid_t root_hub_registration
+	    = fibril_create(hub_register_in_devman_fibril, hc_dev);
+	if (root_hub_registration == 0) {
+		printf(NAME ": failed to register root hub\n");
+		return;
+	}
 
-/** Endpoint descriptor. */
-usb_standard_endpoint_descriptor_t endpoint_descriptor = {
-	.length = sizeof(usb_standard_endpoint_descriptor_t),
-	.descriptor_type = USB_DESCTYPE_ENDPOINT,
-	.endpoint_address = HUB_STATUS_CHANGE_PIPE | 128,
-	.attributes = USB_TRANSFER_INTERRUPT,
-	.max_packet_size = 8,
-	.poll_interval = 0xFF
-};
-
-/** Standard configuration descriptor. */
-usb_standard_configuration_descriptor_t std_configuration_descriptor = {
-	.length = sizeof(usb_standard_configuration_descriptor_t),
-	.descriptor_type = USB_DESCTYPE_CONFIGURATION,
-	.total_length = 
-		sizeof(usb_standard_configuration_descriptor_t)
-		+ sizeof(std_interface_descriptor)
-		+ sizeof(hub_descriptor)
-		+ sizeof(endpoint_descriptor)
-		,
-	.interface_count = 1,
-	.configuration_number = HUB_CONFIGURATION_ID,
-	.str_configuration = 0,
-	.attributes = 128, /* denotes bus-powered device */
-	.max_power = 50
-};
-
-/** All hub configuration descriptors. */
-static usbvirt_device_configuration_extras_t extra_descriptors[] = {
-	{
-		.data = (uint8_t *) &std_interface_descriptor,
-		.length = sizeof(std_interface_descriptor)
-	},
-	{
-		.data = (uint8_t *) &hub_descriptor,
-		.length = sizeof(hub_descriptor)
-	},
-	{
-		.data = (uint8_t *) &endpoint_descriptor,
-		.length = sizeof(endpoint_descriptor)
-	}
-};
-
-/** Hub configuration. */
-usbvirt_device_configuration_t configuration = {
-	.descriptor = &std_configuration_descriptor,
-	.extra = extra_descriptors,
-	.extra_count = sizeof(extra_descriptors)/sizeof(extra_descriptors[0])
-};
-
-/** Hub standard descriptors. */
-usbvirt_descriptors_t descriptors = {
-	.device = &std_device_descriptor,
-	.configuration = &configuration,
-	.configuration_count = 1,
-};
-
-/** Hub as a virtual device. */
-usbvirt_device_t virthub_dev = {
-	.ops = &hub_ops,
-	.descriptors = &descriptors,
-	.lib_debug_level = 0,
-	.lib_debug_enabled_tags = USBVIRT_DEBUGTAG_ALL
-};
-
-/** Hub device. */
-hub_device_t hub_dev;
+	fibril_add_ready(root_hub_registration);
+}
 
 /** Register root hub in devman.
@@ -157,5 +75,5 @@
  * @return Error code.
  */
-static int hub_register_in_devman_fibril(void *arg)
+int hub_register_in_devman_fibril(void *arg)
 {
 	device_t *hc_dev = (device_t *) arg;
@@ -180,128 +98,5 @@
 	return EOK;
 }
-
-/** Initialize virtual hub. */
-void hub_init(device_t *hc_dev)
-{
-	size_t i;
 	
-	for (i = 0; i < HUB_PORT_COUNT; i++) {
-		hub_port_t *port = &hub_dev.ports[i];
-		
-		port->index = (int) i + 1;
-		port->device = NULL;
-		port->state = HUB_PORT_STATE_NOT_CONFIGURED;
-		port->status_change = 0;
-		fibril_mutex_initialize(&port->guard);
-	}
-	
-	usbvirt_connect_local(&virthub_dev);
-	
-	/*
-	 * We need to register the root hub.
-	 * This must be done in separate fibril because the device
-	 * we are connecting to are ourselves and we cannot connect
-	 * before leaving the add_device() function.
-	 */
-	fid_t root_hub_registration
-	    = fibril_create(hub_register_in_devman_fibril, hc_dev);
-	if (root_hub_registration == 0) {
-		printf(NAME ": failed to register root hub\n");
-		return;
-	}
-
-	fibril_add_ready(root_hub_registration);
-}
-
-/** Connect device to the hub.
- *
- * @param device Device to be connected.
- * @return Port where the device was connected to.
- */
-size_t hub_add_device(virtdev_connection_t *device)
-{
-	size_t i;
-	for (i = 0; i < HUB_PORT_COUNT; i++) {
-		hub_port_t *port = &hub_dev.ports[i];
-		fibril_mutex_lock(&port->guard);
-		
-		if (port->device != NULL) {
-			fibril_mutex_unlock(&port->guard);
-			continue;
-		}
-		
-		port->device = device;
-		
-		/*
-		 * TODO:
-		 * If the hub was configured, we can normally
-		 * announce the plug-in.
-		 * Otherwise, we will wait until hub is configured
-		 * and announce changes in single burst.
-		 */
-		//if (port->state == HUB_PORT_STATE_DISCONNECTED) {
-			port->state = HUB_PORT_STATE_DISABLED;
-			set_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION);
-		//}
-		
-		fibril_mutex_unlock(&port->guard);
-
-		return i;
-	}
-	
-	return (size_t)-1;
-}
-
-/** Disconnect device from the hub. */
-void hub_remove_device(virtdev_connection_t *device)
-{
-	size_t i;
-	for (i = 0; i < HUB_PORT_COUNT; i++) {
-		hub_port_t *port = &hub_dev.ports[i];
-		
-		if (port->device != device) {
-			continue;
-		}
-		
-		port->device = NULL;
-		port->state = HUB_PORT_STATE_DISCONNECTED;
-		
-		set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
-	}
-}
-
-/** Tell whether device port is open.
- *
- * @return Whether communication to and from the device can go through the hub.
- */
-bool hub_can_device_signal(virtdev_connection_t * device)
-{
-	size_t i;
-	for (i = 0; i < HUB_PORT_COUNT; i++) {
-		if (hub_dev.ports[i].device == device) {
-			return hub_dev.ports[i].state == HUB_PORT_STATE_ENABLED;
-		}
-	}
-	
-	return false;
-}
-
-/** Format hub port status.
- *
- * @param result Buffer where to store status string.
- * @param len Number of characters that is possible to store in @p result
- * 	(excluding trailing zero).
- */
-void hub_get_port_statuses(char *result, size_t len)
-{
-	if (len > HUB_PORT_COUNT) {
-		len = HUB_PORT_COUNT;
-	}
-	size_t i;
-	for (i = 0; i < len; i++) {
-		result[i] = hub_port_state_as_char(hub_dev.ports[i].state);
-	}
-	result[len] = 0;
-}
 
 /**
