Index: uspace/lib/usbhid/src/hiddescriptor.c
===================================================================
--- uspace/lib/usbhid/src/hiddescriptor.c	(revision 0c904a3fb5599566e1ae979140f5f8493cbf9fe1)
+++ uspace/lib/usbhid/src/hiddescriptor.c	(revision 574f2763a63b0f7a18a34c671fc59e327a54e4ec)
@@ -187,4 +187,8 @@
 
 		field = malloc(sizeof(usb_hid_report_field_t));
+		if(field == NULL) {
+			return ENOMEM;
+		}
+
 		memset(field, 0, sizeof(usb_hid_report_field_t));
 		list_initialize(&field->link);
@@ -241,13 +245,15 @@
 
 		field->size = report_item->size;
-		
-		size_t offset_byte = (report_item->offset + (i *
-			report_item->size)) / 8; 
-
-		size_t offset_bit = 8 - ((report_item->offset + (i *
-			report_item->size)) % 8) - report_item->size;
-
-		field->offset = 8 * offset_byte + offset_bit;
-		if(report_item->id != 0) {
+	
+		if(report_item->type == USB_HID_REPORT_TYPE_INPUT) {
+			field->offset = report_item->offset + 
+			    ((report_item->count - (i + 1)) * 
+			    report_item->size);
+		}
+		else {
+			field->offset = report_item->offset + (i * report_item->size);
+		}
+
+		if(report->use_report_ids != 0) {
 			field->offset += 8;
 			report->use_report_ids = 1;
Index: uspace/lib/usbhid/src/hidparser.c
===================================================================
--- uspace/lib/usbhid/src/hidparser.c	(revision 0c904a3fb5599566e1ae979140f5f8493cbf9fe1)
+++ uspace/lib/usbhid/src/hidparser.c	(revision 574f2763a63b0f7a18a34c671fc59e327a54e4ec)
@@ -258,15 +258,18 @@
 				foo = data + i;
 				mask =  ((1 << (item->size-part_size))-1);
-				value = (*foo & mask) << part_size;
+				value = (*foo & mask);
 			}
 			else if(i == ((offset+item->size-1)/8)){
 				// the lower one
 				foo = data + i;
-				mask =  ((1 << part_size)-1) << (8-part_size);
-				value += ((*foo & mask) >> (8-part_size));
+				mask = ((1 << (item->size - part_size)) - 1) 
+					<< (8 - (item->size - part_size));
+
+				value = (((*foo & mask) >> (8 - 
+				    (item->size - part_size))) << part_size ) 
+				    + value;
 			}
 			else {
-				value = value << 8;
-				value += *(data + 1);
+				value = (*(data + 1) << (part_size + 8)) + value;
 				part_size += 8;
 			}
@@ -386,22 +389,10 @@
 		report_item = list_get_instance(item, usb_hid_report_field_t, link);
 
-		if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
-					
-			// array
-			value = usb_hid_translate_data_reverse(report_item, 
-				report_item->value);
-
-			offset = report_item->offset;
-			length = report_item->size;
-		}
-		else {
-			// variable item
-			value  = usb_hid_translate_data_reverse(report_item, 
-				report_item->value);
-
-			offset = report_item->offset;
-			length = report_item->size;
-		}
-
+		value = usb_hid_translate_data_reverse(report_item, 
+			report_item->value);
+
+		offset = report_des->bit_length - report_item->offset - 1;
+		length = report_item->size;
+		
 		usb_log_debug("\ttranslated value: %x\n", value);
 
