Index: uspace/lib/drv/generic/remote_usbhid.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhid.c	(revision a28b41dd6b0ca2ce220627ab395811bd5b0f71c0)
+++ uspace/lib/drv/generic/remote_usbhid.c	(revision 9dddb3dfa6c4ae26ceff0ac4e871f83e29b386e2)
@@ -117,4 +117,5 @@
 		async_answer_0(data_callid, EINVAL);
 		async_answer_0(callid, EINVAL);
+		return;
 	}
 
@@ -125,4 +126,5 @@
 		async_answer_0(data_callid, ENOMEM);
 		async_answer_0(callid, ENOMEM);
+		return;
 	}
 
@@ -133,4 +135,5 @@
 		async_answer_0(data_callid, rc);
 		async_answer_0(callid, rc);
+		return;
 	}
 	if (act_length >= len) {
@@ -147,15 +150,68 @@
 }
 
-void remote_usbhid_get_report_descriptor(ddf_fun_t *fun, void *iface, 
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	/** @todo Implement! */
-}
-
-void remote_usbhid_get_report_descriptor_length(ddf_fun_t *fun, void *iface, 
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	/** @todo Implement! */
-}
+void remote_usbhid_get_report_descriptor_length(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface;
+
+	if (!hid_iface->get_report_descriptor_length) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	size_t len = hid_iface->get_report_descriptor_length(fun);
+	async_answer_1(callid, EOK, (sysarg_t) len);
+}
+
+void remote_usbhid_get_report_descriptor(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface;
+
+	if (!hid_iface->get_report_descriptor) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	size_t len;
+	ipc_callid_t data_callid;
+	if (!async_data_read_receive(&data_callid, &len)) {
+		async_answer_0(callid, EINVAL);
+		return;
+	}
+
+	if (len == 0) {
+		async_answer_0(data_callid, EINVAL);
+		async_answer_0(callid, EINVAL);
+		return;
+	}
+
+	uint8_t *descriptor = malloc(len);
+	if (descriptor == NULL) {
+		async_answer_0(data_callid, ENOMEM);
+		async_answer_0(callid, ENOMEM);
+		return;
+	}
+
+	size_t act_len = 0;
+	int rc = hid_iface->get_report_descriptor(fun, descriptor, len,
+	    &act_len);
+	if (act_len > len) {
+		rc = ELIMIT;
+	}
+	if (rc != EOK) {
+		free(descriptor);
+		async_answer_0(data_callid, rc);
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	async_data_read_finalize(data_callid, descriptor, act_len);
+	async_answer_0(callid, EOK);
+
+	free(descriptor);
+}
+
+
 
 /**
Index: uspace/lib/drv/include/usbhid_iface.h
===================================================================
--- uspace/lib/drv/include/usbhid_iface.h	(revision a28b41dd6b0ca2ce220627ab395811bd5b0f71c0)
+++ uspace/lib/drv/include/usbhid_iface.h	(revision 9dddb3dfa6c4ae26ceff0ac4e871f83e29b386e2)
@@ -71,8 +71,7 @@
 	 * - none
 	 * Answer:
-	 * - Size of one report in bytes.
-	 * - 
-	 *
-	 * @todo Finish this comment
+	 * - EOK - method is implemented (expected always)
+	 * Parameters of the answer:
+	 * - Size of the report in bytes.
 	 */
 	IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH,
@@ -82,9 +81,7 @@
 	 * Parameters:
 	 * - none
+	 * The call is followed by data read expecting the descriptor itself.
 	 * Answer:
 	 * - EOK - report descriptor returned.
-	 * - 
-	 *
-	 * @todo Finish this comment
 	 */
 	IPC_M_USBHID_GET_REPORT_DESCRIPTOR
@@ -125,5 +122,6 @@
 	 * @param[in] fun DDF function answering the request.
 	 * @param[out] desc Buffer with the report descriptor.
-	 * @param[out] size Size of the report descriptors in bytes.
+	 * @param[in] size Size of the allocated @p desc buffer.
+	 * @param[out] act_size Actual size of the report descriptor returned.
 	 * @return Error code.
 	 */
Index: uspace/lib/usbhid/src/hidiface.c
===================================================================
--- uspace/lib/usbhid/src/hidiface.c	(revision a28b41dd6b0ca2ce220627ab395811bd5b0f71c0)
+++ uspace/lib/usbhid/src/hidiface.c	(revision 9dddb3dfa6c4ae26ceff0ac4e871f83e29b386e2)
@@ -56,5 +56,7 @@
 	    IPC_M_USBHID_GET_EVENT_LENGTH, &len);
 	if (rc == EOK) {
-		*size = (size_t) len;
+		if (size != NULL) {
+			*size = (size_t) len;
+		}
 	}
 	
@@ -148,6 +150,17 @@
 int usbhid_dev_get_report_descriptor_length(int dev_phone, size_t *size)
 {
-	/** @todo Implement! */
-	return ENOTSUP;
+	if (dev_phone < 0) {
+		return EINVAL;
+	}
+
+	sysarg_t arg_size;
+	int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE),
+	    IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
+	if (rc == EOK) {
+		if (size != NULL) {
+			*size = (size_t) arg_size;
+		}
+	}
+	return rc;
 }
 
@@ -155,6 +168,54 @@
     size_t *actual_size)
 {
-	/** @todo Implement! */
-	return ENOTSUP;
+	if (dev_phone < 0) {
+		return EINVAL;
+	}
+	if ((buf == NULL)) {
+		return ENOMEM;
+	}
+	if (size == 0) {
+		return EINVAL;
+	}
+
+	aid_t opening_request = async_send_1(dev_phone,
+	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
+	    NULL);
+	if (opening_request == 0) {
+		return ENOMEM;
+	}
+
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(dev_phone, buf, size,
+	    &data_request_call);
+	if (data_request == 0) {
+		async_wait_for(opening_request, NULL);
+		return ENOMEM;
+	}
+
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(opening_request, &opening_request_rc);
+
+	if (data_request_rc != EOK) {
+		/* Prefer return code of the opening request. */
+		if (opening_request_rc != EOK) {
+			return (int) opening_request_rc;
+		} else {
+			return (int) data_request_rc;
+		}
+	}
+
+	if (opening_request_rc != EOK) {
+		return (int) opening_request_rc;
+	}
+
+	size_t act_size = IPC_GET_ARG2(data_request_call);
+
+	if (actual_size != NULL) {
+		*actual_size = act_size;
+	}
+
+	return EOK;
 }
 
