Index: uspace/drv/bus/usb/ohci/ohci_regs.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_regs.h	(revision ece7f783e6a37b9486a7a9c1852130bf064ac2a6)
+++ uspace/drv/bus/usb/ohci/ohci_regs.h	(revision c85804f9f44a2f7d6f47dcb22455b2b036c47f39)
@@ -159,5 +159,5 @@
 #define RHDA_DT_FLAG   (1 << 10) /* 1-Compound device, must be 0 */
 #define RHDA_OCPM_FLAG (1 << 11) /* Over-current mode: 0-global, 1-per port */
-#define RHDA_NOCP      (1 << 12) /* OC control: 0-use OCPM, 1-OC off */
+#define RHDA_NOCP_FLAG (1 << 12) /* OC control: 0-use OCPM, 1-OC off */
 #define RHDA_POTPGT_MASK (0xff)  /* Power on to power good time */
 #define RHDA_POTPGT_SHIFT (24)
Index: uspace/drv/bus/usb/ohci/root_hub.c
===================================================================
--- uspace/drv/bus/usb/ohci/root_hub.c	(revision ece7f783e6a37b9486a7a9c1852130bf064ac2a6)
+++ uspace/drv/bus/usb/ohci/root_hub.c	(revision c85804f9f44a2f7d6f47dcb22455b2b036c47f39)
@@ -231,5 +231,5 @@
 	instance->port_count =
 	    (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK;
-	if (port_count > 15) {
+	if (instance->port_count > 15) {
 		usb_log_error("OHCI specification does not allow more than 15"
 		    " ports. Max 15 ports will be used");
@@ -241,11 +241,12 @@
 		return ret;
 	}
-	/* Set port power mode to no-power-switching. */
-	instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
-	instance->unfinished_interrupt_transfer = NULL;
 	/* Don't forget the hub status bit and round up */
 	instance->interrupt_mask_size = (instance->port_count + 1 + 8) / 8;
 	instance->interrupt_buffer[0] = 0;
 	instance->interrupt_buffer[1] = 0;
+	instance->unfinished_interrupt_transfer = NULL;
+
+	/* Set port power mode to no-power-switching. */
+	instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
 
 	usb_log_info("Root hub (%zu ports) initialized.\n",
@@ -313,8 +314,7 @@
 /*----------------------------------------------------------------------------*/
 /**
- * Create hub descriptor used in hub-driver <-> hub communication
- *
- * This means creating bit array from data in root hub registers. For more
- * info see usb hub specification.
+ * Create hub descriptor.
+ *
+ * For descriptor format see USB hub specification (chapter 11.15.2.1, pg. 263)
  *
  * @param instance Root hub instance
@@ -325,38 +325,46 @@
 	assert(instance);
 
-	const size_t size = 7 +
-	    ((instance->port_count + 7) / 8) * 2;
-	uint8_t * result = malloc(size);
+	const size_t bit_field_size = (instance->port_count + 1 + 7) / 8;
+	assert(bit_field_size == 2 || bit_field_size == 1);
+	/* 7 bytes + 2 port bit fields (port count + global bit) */
+	const size_t size = 7 + (bit_field_size * 2);
+
+	uint8_t *result = malloc(size);
 	if (!result)
 	    return ENOMEM;
 
-	bzero(result, size);
-	//size
+	/* bDescLength */
 	result[0] = size;
-	//descriptor type
+	/* bDescriptorType */
 	result[1] = USB_DESCTYPE_HUB;
+	/* bNmbrPorts */
 	result[2] = instance->port_count;
-	const uint32_t hub_desc_reg = instance->registers->rh_desc_a;
-	result[3] =
-	    ((hub_desc_reg >> 8) % 2) +
-	    (((hub_desc_reg >> 9) % 2) << 1) +
-	    (((hub_desc_reg >> 10) % 2) << 2) +
-	    (((hub_desc_reg >> 11) % 2) << 3) +
-	    (((hub_desc_reg >> 12) % 2) << 4);
+	const uint32_t hub_desc = instance->registers->rh_desc_a;
+	/* wHubCharacteristics */
+	result[3] = 0 |
+	    /* The lowest 2 bits indicate power switching mode */
+	    (((hub_desc & RHDA_PSM_FLAG)  ? 1 : 0) << 0) |
+	    (((hub_desc & RHDA_NPS_FLAG)  ? 1 : 0) << 1) |
+	    /* Bit 3 indicates device type (compound device) */
+	    (((hub_desc & RHDA_DT_FLAG)   ? 1 : 0) << 2) |
+	    /* Bits 4,5 indicate over-current protection mode */
+	    (((hub_desc & RHDA_OCPM_FLAG) ? 1 : 0) << 3) |
+	    (((hub_desc & RHDA_NOCP_FLAG) ? 1 : 0) << 4);
+
+	/* Reserved */
 	result[4] = 0;
-	result[5] = 50; /*descriptor->pwr_on_2_good_time*/
-	result[6] = 50;
-
-	size_t port = 1;
-	for (; port <= instance->port_count; ++port) {
-		const uint8_t is_non_removable =
-		    instance->registers->rh_desc_b >> port % 2;
-		result[7 + port / 8] +=
-		    is_non_removable << (port % 8);
-	}
-	const size_t var_size = (instance->port_count + 7) / 8;
-	size_t i = 0;
-	for (; i < var_size; ++i) {
-		result[7 + var_size + i] = 255;
+	/* bPwrOn2PwrGood */
+	result[5] = (hub_desc >> RHDA_POTPGT_SHIFT) & RHDA_POTPGT_MASK;
+	/* bHubContrCurrent, root hubs don't need no power. */
+	result[6] = 0;
+
+	const uint32_t port_desc = instance->registers->rh_desc_a;
+	/* Device Removable and some legacy 1.0 stuff*/
+	result[7] = (port_desc >> RHDB_DR_SHIFT) & RHDB_DR_MASK & 0xff;
+	result[8] = 0xff;
+	if (bit_field_size == 2) {
+		result[8]  = (port_desc >> RHDB_DR_SHIFT) & RHDB_DR_MASK >> 8;
+		result[9]  = 0xff;
+		result[10] = 0xff;
 	}
 	instance->hub_descriptor = result;
@@ -378,34 +386,36 @@
 
 	memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor,
-	    sizeof (ohci_rh_device_descriptor)
-	    );
+	    sizeof(ohci_rh_device_descriptor));
+
 	usb_standard_configuration_descriptor_t descriptor;
 	memcpy(&descriptor, &ohci_rh_conf_descriptor,
-	    sizeof (ohci_rh_conf_descriptor));
+	    sizeof(ohci_rh_conf_descriptor));
 
 	int opResult = create_serialized_hub_descriptor(instance);
-	if (opResult != EOK) {
+	if (opResult != EOK)
 		return opResult;
-	}
+
 	descriptor.total_length =
-	    sizeof (usb_standard_configuration_descriptor_t) +
-	    sizeof (usb_standard_endpoint_descriptor_t) +
-	    sizeof (usb_standard_interface_descriptor_t) +
+	    sizeof(usb_standard_configuration_descriptor_t) +
+	    sizeof(usb_standard_endpoint_descriptor_t) +
+	    sizeof(usb_standard_interface_descriptor_t) +
 	    instance->descriptor_size;
 
-	uint8_t * full_config_descriptor = malloc(descriptor.total_length);
-	if (!full_config_descriptor) {
+	uint8_t *full_config_descriptor = malloc(descriptor.total_length);
+	if (!full_config_descriptor)
 		return ENOMEM;
-	}
-	memcpy(full_config_descriptor, &descriptor, sizeof (descriptor));
-	memcpy(full_config_descriptor + sizeof (descriptor),
-	    &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor));
-	memcpy(full_config_descriptor + sizeof (descriptor) +
-	    sizeof (ohci_rh_iface_descriptor),
-	    &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor));
-	memcpy(full_config_descriptor + sizeof (descriptor) +
-	    sizeof (ohci_rh_iface_descriptor) +
-	    sizeof (ohci_rh_ep_descriptor),
-	    instance->hub_descriptor, instance->descriptor_size);
+
+	uint8_t *place = full_config_descriptor;
+	memcpy(place, &descriptor, sizeof(descriptor));
+
+	place += sizeof(descriptor);
+	memcpy(place, &ohci_rh_iface_descriptor,
+	    sizeof(ohci_rh_iface_descriptor));
+
+	place += sizeof(ohci_rh_iface_descriptor);
+	memcpy(place, &ohci_rh_ep_descriptor, sizeof(ohci_rh_ep_descriptor));
+
+	place += sizeof(ohci_rh_iface_descriptor);
+	memcpy(place, instance->hub_descriptor, instance->descriptor_size);
 
 	instance->descriptors.configuration = full_config_descriptor;
Index: uspace/drv/bus/usb/ohci/root_hub.h
===================================================================
--- uspace/drv/bus/usb/ohci/root_hub.h	(revision ece7f783e6a37b9486a7a9c1852130bf064ac2a6)
+++ uspace/drv/bus/usb/ohci/root_hub.h	(revision c85804f9f44a2f7d6f47dcb22455b2b036c47f39)
@@ -55,5 +55,5 @@
 	/** interrupt transfer waiting for an actual interrupt to occur */
 	usb_transfer_batch_t * unfinished_interrupt_transfer;
-	/** pre-allocated interrupt mask
+	/** Interrupt mask of changes
 	 *
 	 * OHCI support max 15 ports (specs page 124) + one global bit, it
