Index: uspace/drv/usbhid/hidreq.c
===================================================================
--- uspace/drv/usbhid/hidreq.c	(revision a60150a3100679ffb522243b05de26eafc57efed)
+++ uspace/drv/usbhid/hidreq.c	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -69,4 +69,7 @@
 		return sess_rc;
 	}
+	
+	uint16_t value = 0;
+	value |= (type << 8);
 
 	usb_log_debug("Sending Set_Report request to the device.\n");
@@ -74,5 +77,5 @@
 	rc = usb_control_request_set(&hid_dev->ctrl_pipe, 
 	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
-	    USB_HIDREQ_SET_REPORT, type, hid_dev->iface, buffer, buf_size);
+	    USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);
 
 	sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
@@ -187,4 +190,172 @@
 		return sess_rc;
 	}
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
+int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 
+    uint8_t *buffer, size_t buf_size, size_t *actual_size)
+{
+	if (hid_dev == NULL) {
+		usb_log_error("usbhid_req_set_report(): no HID device structure"
+		    " given.\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc, sess_rc;
+	
+	sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
+	if (sess_rc != EOK) {
+		usb_log_warning("Failed to start a session: %s.\n",
+		    str_error(sess_rc));
+		return sess_rc;
+	}
+
+	uint16_t value = 0;
+	value |= (type << 8);
+	
+	usb_log_debug("Sending Get_Report request to the device.\n");
+	
+	rc = usb_control_request_get(&hid_dev->ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,
+	    actual_size);
+
+	sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+
+	if (sess_rc != EOK) {
+		usb_log_warning("Error closing session: %s.\n",
+		    str_error(sess_rc));
+		return sess_rc;
+	}
+	
+	return EOK;
+}
+
+int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
+{
+	if (hid_dev == NULL) {
+		usb_log_error("usbhid_req_set_protocol(): no HID device "
+		    "structure given.\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc, sess_rc;
+	
+	sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
+	if (sess_rc != EOK) {
+		usb_log_warning("Failed to start a session: %s.\n",
+		    str_error(sess_rc));
+		return sess_rc;
+	}
+
+	usb_log_debug("Sending Get_Protocol request to the device ("
+	    "iface: %d).\n", hid_dev->iface);
+	
+	uint8_t buffer[1];
+	size_t actual_size = 0;
+	
+	rc = usb_control_request_get(&hid_dev->ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);
+
+	sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+
+	if (sess_rc != EOK) {
+		usb_log_warning("Error closing session: %s.\n",
+		    str_error(sess_rc));
+		return sess_rc;
+	}
+	
+	if (actual_size != 1) {
+		usb_log_warning("Wrong data size: %zu, expected: 1.\n",
+			actual_size);
+		return ELIMIT;
+	}
+	
+	*protocol = buffer[0];
+	
+	return EOK;
+}
+
+int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
+{
+	if (hid_dev == NULL) {
+		usb_log_error("usbhid_req_set_idle(): no HID device "
+		    "structure given.\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc, sess_rc;
+	
+	sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
+	if (sess_rc != EOK) {
+		usb_log_warning("Failed to start a session: %s.\n",
+		    str_error(sess_rc));
+		return sess_rc;
+	}
+
+	usb_log_debug("Sending Get_Idle request to the device ("
+	    "iface: %d).\n", hid_dev->iface);
+	
+	uint16_t value = 0;
+	uint8_t buffer[1];
+	size_t actual_size = 0;
+	
+	rc = usb_control_request_get(&hid_dev->ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1, 
+	    &actual_size);
+
+	sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+
+	if (sess_rc != EOK) {
+		usb_log_warning("Error closing session: %s.\n",
+		    str_error(sess_rc));
+		return sess_rc;
+	}
+	
+	if (actual_size != 1) {
+		usb_log_warning("Wrong data size: %zu, expected: 1.\n",
+			actual_size);
+		return ELIMIT;
+	}
+	
+	*duration = buffer[0];
 	
 	return EOK;
Index: uspace/drv/usbhid/hidreq.h
===================================================================
--- uspace/drv/usbhid/hidreq.h	(revision a60150a3100679ffb522243b05de26eafc57efed)
+++ uspace/drv/usbhid/hidreq.h	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -52,4 +52,11 @@
 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration);
 
+int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 
+    uint8_t *buffer, size_t buf_size, size_t *actual_size);
+
+int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol);
+
+int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration);
+
 /*----------------------------------------------------------------------------*/
 
Index: uspace/drv/usbhid/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbddev.c	(revision a60150a3100679ffb522243b05de26eafc57efed)
+++ uspace/drv/usbhid/kbddev.c	(revision 8a203808ad84cae152a85f2b2171b0aac758e47d)
@@ -63,4 +63,5 @@
 static const size_t BOOTP_BUFFER_SIZE = 8;
 static const size_t BOOTP_BUFFER_OUT_SIZE = 1;
+static const uint8_t BOOTP_ERROR_ROLLOVER = 1;
 static const uint8_t IDLE_RATE = 0;
 
@@ -181,11 +182,8 @@
 	    usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0));
 	
-	uint16_t value = 0;
-	value |= (USB_HID_REPORT_TYPE_OUTPUT << 8);
-
 	assert(kbd_dev->hid_dev != NULL);
 	assert(kbd_dev->hid_dev->initialized);
-	usbhid_req_set_report(kbd_dev->hid_dev, value, buffer, 
-	    BOOTP_BUFFER_OUT_SIZE);
+	usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT, 
+	    buffer, BOOTP_BUFFER_OUT_SIZE);
 }
 
@@ -322,8 +320,21 @@
     const uint8_t *key_codes)
 {
-	// TODO: phantom state!!
-	
 	unsigned int key;
 	unsigned int i, j;
+	
+	/*
+	 * First of all, check if the kbd have reported phantom state.
+	 */
+	i = 0;
+	// all fields should report Error Rollover
+	while (i < kbd_dev->keycode_count &&
+	    key_codes[i] == BOOTP_ERROR_ROLLOVER) {
+		++i;
+	}
+	if (i == kbd_dev->keycode_count) {
+		usb_log_debug("Phantom state occured.\n");
+		// phantom state, do nothing
+		return;
+	}
 	
 	// TODO: quite dummy right now, think of better implementation
@@ -344,5 +355,5 @@
 			key = usbhid_parse_scancode(kbd_dev->keycodes[j]);
 			usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
-			usb_log_debug2("\nKey released: %d\n", key);
+			usb_log_debug2("Key released: %d\n", key);
 		} else {
 			// found, nothing happens
@@ -364,5 +375,5 @@
 			// not found, i.e. new key pressed
 			key = usbhid_parse_scancode(key_codes[i]);
-			usb_log_debug2("\nKey pressed: %d (keycode: %d)\n", key,
+			usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
 			    key_codes[i]);
 			usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
@@ -375,5 +386,5 @@
 //		if (key_codes[i] != 0) {
 //			key = usbhid_parse_scancode(key_codes[i]);
-//			usb_log_debug2("\nKey pressed: %d (keycode: %d)\n", key,
+//			usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
 //			    key_codes[i]);
 //			usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
