Index: uspace/lib/usb/src/devpoll.c
===================================================================
--- uspace/lib/usb/src/devpoll.c	(revision ffc63b0f6b944d4d796b469b5aec506c6dd1dbba)
+++ uspace/lib/usb/src/devpoll.c	(revision 6bec59bee36bbb7344227073a8e47f3537a0b284)
@@ -66,4 +66,10 @@
 	usb_pipe_t *pipe
 	    = polling_data->dev->pipes[polling_data->pipe_index].pipe;
+	
+	usb_log_debug("Pipe interface number: %d, protocol: %d, subclass: %d, max packet size: %d\n", 
+	    polling_data->dev->pipes[polling_data->pipe_index].interface_no,
+	    polling_data->dev->pipes[polling_data->pipe_index].description->interface_protocol,
+	    polling_data->dev->pipes[polling_data->pipe_index].description->interface_subclass,
+	    pipe->max_packet_size);
 
 	size_t failed_attempts = 0;
@@ -83,4 +89,11 @@
 		/* Quit the session regardless of errors. */
 		usb_pipe_end_session(pipe);
+		
+//		if (rc == ESTALL) {
+//			usb_log_debug("Seding clear feature...\n");
+//			usb_request_clear_feature(pipe, USB_REQUEST_TYPE_STANDARD,
+//			  USB_REQUEST_RECIPIENT_ENDPOINT, 0, pipe->endpoint_no);
+//			continue;
+//		}
 
 		if (rc != EOK) {
Index: uspace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision ffc63b0f6b944d4d796b469b5aec506c6dd1dbba)
+++ uspace/lib/usb/src/hidparser.c	(revision 6bec59bee36bbb7344227073a8e47f3537a0b284)
@@ -64,5 +64,5 @@
 int usb_hid_report_reset_local_items();
 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);
 /*
  * Data translation private functions
@@ -106,4 +106,7 @@
     list_initialize(&(parser->feature));
 
+	list_initialize(&(parser->stack));
+
+	parser->use_report_id = 0;
     return EOK;   
 }
@@ -186,4 +189,8 @@
 					tmp_usage_path = NULL;
 
+					usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);	
+					if(report_item->id != 0){
+						parser->use_report_id = 1;
+					}
 					
 					switch(tag) {
@@ -215,11 +222,22 @@
 					if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
 						return ENOMEM;
-					}
+					}					
 					memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t));
+					link_initialize(&(new_report_item->link));
+					
 					/* reset local items */
 					new_report_item->usage_minimum = 0;
 					new_report_item->usage_maximum = 0;
+					new_report_item->designator_index = 0;
+					new_report_item->designator_minimum = 0;
+					new_report_item->designator_maximum = 0;
+					new_report_item->string_index = 0;
+					new_report_item->string_minimum = 0;
+					new_report_item->string_maximum = 0;
+
+					/* reset usage from current usage path */
+					usb_hid_report_usage_path_t *path = list_get_instance(&usage_path->link, usb_hid_report_usage_path_t, link);
+					path->usage = 0;
 					
-					link_initialize(&(new_report_item->link));
 					report_item = new_report_item;
 										
@@ -227,9 +245,17 @@
 				case USB_HID_REPORT_TAG_PUSH:
 					// push current state to stack
-					// not yet implemented
+					new_report_item = usb_hid_report_item_clone(report_item);
+					list_prepend (&parser->stack, &new_report_item->link);
+					
 					break;
 				case USB_HID_REPORT_TAG_POP:
 					// restore current state from stack
-					// not yet implemented						   
+					if(list_empty (&parser->stack)) {
+						return EINVAL;
+					}
+					
+					report_item = list_get_instance(&parser->stack, usb_hid_report_item_t, link);
+					list_remove (parser->stack.next);
+					
 					break;
 					
@@ -647,4 +673,6 @@
 	}
 
+	parser->use_report_id = 0;
+
 	usb_hid_free_report_list(&parser->input);
 	usb_hid_free_report_list(&parser->output);
@@ -676,4 +704,5 @@
 	size_t i=0;
 	size_t j=0;
+	uint8_t report_id = 0;
 
 	if(parser == NULL) {
@@ -686,4 +715,9 @@
 	if(!(keys = malloc(sizeof(uint8_t) * key_count))){
 		return ENOMEM;
+	}
+
+	if(parser->use_report_id != 0) {
+		report_id = data[0];
+		usb_hid_report_path_set_report_id(path, report_id);
 	}
 
@@ -693,4 +727,5 @@
 
 		item = list_get_instance(list_item, usb_hid_report_item_t, link);
+
 		if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 
 		   (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {
@@ -715,5 +750,5 @@
 	}
 
-	callbacks->keyboard(keys, key_count, 0, arg);
+	callbacks->keyboard(keys, key_count, report_id, arg);
 	   
 	free(keys);	
@@ -739,5 +774,5 @@
 	int32_t mask;
 	const uint8_t *foo;
-	
+
 	// now only common numbers llowed
 	if(item->size > 32) {
@@ -758,5 +793,10 @@
 		(usb_pow(10,(item->unit_exponent))));
 	}
+
 	offset = item->offset + (j * item->size);
+	if(item->id != 0) {
+		offset += 8;
+		usb_log_debug("MOVED OFFSET BY 1Byte, REPORT_ID(%d)\n", item->id);
+	}
 	
 	// FIXME
@@ -942,4 +982,8 @@
 
 	int only_page;
+
+	if(report_path->report_id != path->report_id) {
+		return 1;
+	}
 
 	if(path->depth == 0){
@@ -1038,4 +1082,5 @@
 	else {
 		path->depth = 0;
+		path->report_id = 0;
 		list_initialize(&path->link);
 		return path;
@@ -1155,5 +1200,5 @@
 		return 0;
 	}
-	
+
 	item = parser->output.next;
 	while(&parser->output != item) {
@@ -1195,7 +1240,13 @@
 	int length;
 	int32_t tmp_value;
+	size_t offset_prefix = 0;
 	
 	if(parser == NULL) {
 		return EINVAL;
+	}
+
+	if(parser->use_report_id != 0) {
+		buffer[0] = path->report_id;
+		offset_prefix = 8;
 	}
 
@@ -1218,5 +1269,5 @@
 //				// variable item
 				value = usb_hid_translate_data_reverse(report_item, data[idx++]);
-				offset = report_item->offset + (i * report_item->size);
+				offset = report_item->offset + (i * report_item->size) + offset_prefix;
 				length = report_item->size;
 			}
@@ -1224,5 +1275,5 @@
 				//bitmap
 				value += usb_hid_translate_data_reverse(report_item, data[idx++]);
-				offset = report_item->offset;
+				offset = report_item->offset + offset_prefix;
 				length = report_item->size * report_item->count;
 			}
@@ -1323,4 +1374,28 @@
 
 
+int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id)
+{
+	if(path == NULL){
+		return EINVAL;
+	}
+
+	path->report_id = report_id;
+	return EOK;
+}
+
+
+usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item)
+{
+	usb_hid_report_item_t *new_report_item;
+	
+	if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
+		return NULL;
+	}					
+	memcpy(new_report_item,item, sizeof(usb_hid_report_item_t));
+	link_initialize(&(new_report_item->link));
+
+	return new_report_item;
+}
+
 /**
  * @}
Index: uspace/lib/usb/src/hidreport.c
===================================================================
--- uspace/lib/usb/src/hidreport.c	(revision ffc63b0f6b944d4d796b469b5aec506c6dd1dbba)
+++ uspace/lib/usb/src/hidreport.c	(revision 6bec59bee36bbb7344227073a8e47f3537a0b284)
@@ -80,4 +80,5 @@
 		d = usb_dp_get_sibling_descriptor(&parser, &parser_data, 
 		    dev->descriptors.configuration, d);
+		++i;
 	}
 	
