Index: uspace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision 1775ebc62e3f1fe43ab64f79d88cf2437d7fffdd)
+++ uspace/lib/usb/src/hidparser.c	(revision cf2ccd4368b5ded2c44cf0c34588f91253ac78f9)
@@ -73,5 +73,5 @@
 void usb_hid_print_usage_path(usb_hid_report_path_t *path);
 void usb_hid_descriptor_print_list(link_t *head);
-int usb_hid_report_reset_local_items();
+void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item);
 void usb_hid_free_report_list(link_t *head);
 usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item);
@@ -79,5 +79,5 @@
  * Data translation private functions
  */
-int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);
+uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data);
@@ -85,4 +85,6 @@
 int usb_pow(int a, int b);
 
+#define USB_HID_UINT32_TO_INT32(x, size)	((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1)))
+#define USB_HID_INT32_TO_UINT32(x, size)	(((x) < 0 ) ? ((1 << (size)) + (x)) : (x))
 // TODO: tohle ma bejt asi jinde
 int usb_pow(int a, int b)
@@ -144,4 +146,8 @@
 	}
 
+	for(i=0; i<report_item->usages_count; i++){
+		usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]);
+	}
+
 	
 	for(i=0; i<report_item->count; i++){
@@ -168,16 +174,32 @@
 
 		if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
-			if(i < report_item->usages_count){
-				if((report_item->usages[i] & 0xFF00) != 0){
-					field->usage_page = (report_item->usages[i] >> 16);					
-					field->usage = (report_item->usages[i] & 0xFF);
+			uint32_t usage;
+			if(report_item->type != USB_HID_REPORT_TYPE_INPUT) {
+				if(i < report_item->usages_count){
+					usage = report_item->usages[i];
 				}
 				else {
-					field->usage = report_item->usages[i];
+					usage = report_item->usages[report_item->usages_count - 1];
 				}
 			}
 			else {
-				field->usage = report_item->usages[report_item->usages_count - 1];
-			}
+				if((report_item->count - i - 1) < report_item->usages_count){
+					usage = report_item->usages[(report_item->count - i - 1)];
+				}
+				else {
+					usage = report_item->usages[report_item->usages_count - 1];
+				}
+			}
+
+						
+			if((usage & 0xFF00) != 0){
+				field->usage_page = (usage >> 16);					
+				field->usage = (usage & 0xFF);
+			}
+			else {
+				field->usage = usage;
+			}
+
+			
 		}	
 
@@ -342,17 +364,5 @@
 
 					/* reset local items */
-					while(report_item->usages_count > 0){
-						report_item->usages[--(report_item->usages_count)] = 0;
-					}
-
-					report_item->extended_usage_page = 0;
-					report_item->usage_minimum = 0;
-					report_item->usage_maximum = 0;
-					report_item->designator_index = 0;
-					report_item->designator_minimum = 0;
-					report_item->designator_maximum = 0;
-					report_item->string_index = 0;
-					report_item->string_minimum = 0;
-					report_item->string_maximum = 0;
+					usb_hid_report_reset_local_items (report_item);
 
 					break;
@@ -476,4 +486,5 @@
 			// TODO usage_path->flags = *data;
 			usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);						
+			usb_hid_report_reset_local_items (report_item);
 			return USB_HID_NO_ACTION;
 			break;
@@ -506,32 +517,33 @@
 	{
 		case USB_HID_REPORT_TAG_USAGE_PAGE:
-			report_item->usage_page = usb_hid_report_tag_data_int32(data, item_size);
+			report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size);
 			break;
 		case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
-			report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
 			break;
 		case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
-			report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
 			break;
 		case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
-			report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
 			break;			
 		case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
-			report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
+
 			break;
 		case USB_HID_REPORT_TAG_UNIT_EXPONENT:
-			report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_UNIT:
-			report_item->unit = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->unit = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_REPORT_SIZE:
-			report_item->size = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->size = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_REPORT_COUNT:
-			report_item->count = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->count = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_REPORT_ID:
-			report_item->id = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->id = usb_hid_report_tag_data_uint32(data,item_size);
 			return USB_HID_RESET_OFFSET;
 			break;
@@ -548,5 +560,5 @@
 			return USB_HID_NO_ACTION;
 	}
-	
+
 	return EOK;
 }
@@ -567,14 +579,15 @@
 	{
 		case USB_HID_REPORT_TAG_USAGE:
-			report_item->usages[report_item->usages_count++] = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
+			report_item->usages_count++;
 			break;
 		case USB_HID_REPORT_TAG_USAGE_MINIMUM:
 			if (item_size == 3) {
 				// usage extended usages
-				report_item->extended_usage_page = (usb_hid_report_tag_data_int32(data,item_size) & 0xFF00) >> 16; 
-				report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size) & 0xFF;
+				report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 
+				report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
 			}
 			else {
-				report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);
+				report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
 			}
 			break;
@@ -582,31 +595,31 @@
 			if (item_size == 3) {
 				// usage extended usages
-				report_item->extended_usage_page = (usb_hid_report_tag_data_int32(data,item_size) & 0xFF00) >> 16; 
-				report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size) & 0xFF;
+				report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 
+				report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
 			}
 			else {
-				report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);
+				report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
 			}
 			break;
 		case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
-			report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
-			report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
-			report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_STRING_INDEX:
-			report_item->string_index = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_STRING_MINIMUM:
-			report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size);
 			break;
 		case USB_HID_REPORT_TAG_STRING_MAXIMUM:
-			report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size);
+			report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size);
 			break;			
 		case USB_HID_REPORT_TAG_DELIMITER:
-			//report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);
+			//report_item->delimiter = usb_hid_report_tag_data_uint32(data,item_size);
 			//TODO: 
 			//	DELIMITER STUFF
@@ -621,5 +634,5 @@
 
 /**
- * Converts raw data to int32 (thats the maximum length of short item data)
+ * Converts raw data to uint32 (thats the maximum length of short item data)
  *
  * @param Data buffer
@@ -627,8 +640,8 @@
  * @return Converted int32 number
  */
-int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size)
+uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size)
 {
 	unsigned int i;
-	int32_t result;
+	uint32_t result;
 
 	result = 0;
@@ -639,6 +652,4 @@
 	return result;
 }
-
-
 
 /**
@@ -665,8 +676,8 @@
 		usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
 		usb_log_debug("\t\tSIZE: %X\n", report_item->size);				
-		usb_log_debug("\t\tLOGMIN: %X\n", report_item->logical_minimum);
-		usb_log_debug("\t\tLOGMAX: %X\n", report_item->logical_maximum);		
-		usb_log_debug("\t\tPHYMIN: %X\n", report_item->physical_minimum);		
-		usb_log_debug("\t\tPHYMAX: %X\n", report_item->physical_maximum);				
+		usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
+		usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);		
+		usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum);		
+		usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum);				
 		usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
 		usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
@@ -918,9 +929,6 @@
 	}
 
-	if(!(item->logical_minimum >= 0 && item->logical_maximum >= 0)){
-		value = (int32_t)value;
-	}
-	else {
-		value = (uint32_t)value;
+	if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
+		value = USB_HID_UINT32_TO_INT32(value, item->size);
 	}
 
@@ -1529,6 +1537,8 @@
 	}
 
-
-	return (uint32_t)ret;
+	if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
+		return USB_HID_INT32_TO_UINT32(ret, item->size);
+	}
+	return (int32_t)ret;
 }
 
@@ -1683,5 +1693,25 @@
 }
 
-
+void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item)
+{
+	if(report_item == NULL)	{
+		return;
+	}
+	
+	report_item->usages_count = 0;
+	memset(report_item->usages, 0, USB_HID_MAX_USAGES);
+	
+	report_item->extended_usage_page = 0;
+	report_item->usage_minimum = 0;
+	report_item->usage_maximum = 0;
+	report_item->designator_index = 0;
+	report_item->designator_minimum = 0;
+	report_item->designator_maximum = 0;
+	report_item->string_index = 0;
+	report_item->string_minimum = 0;
+	report_item->string_maximum = 0;
+
+	return;
+}
 /**
  * @}
