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);
 	}
