Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision 97e87de172275f4c488ecf1af6d38344fe622592)
+++ uspace/drv/uhci-hcd/iface.c	(revision 881c47b89a3f49cc8b416bd912851b33fcce20cb)
@@ -110,5 +110,5 @@
 	assert(hc);
 	return uhci_transfer(hc, dev, target, USB_TRANSFER_INTERRUPT, 0, USB_PID_OUT,
-		data, size, callback, NULL, arg);
+		false, data, size, callback, NULL, arg);
 }
 /*----------------------------------------------------------------------------*/
@@ -121,5 +121,5 @@
 	assert(hc);
 	return uhci_transfer(hc, dev, target, USB_TRANSFER_INTERRUPT, 0, USB_PID_IN,
-		data, size, NULL, callback, arg);
+		false, data, size, NULL, callback, arg);
 }
 /*----------------------------------------------------------------------------*/
@@ -132,5 +132,5 @@
 	assert(hc);
 	return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_SETUP,
-		data, size, callback, NULL, arg);
+		false, data, size, callback, NULL, arg);
 }
 /*----------------------------------------------------------------------------*/
@@ -143,5 +143,5 @@
 	assert(hc);
 	return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 1, USB_PID_OUT,
-		data, size, callback, NULL, arg);
+		false, data, size, callback, NULL, arg);
 }
 /*----------------------------------------------------------------------------*/
@@ -153,5 +153,5 @@
 	assert(hc);
 	return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_IN,
-		NULL, 0, NULL, callback, arg);
+		false, NULL, 0, NULL, callback, arg);
 }
 /*----------------------------------------------------------------------------*/
@@ -164,5 +164,5 @@
 	assert(hc);
 	return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_SETUP,
-		data, size, callback, NULL, arg);
+		false, data, size, callback, NULL, arg);
 }
 /*----------------------------------------------------------------------------*/
@@ -175,5 +175,5 @@
 	assert(hc);
 	return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 1, USB_PID_IN,
-		data, size, NULL, callback, arg);
+		false, data, size, NULL, callback, arg);
 }
 /*----------------------------------------------------------------------------*/
@@ -185,5 +185,5 @@
 	assert(hc);
 	return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_OUT,
-		NULL, 0, callback, NULL, arg);
+		false, NULL, 0, callback, NULL, arg);
 }
 
Index: uspace/drv/uhci-hcd/transfer_list.c
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.c	(revision 97e87de172275f4c488ecf1af6d38344fe622592)
+++ uspace/drv/uhci-hcd/transfer_list.c	(revision 881c47b89a3f49cc8b416bd912851b33fcce20cb)
@@ -38,9 +38,11 @@
 #include "transfer_list.h"
 
-int transfer_list_init(transfer_list_t *instance, transfer_list_t *next)
+int transfer_list_init(transfer_list_t *instance, const char *name)
 {
 	assert(instance);
 	instance->first = NULL;
 	instance->last = NULL;
+	instance->next = NULL;
+	instance->name = name;
 	instance->queue_head = queue_head_get();
 	if (!instance->queue_head) {
@@ -50,7 +52,16 @@
 	instance->queue_head_pa = (uintptr_t)addr_to_phys(instance->queue_head);
 
-	uint32_t next_pa = next ? next->queue_head_pa : 0;
-	queue_head_init(instance->queue_head, next_pa);
+	queue_head_init(instance->queue_head);
 	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)
+{
+	assert(instance);
+	assert(next);
+	instance->next = next;
+	if (!instance->queue_head)
+		return;
+	queue_head_add_next(instance->queue_head, next->queue_head_pa);
 }
 /*----------------------------------------------------------------------------*/
@@ -81,6 +92,6 @@
 		instance->queue_head->element = (pa & LINK_POINTER_ADDRESS_MASK);
 	}
-	usb_log_debug("Successfully added transfer to the hc queue %p.\n",
-	  instance);
+	usb_log_debug("Successfully added transfer to the hc queue %S.\n",
+	  instance->name);
 	return EOK;
 }
Index: uspace/drv/uhci-hcd/transfer_list.h
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.h	(revision 97e87de172275f4c488ecf1af6d38344fe622592)
+++ uspace/drv/uhci-hcd/transfer_list.h	(revision 881c47b89a3f49cc8b416bd912851b33fcce20cb)
@@ -44,7 +44,11 @@
 	queue_head_t *queue_head;
 	uint32_t queue_head_pa;
+	struct transfer_list *next;
+	const char *name;
 } transfer_list_t;
 
-int transfer_list_init(transfer_list_t *instance, transfer_list_t *next);
+int transfer_list_init(transfer_list_t *instance, const char *name);
+
+void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);
 
 static inline void transfer_list_fini(transfer_list_t *instance)
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision 97e87de172275f4c488ecf1af6d38344fe622592)
+++ uspace/drv/uhci-hcd/uhci.c	(revision 881c47b89a3f49cc8b416bd912851b33fcce20cb)
@@ -39,5 +39,5 @@
 #include "uhci.h"
 
-static int uhci_init_transfer_lists(transfer_list_t list[]);
+static int uhci_init_transfer_lists(uhci_t *instance);
 static int uhci_clean_finished(void *arg);
 static int uhci_debug_checker(void *arg);
@@ -64,5 +64,5 @@
 
 	/* init transfer lists */
-	ret = uhci_init_transfer_lists(instance->transfers);
+	ret = uhci_init_transfer_lists(instance);
 	CHECK_RET_RETURN("Failed to initialize transfer lists.\n");
 	usb_log_debug("Transfer lists initialized.\n");
@@ -76,5 +76,5 @@
 	/* initialize all frames to point to the first queue head */
 	const uint32_t queue =
-	  instance->transfers[USB_TRANSFER_INTERRUPT].queue_head_pa
+	  instance->transfers_interrupt.queue_head_pa
 	  | LINK_POINTER_QUEUE_HEAD_FLAG;
 	unsigned i = 0;
@@ -97,41 +97,50 @@
 	    UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
 	usb_log_debug("Started UHCI HC.\n");
-/*
+
 	uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
 	cmd |= UHCI_CMD_DEBUG;
 	pio_write_16(&instance->registers->usbcmd, cmd);
-*/
+
 	return EOK;
 }
 /*----------------------------------------------------------------------------*/
-int uhci_init_transfer_lists(transfer_list_t transfers[])
-{
-	//TODO:refactor
-	transfers[USB_TRANSFER_ISOCHRONOUS].first = NULL;
-	transfers[USB_TRANSFER_ISOCHRONOUS].last = NULL;
-
+int uhci_init_transfer_lists(uhci_t *instance)
+{
+	assert(instance);
+
+	/* initialize */
 	int ret;
-	ret = transfer_list_init(&transfers[USB_TRANSFER_BULK], NULL);
-	if (ret != EOK) {
-		usb_log_error("Failed to initialize bulk queue.\n");
-		return ret;
-	}
-
-	ret = transfer_list_init(
-	  &transfers[USB_TRANSFER_CONTROL], &transfers[USB_TRANSFER_BULK]);
-	if (ret != EOK) {
-		usb_log_error("Failed to initialize control queue.\n");
-		transfer_list_fini(&transfers[USB_TRANSFER_BULK]);
-		return ret;
-	}
-
-	ret = transfer_list_init(
-	  &transfers[USB_TRANSFER_INTERRUPT], &transfers[USB_TRANSFER_CONTROL]);
-	if (ret != EOK) {
-		usb_log_error("Failed to initialize interrupt queue.\n");
-		transfer_list_fini(&transfers[USB_TRANSFER_CONTROL]);
-		transfer_list_fini(&transfers[USB_TRANSFER_BULK]);
-		return ret;
-	}
+	ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
+	assert(ret == EOK);
+	ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL");
+	assert(ret == EOK);
+	ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW");
+	assert(ret == EOK);
+	ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT");
+	assert(ret == EOK);
+
+	transfer_list_set_next(&instance->transfers_control_full,
+		&instance->transfers_bulk_full);
+	transfer_list_set_next(&instance->transfers_control_slow,
+		&instance->transfers_control_full);
+	transfer_list_set_next(&instance->transfers_interrupt,
+		&instance->transfers_control_slow);
+
+	/*FSBR*/
+#ifdef FSBR
+	transfer_list_set_next(&instance->transfers_bulk_full,
+		&instance->transfers_control_full);
+#endif
+
+	instance->transfers[0][USB_TRANSFER_INTERRUPT] =
+	  &instance->transfers_interrupt;
+	instance->transfers[1][USB_TRANSFER_INTERRUPT] =
+	  &instance->transfers_interrupt;
+	instance->transfers[0][USB_TRANSFER_CONTROL] =
+	  &instance->transfers_control_full;
+	instance->transfers[1][USB_TRANSFER_CONTROL] =
+	  &instance->transfers_control_slow;
+	instance->transfers[0][USB_TRANSFER_CONTROL] =
+	  &instance->transfers_control_full;
 
 	return EOK;
@@ -145,4 +154,5 @@
 	bool toggle,
   usb_packet_id pid,
+	bool low_speed,
   void *buffer, size_t size,
   usbhc_iface_transfer_out_callback_t callback_out,
@@ -165,4 +175,9 @@
 	if (size >= 1024) {
 		usb_log_warning("Transfer too big.\n");
+		return ENOTSUP;
+	}
+	transfer_list_t *list = instance->transfers[low_speed][transfer_type];
+	if (!list) {
+		usb_log_warning("UNSUPPORTED transfer %d-%d.\n", low_speed, transfer_type);
 		return ENOTSUP;
 	}
@@ -193,6 +208,8 @@
 	td->callback = job;
 
-	usb_log_debug("Appending a new transfer to queue.\n");
-	ret = transfer_list_append(&instance->transfers[transfer_type], td);
+
+	usb_log_debug("Appending a new transfer to queue %s.\n", list->name);
+
+	ret = transfer_list_append(list, td);
 	CHECK_RET_TRANS_FREE_JOB_TD("Failed to append transfer descriptor.\n");
 
@@ -209,12 +226,12 @@
 		usb_log_debug("Running cleaning fibril on: %p.\n", instance);
 		/* iterate all transfer queues */
-		int i = 0;
-		for (; i < TRANSFER_QUEUES; ++i) {
+		transfer_list_t *current_list = &instance->transfers_interrupt;
+		while (current_list) {
 			/* Remove inactive transfers from the top of the queue
 			 * TODO: should I reach queue head or is this enough? */
 			volatile transfer_descriptor_t * it =
-				instance->transfers[i].first;
-			usb_log_debug("Running cleaning fibril on queue: %p (%s).\n",
-				&instance->transfers[i], it ? "SOMETHING" : "EMPTY");
+				current_list->first;
+			usb_log_debug("Running cleaning fibril on queue: %s (%s).\n",
+				current_list->name, it ? "SOMETHING" : "EMPTY");
 
 			if (it)
@@ -222,14 +239,16 @@
 					it, it->status);
 
-			while (instance->transfers[i].first &&
-			 !(instance->transfers[i].first->status & TD_STATUS_ERROR_ACTIVE)) {
-				transfer_descriptor_t *transfer = instance->transfers[i].first;
+			while (current_list->first &&
+			 !(current_list->first->status & TD_STATUS_ERROR_ACTIVE)) {
+				transfer_descriptor_t *transfer = current_list->first;
 				usb_log_info("Inactive transfer calling callback with status %x.\n",
 				  transfer->status);
-				instance->transfers[i].first = transfer->next_va;
+				current_list->first = transfer->next_va;
 				transfer_descriptor_dispose(transfer);
 			}
-			if (!instance->transfers[i].first)
-				instance->transfers[i].last = instance->transfers[i].first;
+			if (!current_list->first)
+				current_list->last = current_list->first;
+
+			current_list = current_list->next;
 		}
 		async_usleep(UHCI_CLEANER_TIMEOUT);
@@ -246,5 +265,5 @@
 		uint16_t sts = pio_read_16(&instance->registers->usbsts);
 		usb_log_debug("Command register: %X Status register: %X\n", cmd, sts);
-/*
+
 		uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
 		usb_log_debug("Framelist address: %p vs. %p.\n",
@@ -253,19 +272,35 @@
 		usb_log_debug("Framelist item: %d \n", frnum );
 
-		queue_head_t* qh = instance->transfers[USB_TRANSFER_INTERRUPT].queue_head;
-		usb_log_debug("Interrupt QH: %p vs. %p.\n",
-			instance->frame_list[frnum], addr_to_phys(qh));
-
-		usb_log_debug("Control QH: %p vs. %p.\n", qh->next_queue,
-			addr_to_phys(instance->transfers[USB_TRANSFER_CONTROL].queue_head));
-		qh = instance->transfers[USB_TRANSFER_CONTROL].queue_head;
-
-		usb_log_debug("Bulk QH: %p vs. %p.\n", qh->next_queue,
-			addr_to_phys(instance->transfers[USB_TRANSFER_BULK].queue_head));
+		queue_head_t* qh = instance->transfers_interrupt.queue_head;
+
+		if ((instance->frame_list[frnum] & (~0xf)) != (uintptr_t)addr_to_phys(qh)) {
+			usb_log_debug("Interrupt QH: %p vs. %p.\n",
+				instance->frame_list[frnum] & (~0xf), addr_to_phys(qh));
+		}
+
+		if ((qh->next_queue & (~0xf))
+		  != (uintptr_t)addr_to_phys(instance->transfers_control_slow.queue_head)) {
+			usb_log_debug("Control Slow QH: %p vs. %p.\n", qh->next_queue & (~0xf),
+				addr_to_phys(instance->transfers_control_slow.queue_head));
+		}
+		qh = instance->transfers_control_slow.queue_head;
+
+		if ((qh->next_queue & (~0xf))
+		  != (uintptr_t)addr_to_phys(instance->transfers_control_full.queue_head)) {
+			usb_log_debug("Control Full QH: %p vs. %p.\n", qh->next_queue & (~0xf),
+				addr_to_phys(instance->transfers_control_full.queue_head));\
+		}
+		qh = instance->transfers_control_full.queue_head;
+
+		if ((qh->next_queue & (~0xf))
+		  != (uintptr_t)addr_to_phys(instance->transfers_bulk_full.queue_head)) {
+			usb_log_debug("Bulk QH: %p vs. %p.\n", qh->next_queue & (~0xf),
+				addr_to_phys(instance->transfers_bulk_full.queue_head));
+		}
+/*
 	uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
 	cmd |= UHCI_CMD_RUN_STOP;
 	pio_write_16(&instance->registers->usbcmd, cmd);
 */
-
 		async_usleep(UHCI_DEBUGER_TIMEOUT);
 	}
Index: uspace/drv/uhci-hcd/uhci.h
===================================================================
--- uspace/drv/uhci-hcd/uhci.h	(revision 97e87de172275f4c488ecf1af6d38344fe622592)
+++ uspace/drv/uhci-hcd/uhci.h	(revision 881c47b89a3f49cc8b416bd912851b33fcce20cb)
@@ -79,5 +79,11 @@
 	link_pointer_t *frame_list;
 
-	transfer_list_t transfers[TRANSFER_QUEUES];
+	transfer_list_t transfers_bulk_full;
+	transfer_list_t transfers_control_full;
+	transfer_list_t transfers_control_slow;
+	transfer_list_t transfers_interrupt;
+
+	transfer_list_t *transfers[2][4];
+
 	fid_t cleaner;
 	fid_t debug_checker;
@@ -96,4 +102,5 @@
 	bool toggle,
   usb_packet_id pid,
+	bool low_speed,
   void *buffer, size_t size,
   usbhc_iface_transfer_out_callback_t callback_out,
Index: uspace/drv/uhci-hcd/uhci_struct/queue_head.h
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/queue_head.h	(revision 97e87de172275f4c488ecf1af6d38344fe622592)
+++ uspace/drv/uhci-hcd/uhci_struct/queue_head.h	(revision 881c47b89a3f49cc8b416bd912851b33fcce20cb)
@@ -47,15 +47,17 @@
 } __attribute__((packed)) queue_head_t;
 
-static inline void queue_head_init(queue_head_t *instance, uint32_t next_queue_pa)
+static inline void queue_head_init(queue_head_t *instance)
 {
 	assert(instance);
-	assert((next_queue_pa & LINK_POINTER_ADDRESS_MASK) == next_queue_pa);
 
 	instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
+	instance->next_queue = 0 | LINK_POINTER_TERMINATE_FLAG;
+}
+
+static inline void queue_head_add_next(queue_head_t *instance, uint32_t next_queue_pa)
+{
 	if (next_queue_pa) {
 		instance->next_queue = (next_queue_pa & LINK_POINTER_ADDRESS_MASK)
 		  | LINK_POINTER_QUEUE_HEAD_FLAG;
-	} else {
-		instance->next_queue = 0 | LINK_POINTER_TERMINATE_FLAG;
 	}
 }
