Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 241608526d1512eb2560c3f5334e71180744c043)
+++ uspace/lib/c/Makefile	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -101,4 +101,5 @@
 	generic/io/printf.c \
 	generic/io/log.c \
+	generic/io/logctl.c \
 	generic/io/klog.c \
 	generic/io/snprintf.c \
Index: uspace/lib/c/generic/io/log.c
===================================================================
--- uspace/lib/c/generic/io/log.c	(revision 241608526d1512eb2560c3f5334e71180744c043)
+++ uspace/lib/c/generic/io/log.c	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -38,58 +38,190 @@
 #include <stdlib.h>
 #include <stdio.h>
-
+#include <async.h>
 #include <io/log.h>
-
-/** Serialization mutex for logging functions. */
-static FIBRIL_MUTEX_INITIALIZE(log_serializer);
-
-/** Current log level. */
-static log_level_t log_level;
-
-static FILE *log_stream;
-
+#include <ipc/logger.h>
+#include <ns.h>
+
+/** Id of the first log we create at logger. */
+static sysarg_t default_log_id;
+
+/** Log messages are printed under this name. */
 static const char *log_prog_name;
 
-/** Prefixes for individual logging levels. */
+/** Names of individual log levels. */
 static const char *log_level_names[] = {
-	[LVL_FATAL] = "Fatal error",
-	[LVL_ERROR] = "Error",
-	[LVL_WARN] = "Warning",
-	[LVL_NOTE] = "Note",
-	[LVL_DEBUG] = "Debug",
-	[LVL_DEBUG2] = "Debug2"
+	"fatal",
+	"error",
+	"warn",
+	"note",
+	"debug",
+	"debug2",
+	NULL
 };
 
+/** IPC session with the logger service. */
+static async_sess_t *logger_session;
+
+/** Maximum length of a single log message (in bytes). */
+#define MESSAGE_BUFFER_SIZE 4096
+
+/** Send formatted message to the logger service.
+ *
+ * @param session Initialized IPC session with the logger.
+ * @param log Log to use.
+ * @param level Verbosity level of the message.
+ * @param message The actual message.
+ * @return Error code of the conversion or EOK on success.
+ */
+static int logger_message(async_sess_t *session, log_t log, log_level_t level, char *message)
+{
+	async_exch_t *exchange = async_exchange_begin(session);
+	if (exchange == NULL) {
+		return ENOMEM;
+	}
+	if (log == LOG_DEFAULT)
+		log = default_log_id;
+
+	// FIXME: remove when all USB drivers use libc logging explicitly
+	str_rtrim(message, '\n');
+
+	aid_t reg_msg = async_send_2(exchange, LOGGER_WRITER_MESSAGE,
+	    log, level, NULL);
+	int rc = async_data_write_start(exchange, message, str_size(message));
+	sysarg_t reg_msg_rc;
+	async_wait_for(reg_msg, &reg_msg_rc);
+
+	async_exchange_end(exchange);
+
+	/*
+	 * Getting ENAK means no-one wants our message. That is not an
+	 * error at all.
+	 */
+	if (rc == ENAK)
+		rc = EOK;
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	return reg_msg_rc;
+}
+
+/** Get name of the log level.
+ *
+ * @param level The log level.
+ * @return String name or "unknown".
+ */
+const char *log_level_str(log_level_t level)
+{
+	if (level >= LVL_LIMIT)
+		return "unknown";
+	else
+		return log_level_names[level];
+}
+
+/** Convert log level name to the enum.
+ *
+ * @param[in] name Log level name or log level number.
+ * @param[out] level_out Where to store the result (set to NULL to ignore).
+ * @return Error code of the conversion or EOK on success.
+ */
+int log_level_from_str(const char *name, log_level_t *level_out)
+{
+	log_level_t level = LVL_FATAL;
+
+	while (log_level_names[level] != NULL) {
+		if (str_cmp(name, log_level_names[level]) == 0) {
+			if (level_out != NULL)
+				*level_out = level;
+			return EOK;
+		}
+		level++;
+	}
+
+	/* Maybe user specified number directly. */
+	char *end_ptr;
+	int level_int = strtol(name, &end_ptr, 0);
+	if ((end_ptr == name) || (str_length(end_ptr) != 0))
+		return EINVAL;
+	if (level_int < 0)
+		return ERANGE;
+	if (level_int >= (int) LVL_LIMIT)
+		return ERANGE;
+
+	if (level_out != NULL)
+		*level_out = (log_level_t) level_int;
+
+	return EOK;
+}
+
 /** Initialize the logging system.
  *
- * @param prog_name	Program name, will be printed as part of message
- * @param level		Minimum message level to print
- */
-int log_init(const char *prog_name, log_level_t level)
-{
-	assert(level < LVL_LIMIT);
-	log_level = level;
-
-	log_stream = stdout;
+ * @param prog_name Program name, will be printed as part of message
+ */
+int log_init(const char *prog_name)
+{
 	log_prog_name = str_dup(prog_name);
 	if (log_prog_name == NULL)
 		return ENOMEM;
 
+	logger_session = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOGGER, LOGGER_INTERFACE_WRITER, 0);
+	if (logger_session == NULL) {
+		return ENOMEM;
+	}
+
+	default_log_id = log_create(prog_name, LOG_NO_PARENT);
+
 	return EOK;
 }
 
+/** Create a new (sub-) log.
+ *
+ * This function always returns a valid log_t. In case of errors,
+ * @c parent is returned and errors are silently ignored.
+ *
+ * @param name Log name under which message will be reported (appended to parents name).
+ * @param parent Parent log.
+ * @return Opaque identifier of the newly created log.
+ */
+log_t log_create(const char *name, log_t parent)
+{
+	async_exch_t *exchange = async_exchange_begin(logger_session);
+	if (exchange == NULL)
+		return parent;
+
+	if (parent == LOG_DEFAULT)
+		parent = default_log_id;
+
+	ipc_call_t answer;
+	aid_t reg_msg = async_send_1(exchange, LOGGER_WRITER_CREATE_LOG,
+	    parent, &answer);
+	int rc = async_data_write_start(exchange, name, str_size(name));
+	sysarg_t reg_msg_rc;
+	async_wait_for(reg_msg, &reg_msg_rc);
+
+	async_exchange_end(exchange);
+
+	if ((rc != EOK) || (reg_msg_rc != EOK))
+		return parent;
+
+	return IPC_GET_ARG1(answer);
+}
+
 /** Write an entry to the log.
  *
- * @param level		Message verbosity level. Message is only printed
- *			if verbosity is less than or equal to current
- *			reporting level.
- * @param fmt		Format string (no traling newline).
- */
-void log_msg(log_level_t level, const char *fmt, ...)
+ * The message is printed only if the verbosity level is less than or
+ * equal to currently set reporting level of the log.
+ *
+ * @param ctx Log to use (use LOG_DEFAULT if you have no idea what it means).
+ * @param level Severity level of the message.
+ * @param fmt Format string in printf-like format (without trailing newline).
+ */
+void log_msg(log_t ctx, log_level_t level, const char *fmt, ...)
 {
 	va_list args;
 
 	va_start(args, fmt);
-	log_msgv(level, fmt, args);
+	log_msgv(ctx, level, fmt, args);
 	va_end(args);
 }
@@ -97,25 +229,20 @@
 /** Write an entry to the log (va_list variant).
  *
- * @param level		Message verbosity level. Message is only printed
- *			if verbosity is less than or equal to current
- *			reporting level.
- * @param fmt		Format string (no trailing newline)
- */
-void log_msgv(log_level_t level, const char *fmt, va_list args)
+ * @param ctx Log to use (use LOG_DEFAULT if you have no idea what it means).
+ * @param level Severity level of the message.
+ * @param fmt Format string in printf-like format (without trailing newline).
+ * @param args Arguments.
+ */
+void log_msgv(log_t ctx, log_level_t level, const char *fmt, va_list args)
 {
 	assert(level < LVL_LIMIT);
 
-	/* Higher number means higher verbosity. */
-	if (level <= log_level) {
-		fibril_mutex_lock(&log_serializer);
-
-		fprintf(log_stream, "%s: %s: ", log_prog_name,
-		    log_level_names[level]);
-		vfprintf(log_stream, fmt, args);
-		fputc('\n', log_stream);
-		fflush(log_stream);
-
-		fibril_mutex_unlock(&log_serializer);
-	}
+	char *message_buffer = malloc(MESSAGE_BUFFER_SIZE);
+	if (message_buffer == NULL) {
+		return;
+	}
+
+	vsnprintf(message_buffer, MESSAGE_BUFFER_SIZE, fmt, args);
+	logger_message(logger_session, ctx, level, message_buffer);
 }
 
Index: uspace/lib/c/generic/io/logctl.c
===================================================================
--- uspace/lib/c/generic/io/logctl.c	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
+++ uspace/lib/c/generic/io/logctl.c	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012 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 libc
+ * @{
+ */
+
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+#include <io/logctl.h>
+#include <ipc/logger.h>
+#include <sysinfo.h>
+#include <ns.h>
+#include <str.h>
+
+/** IPC session with the logger service. */
+static async_sess_t *logger_session = NULL;
+
+static int start_logger_exchange(async_exch_t **exchange_out)
+{
+	assert(exchange_out != NULL);
+
+	if (logger_session == NULL) {
+		logger_session = service_connect_blocking(EXCHANGE_SERIALIZE,
+		    SERVICE_LOGGER, LOGGER_INTERFACE_CONTROL, 0);
+		if (logger_session == NULL)
+			return ENOMEM;
+	}
+
+	assert(logger_session != NULL);
+
+	async_exch_t *exchange = async_exchange_begin(logger_session);
+	if (exchange == NULL)
+		return ENOMEM;
+
+	*exchange_out = exchange;
+
+	return EOK;
+}
+
+/** Set default reported log level (global setting).
+ *
+ * This setting affects all logger clients whose reporting level was
+ * not yet changed.
+ *
+ * If logging level of client A is changed with logctl_set_log_level()
+ * to some level, this call will have no effect at that client's reporting
+ * level. Even if the actual value of the reporting level of client A is
+ * the same as current (previous) default log level.
+ *
+ * @param new_level New reported logging level.
+ * @return Error code of the conversion or EOK on success.
+ */
+int logctl_set_default_level(log_level_t new_level)
+{
+	async_exch_t *exchange = NULL;
+	int rc = start_logger_exchange(&exchange);
+	if (rc != EOK)
+		return rc;
+
+	rc = (int) async_req_1_0(exchange,
+	    LOGGER_CONTROL_SET_DEFAULT_LEVEL, new_level);
+
+	async_exchange_end(exchange);
+
+	return rc;
+}
+
+/** Set reported log level of a single log.
+ *
+ * @see logctl_set_default_level
+ *
+ * @param logname Log name.
+ * @param new_level New reported logging level.
+ * @return Error code of the conversion or EOK on success.
+ */
+int logctl_set_log_level(const char *logname, log_level_t new_level)
+{
+	async_exch_t *exchange = NULL;
+	int rc = start_logger_exchange(&exchange);
+	if (rc != EOK)
+		return rc;
+
+	aid_t reg_msg = async_send_1(exchange, LOGGER_CONTROL_SET_LOG_LEVEL,
+	    new_level, NULL);
+	rc = async_data_write_start(exchange, logname, str_size(logname));
+	sysarg_t reg_msg_rc;
+	async_wait_for(reg_msg, &reg_msg_rc);
+
+	async_exchange_end(exchange);
+
+	if (rc != EOK)
+		return rc;
+
+	return (int) reg_msg_rc;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/io/log.h
===================================================================
--- uspace/lib/c/include/io/log.h	(revision 241608526d1512eb2560c3f5334e71180744c043)
+++ uspace/lib/c/include/io/log.h	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -36,12 +36,20 @@
 
 #include <stdarg.h>
+#include <inttypes.h>
 #include <io/verify.h>
 
+/** Log message level. */
 typedef enum {
+	/** Fatal error, program is not able to recover at all. */
 	LVL_FATAL,
+	/** Serious error but the program can recover from it. */
 	LVL_ERROR,
+	/** Easily recoverable problem. */
 	LVL_WARN,
+	/** Information message that ought to be printed by default. */
 	LVL_NOTE,
+	/** Debugging purpose message. */
 	LVL_DEBUG,
+	/** More detailed debugging message. */
 	LVL_DEBUG2,
 	
@@ -50,8 +58,24 @@
 } log_level_t;
 
-extern int log_init(const char *, log_level_t);
-extern void log_msg(log_level_t, const char *, ...)
-    PRINTF_ATTRIBUTE(2, 3);
-extern void log_msgv(log_level_t, const char *, va_list);
+/** Log itself (logging target). */
+typedef sysarg_t log_t;
+/** Formatting directive for printing log_t. */
+#define PRIlogctx PRIxn
+
+/** Default log (target). */
+#define LOG_DEFAULT ((log_t) -1)
+
+/** Use when creating new top-level log. */
+#define LOG_NO_PARENT ((log_t) 0)
+
+extern const char *log_level_str(log_level_t);
+extern int log_level_from_str(const char *, log_level_t *);
+
+extern int log_init(const char *);
+extern log_t log_create(const char *, log_t);
+
+extern void log_msg(log_t, log_level_t, const char *, ...)
+    PRINTF_ATTRIBUTE(3, 4);
+extern void log_msgv(log_t, log_level_t, const char *, va_list);
 
 #endif
Index: uspace/lib/c/include/io/logctl.h
===================================================================
--- uspace/lib/c/include/io/logctl.h	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
+++ uspace/lib/c/include/io/logctl.h	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011-2012 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 libc
+ * @{
+ */
+
+#ifndef LIBC_IO_LOGCTL_H_
+#define LIBC_IO_LOGCTL_H_
+
+#include <io/log.h>
+
+extern int logctl_set_default_level(log_level_t);
+extern int logctl_set_log_level(const char *, log_level_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/logger.h
===================================================================
--- uspace/lib/c/include/ipc/logger.h	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
+++ uspace/lib/c/include/ipc/logger.h	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012 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 libc
+ * @{
+ */
+
+#ifndef LIBC_IPC_LOGGER_H_
+#define LIBC_IPC_LOGGER_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	/** Set (global) default displayed logging level.
+	 *
+	 * Arguments: new log level.
+	 * Returns: error code
+	 */
+	LOGGER_CONTROL_SET_DEFAULT_LEVEL = IPC_FIRST_USER_METHOD,
+	/** Set displayed level for given log.
+	 *
+	 * Arguments: new log level.
+	 * Returns: error code
+	 * Followed by: string with full log name.
+	 */
+	LOGGER_CONTROL_SET_LOG_LEVEL
+} logger_control_request_t;
+
+typedef enum {
+	/** Create new log.
+	 *
+	 * Arguments: parent log id (0 for top-level log).
+	 * Returns: error code, log id
+	 * Followed by: string with log name.
+	 */
+	LOGGER_WRITER_CREATE_LOG = IPC_FIRST_USER_METHOD,
+	/** Write a message to a given log.
+	 *
+	 * Arguments: log id, message severity level (log_level_t)
+	 * Returns: error code
+	 * Followed by: string with the message.
+	 */
+	LOGGER_WRITER_MESSAGE
+} logger_writer_request_t;
+
+typedef enum {
+	/** Interface for controlling logger behavior. */
+	LOGGER_INTERFACE_CONTROL,
+	/** Interface for servers writing to the log. */
+	LOGGER_INTERFACE_WRITER
+} logger_interface_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision 241608526d1512eb2560c3f5334e71180744c043)
+++ uspace/lib/c/include/ipc/services.h	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -45,4 +45,5 @@
 	SERVICE_VFS        = FOURCC('v', 'f', 's', ' '),
 	SERVICE_LOC        = FOURCC('l', 'o', 'c', ' '),
+	SERVICE_LOGGER     = FOURCC('l', 'o', 'g', 'g'),
 	SERVICE_DEVMAN     = FOURCC('d', 'e', 'v', 'n'),
 	SERVICE_IRC        = FOURCC('i', 'r', 'c', ' '),
Index: uspace/lib/drv/generic/log.c
===================================================================
--- uspace/lib/drv/generic/log.c	(revision 241608526d1512eb2560c3f5334e71180744c043)
+++ uspace/lib/drv/generic/log.c	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -38,10 +38,9 @@
  *
  * @param drv_name Driver name, will be printed as part of message
- * @param level    Minimum message level to print
  *
  */
-int ddf_log_init(const char *drv_name, log_level_t level)
+int ddf_log_init(const char *drv_name)
 {
-	return log_init(drv_name, level);
+	return log_init(drv_name);
 }
 
@@ -59,5 +58,5 @@
 	
 	va_start(args, fmt);
-	log_msgv(level, fmt, args);
+	log_msgv(LOG_DEFAULT, level, fmt, args);
 	va_end(args);
 }
Index: uspace/lib/drv/include/ddf/log.h
===================================================================
--- uspace/lib/drv/include/ddf/log.h	(revision 241608526d1512eb2560c3f5334e71180744c043)
+++ uspace/lib/drv/include/ddf/log.h	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -37,5 +37,5 @@
 #include <io/verify.h>
 
-extern int ddf_log_init(const char *, log_level_t);
+extern int ddf_log_init(const char *);
 extern void ddf_msg(log_level_t, const char *, ...)
     PRINTF_ATTRIBUTE(2, 3);
Index: uspace/lib/usb/include/usb/debug.h
===================================================================
--- uspace/lib/usb/include/usb/debug.h	(revision 241608526d1512eb2560c3f5334e71180744c043)
+++ uspace/lib/usb/include/usb/debug.h	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -38,4 +38,5 @@
 #include <inttypes.h>
 #include <usb/usb.h>
+#include <io/log.h>
 #include <assert.h>
 
@@ -43,52 +44,13 @@
     const uint8_t *, size_t);
 
-/** Logging level. */
-typedef enum {
-	/** Fatal, unrecoverable, error.
-	 * Such error prevents the driver from working at all.
-	 */
-	USB_LOG_LEVEL_FATAL,
+#define USB_LOG_LEVEL_FATAL LVL_FATAL
+#define USB_LOG_LEVEL_ERROR LVL_ERROR
+#define USB_LOG_LEVEL_WARNING LVL_WARN
+#define USB_LOG_LEVEL_INFO LVL_NOTE
+#define USB_LOG_LEVEL_DEBUG LVL_DEBUG
+#define USB_LOG_LEVEL_DEBUG2 LVL_DEBUG2
 
-	/** 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;
-
-/** Default log level. */
-#ifdef CONFIG_USB_VERBOSE
-	#define USB_LOG_LEVEL_DEFAULT USB_LOG_LEVEL_DEBUG
-#else
-	#define USB_LOG_LEVEL_DEFAULT USB_LOG_LEVEL_INFO
-#endif
-
-void usb_log_enable(usb_log_level_t, const char *);
-
-void usb_log_printf(usb_log_level_t, const char *, ...)
-	PRINTF_ATTRIBUTE(2, 3);
+#define usb_log_printf(level, format, ...) \
+	log_msg(LOG_DEFAULT, level, format, ##__VA_ARGS__)
 
 /** Log fatal error. */
Index: uspace/lib/usb/src/debug.c
===================================================================
--- uspace/lib/usb/src/debug.c	(revision 241608526d1512eb2560c3f5334e71180744c043)
+++ uspace/lib/usb/src/debug.c	(revision 54a00703af50587df45bbb8f85be4f05097154f1)
@@ -40,115 +40,4 @@
 #include <ddf/log.h>
 #include <usb/debug.h>
-
-/** 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;
-
-
-/** Enable logging.
- *
- * @param level Maximal enabled level (including this one).
- * @param message_prefix Prefix for each printed message.
- */
-void usb_log_enable(usb_log_level_t level, const char *message_prefix)
-{
-	log_prefix = message_prefix;
-	log_level = level;
-	if (log_stream == NULL) {
-		char *fname;
-		int rc = asprintf(&fname, "/log/%s", message_prefix);
-		if (rc > 0) {
-			log_stream = fopen(fname, "w");
-			if (log_stream != NULL)
-				setvbuf(log_stream, NULL, _IOFBF, BUFSIZ);
-			
-			free(fname);
-		}
-	}
-}
-
-/** 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)
-{
-	switch (level) {
-		case USB_LOG_LEVEL_FATAL:
-			return " FATAL";
-		case USB_LOG_LEVEL_ERROR:
-			return " ERROR";
-		case USB_LOG_LEVEL_WARNING:
-			return " WARN";
-		case USB_LOG_LEVEL_INFO:
-			return " info";
-		default:
-			return "";
-	}
-}
-
-/** Print logging message.
- *
- * @param level Verbosity level of the message.
- * @param format Formatting directive.
- */
-void usb_log_printf(usb_log_level_t level, const char *format, ...)
-{
-	FILE *screen_stream = NULL;
-	switch (level) {
-		case USB_LOG_LEVEL_FATAL:
-		case USB_LOG_LEVEL_ERROR:
-			screen_stream = stderr;
-			break;
-		default:
-			screen_stream = stdout;
-			break;
-	}
-	assert(screen_stream != NULL);
-
-	va_list args;
-
-	/*
-	 * Serialize access to log files.
-	 * Print to screen only messages with higher level than the one
-	 * specified during logging initialization.
-	 * Print also to file, to it print one more (lower) level as well.
-	 */
-	fibril_mutex_lock(&log_serializer);
-
-	const char *level_name = log_level_name(level);
-
-	if ((log_stream != NULL) && (level <= log_level + 1)) {
-		va_start(args, format);
-
-		fprintf(log_stream, "[%s]%s: ", log_prefix, level_name);
-		vfprintf(log_stream, format, args);
-		fflush(log_stream);
-
-		va_end(args);
-	}
-
-	if (level <= log_level) {
-		va_start(args, format);
-
-		fprintf(screen_stream, "[%s]%s: ", log_prefix, level_name);
-		vfprintf(screen_stream, format, args);
-		fflush(screen_stream);
-
-		va_end(args);
-	}
-
-	fibril_mutex_unlock(&log_serializer);
-}
-
 
 #define REMAINDER_STR_FMT " (%zu)..."
