Index: uspace/drv/uhci/Makefile
===================================================================
--- uspace/drv/uhci/Makefile	(revision db7ed07d8ae15decfe15ea427ac19d5f2e1f0706)
+++ uspace/drv/uhci/Makefile	(revision c13ecfeafc4ac52d2edf0fe7af3a8fe05b764278)
@@ -40,5 +40,6 @@
 	root_hub/root_hub.c \
 	transfer_list.c \
-	uhci.c 
+	uhci.c \
+	uhci_struct/transfer_descriptor.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/uhci/uhci_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/uhci/uhci_struct/transfer_descriptor.c	(revision c13ecfeafc4ac52d2edf0fe7af3a8fe05b764278)
+++ uspace/drv/uhci/uhci_struct/transfer_descriptor.c	(revision c13ecfeafc4ac52d2edf0fe7af3a8fe05b764278)
@@ -0,0 +1,62 @@
+#include "transfer_descriptor.h"
+
+void transfer_descriptor_init(transfer_descriptor_t *instance,
+  int error_count, size_t size, bool isochronous, usb_target_t target,
+	int pid)
+{
+	assert(instance);
+
+	instance->next =
+	  0 | LINK_POINTER_VERTICAL_FLAG | LINK_POINTER_TERMINATE_FLAG;
+
+	assert(size < 1024);
+	instance->status = 0
+	  | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
+	  | TD_STATUS_ERROR_ACTIVE;
+
+	instance->device = 0
+		| ((size & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
+		| ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
+		| ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
+		| ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
+
+	instance->next_va = NULL;
+	instance->callback = NULL;
+}
+
+static inline usb_transaction_outcome_t convert_outcome(uint32_t status)
+{
+	/*TODO: refactor into something sane */
+	/*TODO: add additional usb_errors to usb_outcome_t */
+
+	if (status & TD_STATUS_ERROR_STALLED)
+		return USB_OUTCOME_CRCERROR;
+
+	if (status & TD_STATUS_ERROR_BUFFER)
+		return USB_OUTCOME_CRCERROR;
+
+	if (status & TD_STATUS_ERROR_BABBLE)
+		return USB_OUTCOME_BABBLE;
+
+	if (status & TD_STATUS_ERROR_NAK)
+		return USB_OUTCOME_CRCERROR;
+
+  if (status & TD_STATUS_ERROR_CRC)
+		return USB_OUTCOME_CRCERROR;
+
+	if (status & TD_STATUS_ERROR_BIT_STUFF)
+		return USB_OUTCOME_CRCERROR;
+
+	assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
+	| TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
+	return USB_OUTCOME_OK;
+}
+
+void transfer_descriptor_fini(transfer_descriptor_t *instance)
+{
+	assert(instance);
+	callback_run(instance->callback,
+		convert_outcome(instance->status),
+		instance->status >> TD_STATUS_ACTLEN_POS & TD_STATUS_ACTLEN_MASK
+	);
+}
Index: uspace/drv/uhci/uhci_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/uhci/uhci_struct/transfer_descriptor.h	(revision db7ed07d8ae15decfe15ea427ac19d5f2e1f0706)
+++ uspace/drv/uhci/uhci_struct/transfer_descriptor.h	(revision c13ecfeafc4ac52d2edf0fe7af3a8fe05b764278)
@@ -57,5 +57,5 @@
 #define TD_STATUS_COMPLETE_INTERRUPT_FLAG ( 1 << 24 )
 
-#define TD_STATUS_ACTIVE ( 1 << 23 )
+#define TD_STATUS_ERROR_ACTIVE ( 1 << 23 )
 #define TD_STATUS_ERROR_STALLED ( 1 << 22 )
 #define TD_STATUS_ERROR_BUFFER ( 1 << 21 )
@@ -65,6 +65,6 @@
 #define TD_STATUS_ERROR_BIT_STUFF ( 1 << 17 )
 #define TD_STATUS_ERROR_RESERVED ( 1 << 16 )
-#define TD_STATUS_POS 16
-#define TD_STATUS_MASK ( 0xff )
+#define TD_STATUS_ERROR_POS 16
+#define TD_STATUS_ERROR_MASK ( 0xff )
 
 #define TD_STATUS_ACTLEN_POS 0
@@ -86,7 +86,7 @@
 	uint32_t buffer_ptr;
 
-	/* there is 16 byte of data available here
+	/* there is 16 bytes of data available here
 	 * those are used to store callback pointer
-	 * and next pointer. Thus there is some free space
+	 * and next pointer. Thus, there is some free space
 	 * on 32bits systems.
 	 */
@@ -95,29 +95,9 @@
 } __attribute__((packed)) transfer_descriptor_t;
 
-static inline int transfer_descriptor_init(transfer_descriptor_t *instance,
+void transfer_descriptor_init(transfer_descriptor_t *instance,
   int error_count, size_t size, bool isochronous, usb_target_t target,
-	int pid)
-{
-	assert(instance);
+	int pid);
 
-	instance->next =
-	  0 | LINK_POINTER_VERTICAL_FLAG | LINK_POINTER_TERMINATE_FLAG;
-
-	assert(size < 1024);
-	instance->status = 0
-	  | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
-	  | TD_STATUS_ACTIVE;
-
-	instance->device = 0
-		| ((size & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
-		| ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
-		| ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
-		| ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
-
-	instance->next_va = NULL;
-	instance->callback = NULL;
-
-	return EOK;
-}
+void transfer_descriptor_fini(transfer_descriptor_t *instance);
 
 static inline void transfer_descriptor_append(
@@ -128,5 +108,4 @@
 	instance->next = (uintptr_t)addr_to_phys( item ) & LINK_POINTER_ADDRESS_MASK;
 }
-
 #endif
 /**
