Index: uspace/drv/bus/usb/usbhub/usbhub.c
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub.c	(revision dbb9663316ea6d7478b1030015c0c9e090f19f83)
+++ uspace/drv/bus/usb/usbhub/usbhub.c	(revision 5fd0dc23df3107b5d981c0bc688fbea5363e6284)
@@ -220,9 +220,9 @@
  * @return error code
  */
-static int usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info) {
+int usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info)
+{
 	// get hub descriptor
-	usb_log_debug("Creating serialized descriptor\n");
+	usb_log_debug("Retrieving descriptor\n");
 	uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE];
-	usb_hub_descriptor_t * descriptor;
 	int opResult;
 
@@ -234,47 +234,53 @@
 
 	if (opResult != EOK) {
-		usb_log_error("Failed when receiving hub descriptor, "
-		    "%s\n",
-		    str_error(opResult));
-		free(serialized_descriptor);
+		usb_log_error("Failed to receive hub descriptor: %s.\n",
+		    str_error(opResult));
 		return opResult;
 	}
-	usb_log_debug2("Deserializing descriptor\n");
-	descriptor = usb_create_deserialized_hub_desriptor(
-	    serialized_descriptor);
-	if (descriptor == NULL) {
-		usb_log_warning("could not deserialize descriptor \n");
-		return ENOMEM;
-	}
-	usb_log_debug("setting port count to %d\n", descriptor->ports_count);
-	hub_info->port_count = descriptor->ports_count;
-	const bool is_power_switched =
-	    ((descriptor->hub_characteristics & 0x2) == 0);
-	hub_info->ports = malloc(
-	    sizeof (usb_hub_port_t) * (hub_info->port_count + 1));
+	usb_log_debug2("Parsing descriptor\n");
+	usb_hub_descriptor_t descriptor;
+	opResult = usb_deserialize_hub_desriptor(
+	        serialized_descriptor, received_size, &descriptor);
+	if (opResult != EOK) {
+		usb_log_error("Could not parse descriptor: %s\n",
+		    str_error(opResult));
+		return opResult;
+	}
+	usb_log_debug("Setting port count to %d.\n", descriptor.ports_count);
+	hub_info->port_count = descriptor.ports_count;
+
+	hub_info->ports =
+	    malloc(sizeof(usb_hub_port_t) * (hub_info->port_count + 1));
 	if (!hub_info->ports) {
 		return ENOMEM;
 	}
+
 	size_t port;
 	for (port = 0; port < hub_info->port_count + 1; ++port) {
 		usb_hub_port_init(&hub_info->ports[port]);
 	}
+
+	const bool is_power_switched =
+	    !(descriptor.hub_characteristics & HUB_CHAR_NO_POWER_SWITCH_FLAG);
 	if (is_power_switched) {
 		usb_log_debug("Hub power switched\n");
-		const bool has_individual_port_powering =
-		    descriptor->hub_characteristics & 0x1;
-
-		if (!has_individual_port_powering) {
-			//this setting actually makes no difference
-			usb_log_debug("Hub has global powering\n");
-		}
+		const bool per_port_power = descriptor.hub_characteristics
+		    & HUB_CHAR_POWER_PER_PORT_FLAG;
 
 		for (port = 1; port <= hub_info->port_count; ++port) {
 			usb_log_debug("Powering port %zu.\n", port);
-			opResult = usb_hub_set_port_feature(hub_info->control_pipe,
+			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 (!per_port_power) {
+					usb_log_debug(
+					    "Ganged power switching mode,"
+					    "one port is enough.\n");
+					break;
+				}
 			}
 		}
@@ -283,6 +289,4 @@
 		usb_log_debug("Power not switched, not going to be powered\n");
 	}
-	usb_log_debug2("Freeing data\n");
-	free(descriptor);
 	return EOK;
 }
Index: uspace/drv/bus/usb/usbhub/usbhub_private.h
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub_private.h	(revision dbb9663316ea6d7478b1030015c0c9e090f19f83)
+++ uspace/drv/bus/usb/usbhub/usbhub_private.h	(revision 5fd0dc23df3107b5d981c0bc688fbea5363e6284)
@@ -171,9 +171,6 @@
     void * serialized_descriptor);
 
-usb_hub_descriptor_t * usb_create_deserialized_hub_desriptor(
-    void * serialized_descriptor);
-
-void usb_deserialize_hub_desriptor(void * serialized_descriptor,
-    usb_hub_descriptor_t * descriptor);
+int usb_deserialize_hub_desriptor(
+    void *serialized_descriptor, size_t size, usb_hub_descriptor_t *descriptor);
 
 
Index: uspace/drv/bus/usb/usbhub/utils.c
===================================================================
--- uspace/drv/bus/usb/usbhub/utils.c	(revision dbb9663316ea6d7478b1030015c0c9e090f19f83)
+++ uspace/drv/bus/usb/usbhub/utils.c	(revision 5fd0dc23df3107b5d981c0bc688fbea5363e6284)
@@ -110,53 +110,45 @@
 }
 
+/*----------------------------------------------------------------------------*/
 /**
- * create deserialized desriptor structure out of serialized descriptor
+ * Deserialize descriptor into given pointer
  *
- * The serialized descriptor must be proper usb hub descriptor,
- * otherwise an eerror might occur.
- *
- * @param sdescriptor serialized descriptor
- * @return newly created deserialized descriptor pointer
- */
-usb_hub_descriptor_t * usb_create_deserialized_hub_desriptor(
-    void *serialized_descriptor) {
-	uint8_t * sdescriptor = serialized_descriptor;
-
-	if (sdescriptor[1] != USB_DESCTYPE_HUB) {
-		usb_log_warning("trying to deserialize wrong descriptor %x\n",
-		    sdescriptor[1]);
-		return NULL;
-	}
-
-	usb_hub_descriptor_t * result = malloc(sizeof (usb_hub_descriptor_t));
-	if (result)
-		usb_deserialize_hub_desriptor(serialized_descriptor, result);
-	return result;
-}
-
-/**
- * deserialize descriptor into given pointer
- * 
  * @param serialized_descriptor
  * @param descriptor
  * @return
  */
-void usb_deserialize_hub_desriptor(
-    void * serialized_descriptor, usb_hub_descriptor_t *descriptor) {
+int usb_deserialize_hub_desriptor(
+    void *serialized_descriptor, size_t size, usb_hub_descriptor_t *descriptor)
+{
 	uint8_t * sdescriptor = serialized_descriptor;
+
+	if (sdescriptor[1] != USB_DESCTYPE_HUB) {
+		usb_log_error("Trying to deserialize wrong descriptor %x\n",
+		    sdescriptor[1]);
+		return EINVAL;
+	}
+	if (size < 7) {
+		usb_log_error("Serialized descriptor too small.\n");
+		return EOVERFLOW;
+	}
+
 	descriptor->ports_count = sdescriptor[2];
-	/// @fixme handling of endianness??
 	descriptor->hub_characteristics = sdescriptor[3] + 256 * sdescriptor[4];
 	descriptor->pwr_on_2_good_time = sdescriptor[5];
 	descriptor->current_requirement = sdescriptor[6];
-	size_t var_size = (descriptor->ports_count + 7) / 8;
+	const size_t var_size = (descriptor->ports_count + 7) / 8;
 	//descriptor->devices_removable = (uint8_t*) malloc(var_size);
 
-	size_t i;
-	for (i = 0; i < var_size; ++i) {
+	if (size < (7 + var_size)) {
+		usb_log_error("Serialized descriptor too small.\n");
+		return EOVERFLOW;
+	}
+	size_t i = 0;
+	for (; i < var_size; ++i) {
 		descriptor->devices_removable[i] = sdescriptor[7 + i];
 	}
+	return EOK;
 }
-
+/*----------------------------------------------------------------------------*/
 /**
  * @}
Index: uspace/lib/usb/include/usb/classes/hub.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hub.h	(revision dbb9663316ea6d7478b1030015c0c9e090f19f83)
+++ uspace/lib/usb/include/usb/classes/hub.h	(revision 5fd0dc23df3107b5d981c0bc688fbea5363e6284)
@@ -119,4 +119,6 @@
      */
     uint16_t hub_characteristics;
+#define HUB_CHAR_POWER_PER_PORT_FLAG  (1 << 0)
+#define HUB_CHAR_NO_POWER_SWITCH_FLAG (1 << 1)
 
     /**
