Index: uspace/lib/usb/include/usb/debug.h
===================================================================
--- uspace/lib/usb/include/usb/debug.h	(revision 1879a7de2821a2ed5d8b048b5d94f0e6896b5536)
+++ uspace/lib/usb/include/usb/debug.h	(revision 0b314096809e841d815b7cedeaf1988722db8c0e)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2010 Vojtech Horky
+ * Copyright (c) 2010-2011 Vojtech Horky
  * All rights reserved.
  *
@@ -37,4 +37,5 @@
 #include <stdio.h>
 #include <usb/usb.h>
+#include <assert.h>
 
 void usb_dprintf(const char *tag, int level, const char *format, ...);
@@ -44,4 +45,39 @@
     const uint8_t *, size_t);
 
+/** Logging level. */
+typedef enum {
+    USB_LOG_LEVEL_FATAL,
+    USB_LOG_LEVEL_ERROR,
+    USB_LOG_LEVEL_WARNING,
+    USB_LOG_LEVEL_INFO,
+    USB_LOG_LEVEL_DEBUG,
+    USB_LOG_LEVEL_DEBUG2
+} usb_log_level_t;
+
+
+void usb_log_enable(usb_log_level_t, const char *);
+
+void usb_log_printf(usb_log_level_t, const char *, ...);
+
+#define usb_log_fatal(format, ...) \
+	usb_log_printf(USB_LOG_LEVEL_FATAL, format, ##__VA_ARGS__)
+
+#define usb_log_error(format, ...) \
+	usb_log_printf(USB_LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
+
+#define usb_log_warning(format, ...) \
+	usb_log_printf(USB_LOG_LEVEL_WARNING, format, ##__VA_ARGS__)
+
+#define usb_log_info(format, ...) \
+	usb_log_printf(USB_LOG_LEVEL_INFO, format, ##__VA_ARGS__)
+
+#define usb_log_debug(format, ...) \
+	usb_log_printf(USB_LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
+
+#define usb_log_debug2(format, ...) \
+	usb_log_printf(USB_LOG_LEVEL_DEBUG2, format, ##__VA_ARGS__)
+
+
+
 #endif
 /**
Index: uspace/lib/usb/src/debug.c
===================================================================
--- uspace/lib/usb/src/debug.c	(revision 1879a7de2821a2ed5d8b048b5d94f0e6896b5536)
+++ uspace/lib/usb/src/debug.c	(revision 0b314096809e841d815b7cedeaf1988722db8c0e)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2010 Vojtech Horky
+ * Copyright (c) 2010-2011 Vojtech Horky
  * All rights reserved.
  *
@@ -61,4 +61,11 @@
 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);
+
 /** Find or create new tag with given name.
  *
@@ -155,4 +162,65 @@
 }
 
+/** 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;
+}
+
+
+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, ...)
+{
+	if (level > log_level) {
+		return;
+	}
+
+	FILE *stream = NULL;
+	switch (level) {
+		case USB_LOG_LEVEL_FATAL:
+		case USB_LOG_LEVEL_ERROR:
+			stream = stderr;
+			break;
+		default:
+			stream = stdout;
+			break;
+	}
+	assert(stream != NULL);
+
+	va_list args;
+	va_start(args, format);
+
+	fibril_mutex_lock(&log_serializer);
+	fprintf(stream, "[%s]%s: ", log_prefix, log_level_name(level));
+	vfprintf(stream, format, args);
+	fibril_mutex_unlock(&log_serializer);
+
+	va_end(args);
+}
 
 /**
