Index: uspace/lib/c/generic/loader.c
===================================================================
--- uspace/lib/c/generic/loader.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/c/generic/loader.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -160,4 +160,5 @@
 	int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
 	if (rc != EOK) {
+		free(pa);
 		async_wait_for(req, NULL);
 		return rc;
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -69,4 +69,5 @@
 	char *ncwd_path;
 	char *ncwd_path_nc;
+	size_t total_size; 
 
 	fibril_mutex_lock(&cwd_mutex);
@@ -77,14 +78,16 @@
 			return NULL;
 		}
-		ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
+		total_size = cwd_size + 1 + size + 1;
+		ncwd_path_nc = malloc(total_size);
 		if (!ncwd_path_nc) {
 			fibril_mutex_unlock(&cwd_mutex);
 			return NULL;
 		}
-		str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
+		str_cpy(ncwd_path_nc, total_size, cwd_path);
 		ncwd_path_nc[cwd_size] = '/';
 		ncwd_path_nc[cwd_size + 1] = '\0';
 	} else {
-		ncwd_path_nc = malloc(size + 1);
+		total_size = size + 1;
+		ncwd_path_nc = malloc(total_size);
 		if (!ncwd_path_nc) {
 			fibril_mutex_unlock(&cwd_mutex);
@@ -93,5 +96,5 @@
 		ncwd_path_nc[0] = '\0';
 	}
-	str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
+	str_append(ncwd_path_nc, total_size, path);
 	ncwd_path = canonify(ncwd_path_nc, retlen);
 	if (!ncwd_path) {
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -38,4 +38,7 @@
 	CHAR_DEV_IFACE,
 
+	/** Interface provided by any PCI device. */
+	PCI_DEV_IFACE,
+
 	/** Interface provided by any USB device. */
 	USB_DEV_IFACE,
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/drv/Makefile	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -38,4 +38,5 @@
 	generic/remote_hw_res.c \
 	generic/remote_usb.c \
+	generic/remote_pci.c \
 	generic/remote_usbhc.c
 
Index: uspace/lib/drv/generic/dev_iface.c
===================================================================
--- uspace/lib/drv/generic/dev_iface.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/drv/generic/dev_iface.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -43,4 +43,5 @@
 #include "remote_usb.h"
 #include "remote_usbhc.h"
+#include "remote_pci.h"
 
 static iface_dipatch_table_t remote_ifaces = {
@@ -48,4 +49,5 @@
 		&remote_hw_res_iface,
 		&remote_char_dev_iface,
+		&remote_pci_iface,
 		&remote_usb_iface,
 		&remote_usbhc_iface
Index: uspace/lib/drv/generic/remote_pci.c
===================================================================
--- uspace/lib/drv/generic/remote_pci.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/lib/drv/generic/remote_pci.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @{
+ */
+/** @file
+ */
+#include <assert.h>
+#include <async.h>
+#include <errno.h>
+
+#include "pci_dev_iface.h"
+#include "ddf/driver.h"
+
+static void remote_config_space_read_8(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_config_space_read_16(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_config_space_read_32(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+
+static void remote_config_space_write_8(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_config_space_write_16(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_config_space_write_32(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+
+/** Remote USB interface operations. */
+static remote_iface_func_ptr_t remote_pci_iface_ops [] = {
+	remote_config_space_read_8,
+	remote_config_space_read_16,
+	remote_config_space_read_32,
+
+	remote_config_space_write_8,
+	remote_config_space_write_16,
+	remote_config_space_write_32
+};
+
+/** Remote USB interface structure.
+ */
+remote_iface_t remote_pci_iface = {
+	.method_count = sizeof(remote_pci_iface_ops) /
+	    sizeof(remote_pci_iface_ops[0]),
+	.methods = remote_pci_iface_ops
+};
+
+void remote_config_space_read_8(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
+{
+	assert(iface);
+	pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
+	if (pci_iface->config_space_read_8 == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	uint32_t address = DEV_IPC_GET_ARG1(*call);
+	uint8_t value;
+	int ret = pci_iface->config_space_read_8(fun, address, &value);
+	if (ret != EOK) {
+		async_answer_0(callid, ret);
+	} else {
+		async_answer_1(callid, EOK, value);
+	}
+}
+
+void remote_config_space_read_16(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
+{
+	assert(iface);
+	pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
+	if (pci_iface->config_space_read_16 == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	uint32_t address = DEV_IPC_GET_ARG1(*call);
+	uint16_t value;
+	int ret = pci_iface->config_space_read_16(fun, address, &value);
+	if (ret != EOK) {
+		async_answer_0(callid, ret);
+	} else {
+		async_answer_1(callid, EOK, value);
+	}
+}
+void remote_config_space_read_32(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
+{
+	assert(iface);
+	pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
+	if (pci_iface->config_space_read_32 == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	uint32_t address = DEV_IPC_GET_ARG1(*call);
+	uint32_t value;
+	int ret = pci_iface->config_space_read_32(fun, address, &value);
+	if (ret != EOK) {
+		async_answer_0(callid, ret);
+	} else {
+		async_answer_1(callid, EOK, value);
+	}
+}
+
+void remote_config_space_write_8(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
+{
+	assert(iface);
+	pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
+	if (pci_iface->config_space_write_8 == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	uint32_t address = DEV_IPC_GET_ARG1(*call);
+	uint8_t value = DEV_IPC_GET_ARG2(*call);
+	int ret = pci_iface->config_space_write_8(fun, address, value);
+	if (ret != EOK) {
+		async_answer_0(callid, ret);
+	} else {
+		async_answer_0(callid, EOK);
+	}
+}
+
+void remote_config_space_write_16(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
+{
+	assert(iface);
+	pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
+	if (pci_iface->config_space_write_16 == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	uint32_t address = DEV_IPC_GET_ARG1(*call);
+	uint16_t value = DEV_IPC_GET_ARG2(*call);
+	int ret = pci_iface->config_space_write_16(fun, address, value);
+	if (ret != EOK) {
+		async_answer_0(callid, ret);
+	} else {
+		async_answer_0(callid, EOK);
+	}
+}
+
+void remote_config_space_write_32(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
+{
+	assert(iface);
+	pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
+	if (pci_iface->config_space_write_32 == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	uint32_t address = DEV_IPC_GET_ARG1(*call);
+	uint32_t value = DEV_IPC_GET_ARG2(*call);
+	int ret = pci_iface->config_space_write_32(fun, address, value);
+	if (ret != EOK) {
+		async_answer_0(callid, ret);
+	} else {
+		async_answer_0(callid, EOK);
+	}
+}
+
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/include/pci_dev_iface.h
===================================================================
--- uspace/lib/drv/include/pci_dev_iface.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/lib/drv/include/pci_dev_iface.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @addtogroup usb
+ * @{
+ */
+/** @file
+ * @brief PCI device interface definition.
+ */
+
+#ifndef LIBDRV_PCI_DEV_IFACE_H_
+#define LIBDRV_PCI_DEV_IFACE_H_
+
+#include "ddf/driver.h"
+
+typedef enum {
+	IPC_M_CONFIG_SPACE_READ_8,
+	IPC_M_CONFIG_SPACE_READ_16,
+	IPC_M_CONFIG_SPACE_READ_32,
+
+	IPC_M_CONFIG_SPACE_WRITE_8,
+	IPC_M_CONFIG_SPACE_WRITE_16,
+	IPC_M_CONFIG_SPACE_WRITE_32
+} pci_dev_iface_funcs_t;
+
+/** PCI device communication interface. */
+typedef struct {
+	int (*config_space_read_8)(ddf_fun_t *, uint32_t address, uint8_t *data);
+	int (*config_space_read_16)(ddf_fun_t *, uint32_t address, uint16_t *data);
+	int (*config_space_read_32)(ddf_fun_t *, uint32_t address, uint32_t *data);
+
+	int (*config_space_write_8)(ddf_fun_t *, uint32_t address, uint8_t data);
+	int (*config_space_write_16)(ddf_fun_t *, uint32_t address, uint16_t data);
+	int (*config_space_write_32)(ddf_fun_t *, uint32_t address, uint32_t data);
+} pci_dev_iface_t;
+
+
+#endif
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/include/remote_pci.h
===================================================================
--- uspace/lib/drv/include/remote_pci.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/lib/drv/include/remote_pci.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_PCI_H_
+#define LIBDRV_REMOTE_PCI_H_
+
+remote_iface_t remote_pci_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/usb/Makefile
===================================================================
--- uspace/lib/usb/Makefile	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/Makefile	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -47,6 +47,5 @@
 	src/request.c \
 	src/usb.c \
-	src/usbdevice.c \
-	src/usbmem.c
+	src/usbdevice.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/usb/include/usb/classes/classes.h
===================================================================
--- uspace/lib/usb/include/usb/classes/classes.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/include/usb/classes/classes.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief USB device classes and subclasses.
+ * USB device classes (generic constants and functions).
  */
 #ifndef LIBUSB_CLASSES_H_
Index: uspace/lib/usb/include/usb/debug.h
===================================================================
--- uspace/lib/usb/include/usb/debug.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/include/usb/debug.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief Debugging related functions.
+ * Debugging related functions.
  */
 #ifndef LIBUSB_DEBUG_H_
@@ -39,7 +39,4 @@
 #include <assert.h>
 
-void usb_dprintf(const char *tag, int level, const char *format, ...);
-void usb_dprintf_enable(const char *tag, int level);
-
 void usb_dump_standard_descriptor(FILE *, const char *, const char *,
     const uint8_t *, size_t);
@@ -47,10 +44,36 @@
 /** Logging level. */
 typedef enum {
+	/** Fatal, unrecoverable, error.
+	 * Such error prevents the driver from working at all.
+	 */
 	USB_LOG_LEVEL_FATAL,
+
+	/** Serious but recoverable error
+	 * Shall be used for errors fatal for single device but not for
+	 * driver itself.
+	 */
 	USB_LOG_LEVEL_ERROR,
+
+	/** Warning.
+	 * Problems from which the driver is able to recover gracefully.
+	 */
 	USB_LOG_LEVEL_WARNING,
+
+	/** Information message.
+	 * This should be the last level that is printed by default to
+	 * the screen.
+	 * Typical usage is to inform that new device was found and what
+	 * are its capabilities.
+	 * Do not use for repetitive actions (such as device polling).
+	 */
 	USB_LOG_LEVEL_INFO,
+
+	/** Debugging message. */
 	USB_LOG_LEVEL_DEBUG,
+
+	/** More detailed debugging message. */
 	USB_LOG_LEVEL_DEBUG2,
+
+	/** Terminating constant for logging levels. */
 	USB_LOG_LEVEL_MAX
 } usb_log_level_t;
@@ -61,22 +84,29 @@
 void usb_log_printf(usb_log_level_t, const char *, ...);
 
+/** Log fatal error. */
 #define usb_log_fatal(format, ...) \
 	usb_log_printf(USB_LOG_LEVEL_FATAL, format, ##__VA_ARGS__)
 
+/** Log normal (recoverable) error. */
 #define usb_log_error(format, ...) \
 	usb_log_printf(USB_LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
 
+/** Log warning. */
 #define usb_log_warning(format, ...) \
 	usb_log_printf(USB_LOG_LEVEL_WARNING, format, ##__VA_ARGS__)
 
+/** Log informational message. */
 #define usb_log_info(format, ...) \
 	usb_log_printf(USB_LOG_LEVEL_INFO, format, ##__VA_ARGS__)
 
+/** Log debugging message. */
 #define usb_log_debug(format, ...) \
 	usb_log_printf(USB_LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
 
+/** Log verbose debugging message. */
 #define usb_log_debug2(format, ...) \
 	usb_log_printf(USB_LOG_LEVEL_DEBUG2, format, ##__VA_ARGS__)
 
+const char *usb_debug_str_buffer(const uint8_t *, size_t, size_t);
 
 
Index: uspace/lib/usb/include/usb/descriptor.h
===================================================================
--- uspace/lib/usb/include/usb/descriptor.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/include/usb/descriptor.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief Standard USB descriptors.
+ * Standard USB descriptors.
  */
 #ifndef LIBUSB_DESCRIPTOR_H_
@@ -83,5 +83,5 @@
 	/** Product descriptor index. */
 	uint8_t str_product;
-	/** Device serial number desriptor index. */
+	/** Device serial number descriptor index. */
 	uint8_t str_serial_number;
 	/** Number of possible configurations. */
@@ -167,7 +167,4 @@
 } __attribute__ ((packed)) usb_standard_endpoint_descriptor_t;
 
-
-/* TODO: string descriptors. */
-
 #endif
 /**
Index: uspace/lib/usb/include/usb/dp.h
===================================================================
--- uspace/lib/usb/include/usb/dp.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/include/usb/dp.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief USB descriptor parser.
+ * USB descriptor parser.
  */
 #ifndef LIBUSB_DP_H_
@@ -40,6 +40,15 @@
 #include <usb/descriptor.h>
 
+/** USB descriptors nesting.
+ * The nesting describes the logical tree USB descriptors form
+ * (e.g. that endpoint descriptor belongs to interface or that
+ * interface belongs to configuration).
+ *
+ * See usb_descriptor_type_t for descriptor constants.
+ */
 typedef struct {
+	/** Child descriptor id. */
 	int child;
+	/** Parent descriptor id. */
 	int parent;
 } usb_dp_descriptor_nesting_t;
@@ -47,11 +56,17 @@
 extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[];
 
+/** Descriptor parser structure. */
 typedef struct {
+	/** Used descriptor nesting. */
 	usb_dp_descriptor_nesting_t *nesting;
 } usb_dp_parser_t;
 
+/** Descriptor parser data. */
 typedef struct {
+	/** Data to be parsed. */
 	uint8_t *data;
+	/** Size of input data in bytes. */
 	size_t size;
+	/** Custom argument. */
 	void *arg;
 } usb_dp_parser_data_t;
Index: uspace/lib/usb/include/usb/hub.h
===================================================================
--- uspace/lib/usb/include/usb/hub.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/include/usb/hub.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -32,4 +32,6 @@
 /** @file
  * Functions needed by hub drivers.
+ *
+ * For class specific requests, see usb/classes/hub.h.
  */
 #ifndef LIBUSB_HUB_H_
Index: uspace/lib/usb/include/usb/pipes.h
===================================================================
--- uspace/lib/usb/include/usb/pipes.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/include/usb/pipes.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -43,6 +43,5 @@
 #include <ddf/driver.h>
 
-/**
- * Abstraction of a physical connection to the device.
+/** Abstraction of a physical connection to the device.
  * This type is an abstraction of the USB wire that connects the host and
  * the function (device).
@@ -55,6 +54,5 @@
 } usb_device_connection_t;
 
-/**
- * Abstraction of a logical connection to USB device endpoint.
+/** Abstraction of a logical connection to USB device endpoint.
  * It encapsulates endpoint attributes (transfer type etc.) as well
  * as information about currently running sessions.
@@ -111,5 +109,5 @@
 	/** Found descriptor fitting the description. */
 	usb_standard_endpoint_descriptor_t *descriptor;
-	/** Interface the endpoint belongs to. */
+	/** Interface descriptor the endpoint belongs to. */
 	usb_standard_interface_descriptor_t *interface;
 	/** Whether the endpoint was actually found. */
Index: uspace/lib/usb/include/usb/request.h
===================================================================
--- uspace/lib/usb/include/usb/request.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/include/usb/request.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -72,5 +72,5 @@
 	union {
 		uint16_t value;
-		/* FIXME: add #ifdefs according to host endianess */
+		/* FIXME: add #ifdefs according to host endianness */
 		struct {
 			uint8_t value_low;
@@ -106,4 +106,6 @@
 int usb_request_get_full_configuration_descriptor(usb_endpoint_pipe_t *, int,
     void *, size_t, size_t *);
+int usb_request_get_full_configuration_descriptor_alloc(usb_endpoint_pipe_t *,
+    int, void **, size_t *);
 int usb_request_set_configuration(usb_endpoint_pipe_t *, uint8_t);
 
Index: uspace/lib/usb/include/usb/usb.h
===================================================================
--- uspace/lib/usb/include/usb/usb.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/include/usb/usb.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief Base USB types.
+ * Common USB types and functions.
  */
 #ifndef LIBUSB_USB_H_
@@ -121,4 +121,10 @@
 } usb_target_t;
 
+/** Compare USB targets (addresses and endpoints).
+ *
+ * @param a First target.
+ * @param b Second target.
+ * @return Whether @p a and @p b points to the same pipe on the same device.
+ */
 static inline int usb_target_same(usb_target_t a, usb_target_t b)
 {
Index: uspace/lib/usb/include/usb/usbmem.h
===================================================================
--- uspace/lib/usb/include/usb/usbmem.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ 	(revision )
@@ -1,81 +1,0 @@
-/*
- * Copyright (c) 2011 Matus Dekanek
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef USBMEM_H
-#define	USBMEM_H
-
-
-// group should be changed - this is not usb specific
-/** @addtogroup usb
- * @{
- */
-/** @file definitions of memory management with address translation, used mostly in usb stack
- *
- * USB HCD needs traslation between physical and virtual addresses. These
- * functions implement such functionality. For each allocated virtual address
- * the memory manager gets also it`s physical translation and remembers it.
- * Addresses allocated byt this manager can be therefore translated from and to
- * physical addresses.
- * Typical use:
- * void * address = mman_malloc(some_size);
- * void * physical_address = mman_getPA(address);
- * void * the_same_address = mman_getVA(physical_address);
- * void * null_address = mman_getPA(non_existing_address);
- * mman_free(address);
- * // physical_address, adress and the_same_address are no longer valid here
- *
- *
- * @note Addresses allocated by this memory manager should be as well
- * deallocated byt it.
- *
- */
-
-#include <sys/types.h>
-
-extern void * mman_malloc(
-    size_t size,
-    size_t alignment,
-    unsigned long max_physical_address);
-
-extern void * mman_getVA(void * addr);
-
-extern void * mman_getPA(void * addr);
-
-extern void mman_free(void * addr);
-
-
-
-
-
-
-/** @}
- */
-
-
-#endif	/* USBMEM_H */
-
Index: uspace/lib/usb/src/ddfiface.c
===================================================================
--- uspace/lib/usb/src/ddfiface.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/ddfiface.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -56,5 +56,5 @@
 /** Get host controller handle, interface implementation for hub driver.
  *
- * @param[in] device Device the operation is running on.
+ * @param[in] fun Device function the operation is running on.
  * @param[out] handle Storage for the host controller handle.
  * @return Error code.
@@ -69,5 +69,5 @@
  * a hub driver.
  *
- * @param[in] device Device the operation is running on.
+ * @param[in] fun Device function the operation is running on.
  * @param[out] handle Storage for the host controller handle.
  * @return Error code.
@@ -88,4 +88,6 @@
 	    IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle);
 
+	async_hangup(parent_phone);
+
 	if (rc != EOK) {
 		return rc;
@@ -99,5 +101,5 @@
 /** Get host controller handle, interface implementation for HC driver.
  *
- * @param[in] device Device the operation is running on.
+ * @param[in] fun Device function the operation is running on.
  * @param[out] handle Storage for the host controller handle.
  * @return Always EOK.
@@ -116,5 +118,5 @@
 /** Get USB device address, interface implementation for hub driver.
  *
- * @param[in] device Device the operation is running on.
+ * @param[in] fun Device function the operation is running on.
  * @param[in] handle Devman handle of USB device we want address of.
  * @param[out] address Storage for USB address of device with handle @p handle.
@@ -151,5 +153,5 @@
  * a hub driver.
  *
- * @param[in] device Device the operation is running on.
+ * @param[in] fun Device function the operation is running on.
  * @param[in] handle Devman handle of USB device we want address of.
  * @param[out] address Storage for USB address of device with handle @p handle.
Index: uspace/lib/usb/src/debug.c
===================================================================
--- uspace/lib/usb/src/debug.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/debug.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief Debugging support.
+ * Debugging and logging support.
  */
 #include <adt/list.h>
@@ -40,126 +40,16 @@
 #include <usb/debug.h>
 
-/** Debugging tag. */
-typedef struct {
-	/** Linked list member. */
-	link_t link;
-	/** Tag name.
-	 * We always have a private copy of the name.
-	 */
-	char *tag;
-	/** Enabled level of debugging. */
-	int level;
-} usb_debug_tag_t;
-
-/** Get instance of usb_debug_tag_t from link_t. */
-#define USB_DEBUG_TAG_INSTANCE(iterator) \
-	list_get_instance(iterator, usb_debug_tag_t, link)
-
-/** List of all known tags. */
-static LIST_INITIALIZE(tag_list);
-/** Mutex guard for the list of all tags. */
-static FIBRIL_MUTEX_INITIALIZE(tag_list_guard);
-
 /** Level of logging messages. */
 static usb_log_level_t log_level = USB_LOG_LEVEL_WARNING;
+
 /** Prefix for logging messages. */
 static const char *log_prefix = "usb";
+
 /** Serialization mutex for logging functions. */
 static FIBRIL_MUTEX_INITIALIZE(log_serializer);
+
+/** File where to store the log. */
 static FILE *log_stream = NULL;
 
-/** Find or create new tag with given name.
- *
- * @param tagname Tag name.
- * @return Debug tag structure.
- * @retval NULL Out of memory.
- */
-static usb_debug_tag_t *get_tag(const char *tagname)
-{
-	link_t *link;
-	for (link = tag_list.next; \
-	    link != &tag_list; \
-	    link = link->next) {
-		usb_debug_tag_t *tag = USB_DEBUG_TAG_INSTANCE(link);
-		if (str_cmp(tag->tag, tagname) == 0) {
-			return tag;
-		}
-	}
-
-	/*
-	 * Tag not found, we will create a new one.
-	 */
-	usb_debug_tag_t *new_tag = malloc(sizeof(usb_debug_tag_t));
-	int rc = asprintf(&new_tag->tag, "%s", tagname);
-	if (rc < 0) {
-		free(new_tag);
-		return NULL;
-	}
-	list_initialize(&new_tag->link);
-	new_tag->level = 1;
-
-	/*
-	 * Append it to the end of known tags.
-	 */
-	list_append(&new_tag->link, &tag_list);
-
-	return new_tag;
-}
-
-/** Print debugging information.
- * If the tag is used for the first time, its structures are automatically
- * created and initial verbosity level is set to 1.
- *
- * @param tagname Tag name.
- * @param level Level (verbosity) of the message.
- * @param format Formatting string for printf().
- */
-void usb_dprintf(const char *tagname, int level, const char *format, ...)
-{
-	fibril_mutex_lock(&tag_list_guard);
-	usb_debug_tag_t *tag = get_tag(tagname);
-	if (tag == NULL) {
-		printf("USB debug: FATAL ERROR - failed to create tag.\n");
-		goto leave;
-	}
-
-	if (tag->level < level) {
-		goto leave;
-	}
-
-	va_list args;
-	va_start(args, format);
-
-	printf("[%s:%d]: ", tagname, level);
-	vprintf(format, args);
-
-	va_end(args);
-
-leave:
-	fibril_mutex_unlock(&tag_list_guard);
-}
-
-/** Enable debugging prints for given tag.
- *
- * Setting level to <i>n</i> will cause that only printing messages
- * with level lower or equal to <i>n</i> will be printed.
- *
- * @param tagname Tag name.
- * @param level Enabled level.
- */
-void usb_dprintf_enable(const char *tagname, int level)
-{
-	fibril_mutex_lock(&tag_list_guard);
-	usb_debug_tag_t *tag = get_tag(tagname);
-	if (tag == NULL) {
-		printf("USB debug: FATAL ERROR - failed to create tag.\n");
-		goto leave;
-	}
-
-	tag->level = level;
-
-leave:
-	fibril_mutex_unlock(&tag_list_guard);
-}
 
 /** Enable logging.
@@ -182,5 +72,9 @@
 }
 
-
+/** Get log level name prefix.
+ *
+ * @param level Log level.
+ * @return String prefix for the message.
+ */
 static const char *log_level_name(usb_log_level_t level)
 {
@@ -252,4 +146,115 @@
 }
 
+
+#define REMAINDER_STR_FMT " (%zu)..."
+/* string + terminator + number width (enough for 4GB)*/
+#define REMAINDER_STR_LEN (5 + 1 + 10)
+
+/** How many bytes to group together. */
+#define BUFFER_DUMP_GROUP_SIZE 4
+
+/** Size of the string for buffer dumps. */
+#define BUFFER_DUMP_LEN 240 /* Ought to be enough for everybody ;-). */
+
+/** Fibril local storage for the dumped buffer. */
+static fibril_local char buffer_dump[BUFFER_DUMP_LEN];
+
+/** Dump buffer into string.
+ *
+ * The function dumps given buffer into hexadecimal format and stores it
+ * in a static fibril local string.
+ * That means that you do not have to deallocate the string (actually, you
+ * can not do that) and you do not have to guard it against concurrent
+ * calls to it.
+ * The only limitation is that each call rewrites the buffer again.
+ * Thus, it is necessary to copy the buffer elsewhere (that includes printing
+ * to screen or writing to file).
+ * Since this function is expected to be used for debugging prints only,
+ * that is not a big limitation.
+ *
+ * @warning You cannot use this function twice in the same printf
+ * (see detailed explanation).
+ *
+ * @param buffer Buffer to be printed (can be NULL).
+ * @param size Size of the buffer in bytes (can be zero).
+ * @param dumped_size How many bytes to actually dump (zero means all).
+ * @return Dumped buffer as a static (but fibril local) string.
+ */
+const char *usb_debug_str_buffer(const uint8_t *buffer, size_t size,
+    size_t dumped_size)
+{
+	/*
+	 * Remove previous string (that might also reveal double usage of
+	 * this function).
+	 */
+	bzero(buffer_dump, BUFFER_DUMP_LEN);
+
+	if (buffer == NULL) {
+		return "(null)";
+	}
+	if (size == 0) {
+		return "(empty)";
+	}
+	if ((dumped_size == 0) || (dumped_size > size)) {
+		dumped_size = size;
+	}
+
+	/* How many bytes are available in the output buffer. */
+	size_t buffer_remaining_size = BUFFER_DUMP_LEN - 1 - REMAINDER_STR_LEN;
+	char *it = buffer_dump;
+
+	size_t index = 0;
+
+	while (index < size) {
+		/* Determine space before the number. */
+		const char *space_before;
+		if (index == 0) {
+			space_before = "";
+		} else if ((index % BUFFER_DUMP_GROUP_SIZE) == 0) {
+			space_before = "  ";
+		} else {
+			space_before = " ";
+		}
+
+		/*
+		 * Add the byte as a hexadecimal number plus the space.
+		 * We do it into temporary buffer to ensure that always
+		 * the whole byte is printed.
+		 */
+		int val = buffer[index];
+		char current_byte[16];
+		int printed = snprintf(current_byte, 16,
+		    "%s%02x", space_before, val);
+		if (printed < 0) {
+			break;
+		}
+
+		if ((size_t) printed > buffer_remaining_size) {
+			break;
+		}
+
+		/* We can safely add 1, because space for end 0 is reserved. */
+		str_append(it, buffer_remaining_size + 1, current_byte);
+
+		buffer_remaining_size -= printed;
+		/* Point at the terminator 0. */
+		it += printed;
+		index++;
+
+		if (index >= dumped_size) {
+			break;
+		}
+	}
+
+	/* Add how many bytes were not printed. */
+	if (index < size) {
+		snprintf(it, REMAINDER_STR_LEN,
+		    REMAINDER_STR_FMT, size - index);
+	}
+
+	return buffer_dump;
+}
+
+
 /**
  * @}
Index: uspace/lib/usb/src/dp.c
===================================================================
--- uspace/lib/usb/src/dp.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/dp.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -32,5 +32,12 @@
 /**
  * @file
- * @brief USB descriptor parser (implementation).
+ * USB descriptor parser (implementation).
+ *
+ * The descriptor parser is a generic parser for structure, where individual
+ * items are stored in single buffer and each item begins with length followed
+ * by type. These types are organized into tree hierarchy.
+ *
+ * The parser is able of only two actions: find first child and find next
+ * sibling.
  */
 #include <stdio.h>
Index: uspace/lib/usb/src/dump.c
===================================================================
--- uspace/lib/usb/src/dump.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/dump.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief Descriptor dumping.
+ * Descriptor dumping.
  */
 #include <adt/list.h>
@@ -43,6 +43,9 @@
 #include <usb/classes/hid.h>
 
+/** Mapping between descriptor id and dumping function. */
 typedef struct {
+	/** Descriptor id. */
 	int id;
+	/** Dumping function. */
 	void (*dump)(FILE *, const char *, const char *,
 	    const uint8_t *, size_t);
@@ -66,4 +69,5 @@
     const uint8_t *, size_t);
 
+/** Descriptor dumpers mapping. */
 static descriptor_dump_t descriptor_dumpers[] = {
 	{ USB_DESCTYPE_DEVICE, usb_dump_descriptor_device },
@@ -273,4 +277,5 @@
     const uint8_t *descriptor, size_t descriptor_length)
 {
+	/* TODO */
 }
 
@@ -279,4 +284,5 @@
     const uint8_t *descriptor, size_t descriptor_length)
 {
+	/* TODO */
 }
 
Index: uspace/lib/usb/src/hcdhubd_private.h
===================================================================
--- uspace/lib/usb/src/hcdhubd_private.h	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ 	(revision )
@@ -1,77 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libusb
- * @{
- */
-/** @file
- * @brief Common definitions for both HC driver and hub driver.
- */
-#ifndef LIBUSB_HCDHUBD_PRIVATE_H_
-#define LIBUSB_HCDHUBD_PRIVATE_H_
-
-#define USB_HUB_DEVICE_NAME "usbhub"
-#define USB_KBD_DEVICE_NAME "hid"
-
-extern link_t hc_list;
-extern usb_hc_driver_t *hc_driver;
-
-extern usbhc_iface_t usbhc_interface;
-
-usb_address_t usb_get_address_by_handle(devman_handle_t);
-int usb_add_hc_device(device_t *);
-
-/** lowest allowed usb address */
-extern int usb_lowest_address;
-
-/** highest allowed usb address */
-extern int usb_highest_address;
-
-/**
- * @brief initialize address list of given hcd
- *
- * This function should be used only for hcd initialization.
- * It creates interval list of free addresses, thus it is initialized as
- * list with one interval with whole address space. Using an address shrinks
- * the interval, freeing an address extends an interval or creates a
- * new one. 
- *
- * @param hcd
- * @return
- */
-void  usb_create_address_list(usb_hc_device_t * hcd);
-
-
-
-
-
-
-#endif
-/**
- * @}
- */
Index: uspace/lib/usb/src/hub.c
===================================================================
--- uspace/lib/usb/src/hub.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/hub.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -57,4 +57,5 @@
  *
  * @param connection Opened connection to host controller.
+ * @param speed Speed of the device that will respond on the default address.
  * @return Error code.
  */
@@ -86,4 +87,6 @@
  *
  * @param connection Opened connection to host controller.
+ * @param speed Speed of the new device (device that will be assigned
+ *    the returned address).
  * @return Assigned USB address or negative error code.
  */
@@ -144,5 +147,5 @@
 /** Wrapper for registering attached device to the hub.
  *
- * The @p enable_port function is expected to enable singalling on given
+ * The @p enable_port function is expected to enable signaling on given
  * port.
  * The two arguments to it can have arbitrary meaning
@@ -152,17 +155,22 @@
  *
  * If the @p enable_port fails (i.e. does not return EOK), the device
- * addition is cancelled.
+ * addition is canceled.
  * The return value is then returned (it is good idea to use different
  * error codes than those listed as return codes by this function itself).
  *
- * @param parent Parent device (i.e. the hub device).
- * @param connection Opened connection to host controller.
- * @param dev_speed New device speed.
- * @param enable_port Function for enabling signalling through the port the
+ * @param[in] parent Parent device (i.e. the hub device).
+ * @param[in] connection Opened connection to host controller.
+ * @param[in] dev_speed New device speed.
+ * @param[in] enable_port Function for enabling signaling through the port the
  *	device is attached to.
- * @param port_no Port number (passed through to @p enable_port).
- * @param arg Any data argument to @p enable_port.
+ * @param[in] port_no Port number (passed through to @p enable_port).
+ * @param[in] arg Any data argument to @p enable_port.
  * @param[out] assigned_address USB address of the device.
  * @param[out] assigned_handle Devman handle of the new device.
+ * @param[in] dev_ops Child device ops.
+ * @param[in] new_dev_data Arbitrary pointer to be stored in the child
+ *	as @c driver_data.
+ * @param[out] new_fun Storage where pointer to allocated child function
+ *	will be written.
  * @return Error code.
  * @retval ENOENT Connection to HC not opened.
@@ -201,5 +209,5 @@
 
 	/*
-	 * Enable the port (i.e. allow signalling through this port).
+	 * Enable the port (i.e. allow signaling through this port).
 	 */
 	rc = enable_port(port_no, arg);
Index: uspace/lib/usb/src/pipes.c
===================================================================
--- uspace/lib/usb/src/pipes.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/pipes.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -99,5 +99,5 @@
  *
  * @param connection Connection structure to be initialized.
- * @param device Generic device backing the USB device.
+ * @param dev Generic device backing the USB device.
  * @return Error code.
  */
Index: uspace/lib/usb/src/pipesio.c
===================================================================
--- uspace/lib/usb/src/pipesio.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/pipesio.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -115,5 +115,10 @@
 
 	if (data_request_rc != EOK) {
-		return (int) data_request_rc;
+		/* Prefer the 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) {
@@ -331,5 +336,10 @@
 
 	if (data_request_rc != EOK) {
-		return (int) data_request_rc;
+		/* Prefer the 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) {
Index: uspace/lib/usb/src/recognise.c
===================================================================
--- uspace/lib/usb/src/recognise.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/recognise.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief Functions for recognising kind of attached devices.
+ * Functions for recognition of attached devices.
  */
 #include <sys/types.h>
@@ -44,15 +44,22 @@
 #include <assert.h>
 
+/** Index to append after device name for uniqueness. */
 static size_t device_name_index = 0;
+/** Mutex guard for device_name_index. */
 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex);
 
+/** DDF operations of child devices. */
 ddf_dev_ops_t child_ops = {
 	.interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
 };
 
+/** Get integer part from BCD coded number. */
 #define BCD_INT(a) (((unsigned int)(a)) / 256)
+/** Get fraction part from BCD coded number (as an integer, no less). */
 #define BCD_FRAC(a) (((unsigned int)(a)) % 256)
 
+/** Format for BCD coded number to be used in printf. */
 #define BCD_FMT "%x.%x"
+/** Arguments to printf for BCD coded number. */
 #define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
 
@@ -113,4 +120,11 @@
 }
 
+/** Add match id to list or return with error code.
+ *
+ * @param match_ids List of match ids.
+ * @param score Match id score.
+ * @param format Format of the matching string
+ * @param ... Arguments for the format.
+ */
 #define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \
 	do { \
@@ -124,9 +138,10 @@
 /** Create device match ids based on its interface.
  *
- * @param[in] descriptor Interface descriptor.
+ * @param[in] desc_device Device descriptor.
+ * @param[in] desc_interface Interface descriptor.
  * @param[out] matches Initialized list of match ids.
  * @return Error code (the two mentioned are not the only ones).
  * @retval EINVAL Invalid input parameters (expects non NULL pointers).
- * @retval ENOENT Interface does not specify class.
+ * @retval ENOENT Device class is not "use interface".
  */
 int usb_device_create_match_ids_from_interface(
@@ -319,4 +334,9 @@
  * @param[in] parent Parent device.
  * @param[out] child_handle Handle of the child device.
+ * @param[in] dev_ops Child device ops.
+ * @param[in] dev_data Arbitrary pointer to be stored in the child
+ *	as @c driver_data.
+ * @param[out] child_fun Storage where pointer to allocated child function
+ *	will be written.
  * @return Error code.
  */
Index: uspace/lib/usb/src/request.c
===================================================================
--- uspace/lib/usb/src/request.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/request.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -110,5 +110,5 @@
   *	(must be in USB endianness).
   * @param data Buffer where to store data accepted during the DATA stage.
-  *	(they will come in USB endianess).
+  *	(they will come in USB endianness).
   * @param data_size Size of the @p data buffer
   * 	(in native endianness).
@@ -161,10 +161,4 @@
  * the new address.
  *
- * @see usb_drv_reserve_default_address
- * @see usb_drv_release_default_address
- * @see usb_drv_request_address
- * @see usb_drv_release_address
- * @see usb_drv_bind_address
- *
  * @param pipe Control endpoint pipe (session must be already started).
  * @param new_address New USB address to be set (in native endianness).
@@ -201,4 +195,5 @@
  * @param[in] pipe Control endpoint pipe (session must be already started).
  * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Request recipient (device/interface/endpoint).
  * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
  * @param[in] descriptor_index Descriptor index.
@@ -235,4 +230,5 @@
  * @param[in] pipe Control endpoint pipe (session must be already started).
  * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Request recipient (device/interface/endpoint).
  * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
  * @param[in] descriptor_index Descriptor index.
@@ -412,4 +408,69 @@
 }
 
+/** Retrieve full configuration descriptor, allocate space for it.
+ *
+ * The function takes care that full configuration descriptor is returned
+ * (i.e. the function will fail when less data then descriptor.totalLength
+ * is returned).
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] index Configuration index.
+ * @param[out] descriptor_ptr Where to store pointer to allocated buffer.
+ * @param[out] descriptor_size Where to store the size of the descriptor.
+ * @return Error code.
+ */
+int usb_request_get_full_configuration_descriptor_alloc(
+    usb_endpoint_pipe_t *pipe, int index,
+    void **descriptor_ptr, size_t *descriptor_size)
+{
+	int rc;
+
+	if (descriptor_ptr == NULL) {
+		return EBADMEM;
+	}
+
+	usb_standard_configuration_descriptor_t bare_config;
+	rc = usb_request_get_bare_configuration_descriptor(pipe, index,
+	    &bare_config);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (bare_config.descriptor_type != USB_DESCTYPE_CONFIGURATION) {
+		return ENOENT;
+	}
+	if (bare_config.total_length < sizeof(bare_config)) {
+		return ELIMIT;
+	}
+
+	void *buffer = malloc(bare_config.total_length);
+	if (buffer == NULL) {
+		return ENOMEM;
+	}
+
+	size_t transferred = 0;
+	rc = usb_request_get_full_configuration_descriptor(pipe, index,
+	    buffer, bare_config.total_length, &transferred);
+	if (rc != EOK) {
+		free(buffer);
+		return rc;
+	}
+
+	if (transferred != bare_config.total_length) {
+		free(buffer);
+		return ELIMIT;
+	}
+
+	/* Everything looks okay, copy the pointers. */
+
+	*descriptor_ptr = buffer;
+
+	if (descriptor_size != NULL) {
+		*descriptor_size = bare_config.total_length;
+	}
+
+	return EOK;
+}
+
 /** Set configuration of USB device.
  *
@@ -463,5 +524,5 @@
 		return EEMPTY;
 	}
-	/* Substract first 2 bytes (length and descriptor type). */
+	/* Subtract first 2 bytes (length and descriptor type). */
 	string_descriptor_size -= 2;
 
@@ -483,5 +544,5 @@
 	size_t i;
 	for (i = 0; i < langs_count; i++) {
-		/* Language code from the descriptor is in USB endianess. */
+		/* Language code from the descriptor is in USB endianness. */
 		/* FIXME: is this really correct? */
 		uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
@@ -504,6 +565,7 @@
  *
  * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] index String index (in native endianess).
- * @param[in] lang String language (in native endianess).
+ * @param[in] index String index (in native endianness),
+ *	first index has number 1 (index from descriptors can be used directly).
+ * @param[in] lang String language (in native endianness).
  * @param[out] string_ptr Where to store allocated string in native encoding.
  * @return Error code.
@@ -515,6 +577,9 @@
 		return EBADMEM;
 	}
-	/* Index is actually one byte value. */
-	if (index > 0xFF) {
+	/*
+	 * Index is actually one byte value and zero index is used
+	 * to retrieve list of supported languages.
+	 */
+	if ((index < 1) || (index > 0xFF)) {
 		return ERANGE;
 	}
@@ -544,5 +609,5 @@
 		goto leave;
 	}
-	/* Substract first 2 bytes (length and descriptor type). */
+	/* Subtract first 2 bytes (length and descriptor type). */
 	string_size -= 2;
 
Index: uspace/lib/usb/src/usb.c
===================================================================
--- uspace/lib/usb/src/usb.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ uspace/lib/usb/src/usb.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief Base USB types.
+ * Common USB functions.
  */
 #include <usb/usb.h>
@@ -37,5 +37,9 @@
 
 
-/** String representation for USB transfer type. */
+/** String representation for USB transfer type.
+ *
+ * @param t Transfer type.
+ * @return Transfer type as a string (in English).
+ */
 const char * usb_str_transfer_type(usb_transfer_type_t t)
 {
Index: uspace/lib/usb/src/usbmem.c
===================================================================
--- uspace/lib/usb/src/usbmem.c	(revision 60a228fd7f87439364d5a1c15b71834ad60945c0)
+++ 	(revision )
@@ -1,201 +1,0 @@
-/*
- * Copyright (c) 2011 Matus Dekanek
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file implementation of special memory management, used mostly in usb stack
- */
-
-#include <adt/hash_table.h>
-#include <adt/list.h>
-#include <as.h>
-#include <errno.h>
-#include <malloc.h>
-
-#include "usb/usbmem.h"
-
-#define ADDR_BUCKETS 1537
-
-//address translation tables
-static hash_table_t * pa2va_table = NULL;
-static hash_table_t * va2pa_table = NULL;
-
-/**
- * address translation hashtable item
- */
-typedef struct{
-	unsigned long addr;
-	unsigned long translation;
-	link_t link;
-
-}addr_node_t;
-
-static hash_index_t addr_hash(unsigned long key[])
-{
-	return (3*key[0]<<4) % ADDR_BUCKETS;
-}
-
-static int addr_compare(unsigned long key[], hash_count_t keys,
-    link_t *item)
-{
-	addr_node_t *addr_node = hash_table_get_instance(item, addr_node_t, link);
-	return (addr_node->addr == key[0]);
-}
-
-static void addr_remove_callback(link_t * item)
-{
-	//delete item
-	addr_node_t *addr_node = hash_table_get_instance(item, addr_node_t, link);
-	free(addr_node);
-}
-
-
-static hash_table_operations_t addr_devices_ops = {
-	.hash = addr_hash,
-	.compare = addr_compare,
-	.remove_callback = addr_remove_callback
-};
-
-/**
- * create node for address translation hashtable
- * @param addr
- * @param translation
- * @return
- */
-static addr_node_t * create_addr_node(void * addr, void * translation){
-	addr_node_t * node = (addr_node_t*)malloc(sizeof(addr_node_t));
-	node->addr = (unsigned long)addr;
-	node->translation = (unsigned long)translation;
-	return node;
-}
-
-/**
- * allocate size on heap and register it`s pa<->va translation
- *
- * If physical address + size is 2GB or higher, nothing is allocated and NULL
- * is returned.
- * @param size
- * @param alignment
- * @return
- */
-void * mman_malloc(
-	size_t size,
-	size_t alignment,
-	unsigned long max_physical_address)
-{
-	if (size == 0)
-		return NULL;
-	if (alignment == 0)
-		return NULL;
-	//check if tables were initialized
-	if(!pa2va_table){
-		pa2va_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
-		va2pa_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
-		hash_table_create(pa2va_table, ADDR_BUCKETS, 1,
-		    &addr_devices_ops);
-		hash_table_create(va2pa_table, ADDR_BUCKETS, 1,
-		    &addr_devices_ops);
-	}
-	//allocate
-	void * vaddr = memalign(alignment, size);
-	
-	//get translation
-	void * paddr = NULL;
-	int opResult = as_get_physical_mapping(vaddr,(uintptr_t*)&paddr);
-	if(opResult != EOK){
-		//something went wrong
-		free(vaddr);
-		return NULL;
-	}
-	if((unsigned long)paddr + size > max_physical_address){
-		//unusable address for usb
-		free(vaddr);
-		return NULL;
-	}
-	//store translation
-	addr_node_t * pa2vaNode = create_addr_node(paddr,vaddr);
-	addr_node_t * va2paNode = create_addr_node(vaddr,paddr);
-
-	unsigned long keypaddr = (unsigned long)paddr;
-	unsigned long keyvaddr = (unsigned long)vaddr;
-	hash_table_insert(pa2va_table, (&keypaddr), &pa2vaNode->link);
-	hash_table_insert(va2pa_table, (&keyvaddr), &va2paNode->link);
-	//return
-	return vaddr;
-
-}
-
-/**
- * get virtual address from physical
- * @param addr
- * @return translated virtual address or null
- */
-void * mman_getVA(void * addr){
-	unsigned long keypaddr = (unsigned long)addr;
-	link_t * link = hash_table_find(pa2va_table, &keypaddr);
-	if(!link) return NULL;
-	addr_node_t * node = hash_table_get_instance(link, addr_node_t, link);
-	return (void*)node->translation;
-}
-
-/**
- * get physical address from virtual
- * @param addr
- * @return physical address or null
- */
-void * mman_getPA(void * addr){
-	unsigned long keyvaddr = (unsigned long)addr;
-	link_t * link = hash_table_find(va2pa_table, &keyvaddr);
-	if(!link) return NULL;
-	addr_node_t * node = hash_table_get_instance(link, addr_node_t, link);
-	return (void*)node->translation;
-}
-
-/**
- * free the address and deregister it from pa<->va translation
- * @param vaddr if NULL, nothing happens
- */
-void mman_free(void * vaddr){
-	if(!vaddr)
-		return;
-	//get paddress
-	void * paddr = mman_getPA(vaddr);
-	unsigned long keypaddr = (unsigned long)paddr;
-	unsigned long keyvaddr = (unsigned long)vaddr;
-	//remove mapping
-	hash_table_remove(pa2va_table,&keypaddr, 1);
-	hash_table_remove(va2pa_table,&keyvaddr, 1);
-	//free address
-	free(vaddr);
-}
-
-
-
-/** @}
- */
