Index: .bzrignore
===================================================================
--- .bzrignore	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ .bzrignore	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,175 @@
+# user makefile for local targets
+Makefile.local
+
+# generated files (misc)
+Makefile.depend
+*.prev
+*.map
+*.disasm
+_link.ld
+./*.iso
+
+./Makefile.common
+./Makefile.config
+./common.h
+./config.h
+./autotool/
+./image.iso
+./boot/distroot/
+./boot/initrd.fs
+./boot/initrd.img
+./kernel/kernel.bin
+./kernel/kernel.dump
+./kernel/kernel.raw
+./kernel/generic/src/debug/real_map.bin
+
+./kernel/arch/ia32/include/common.h
+./kernel/arch/amd64/include/common.h
+./kernel/generic/include/arch
+./kernel/generic/include/genarch
+./uspace/lib/c/arch/amd64/include/common.h
+./uspace/lib/c/arch/ia32/include/common.h
+./uspace/lib/c/include/arch
+./uspace/lib/c/include/kernel
+./uspace/lib/c/include/libarch
+
+
+  
+  
+  
+
+# generated files (executables)
+./uspace/app/bdsh/bdsh
+./uspace/app/edit/edit
+./uspace/app/getterm/getterm
+./uspace/app/init/init
+./uspace/app/klog/klog
+./uspace/app/mkfat/mkfat
+./uspace/app/netstart/netstart
+./uspace/app/netecho/netecho
+./uspace/app/nettest1/nettest1
+./uspace/app/nettest2/nettest2
+./uspace/app/ping/ping
+./uspace/app/redir/redir
+./uspace/app/sbi/sbi
+./uspace/app/stats/stats
+./uspace/app/taskdump/taskdump
+./uspace/app/tasks/tasks
+./uspace/app/tester/tester
+./uspace/app/test_serial/test_serial
+./uspace/app/tetris/tetris
+./uspace/app/top/top
+./uspace/app/trace/trace
+./uspace/app/usb/usb
+./uspace/app/virtusbkbd/vuk
+./uspace/dist/app/bdsh
+./uspace/dist/app/edit
+./uspace/dist/app/getterm
+./uspace/dist/app/klog
+./uspace/dist/app/mkfat
+./uspace/dist/app/netecho
+./uspace/dist/app/netstart
+./uspace/dist/app/nettest1
+./uspace/dist/app/nettest2
+./uspace/dist/app/ping
+./uspace/dist/app/redir
+./uspace/dist/app/sbi
+./uspace/dist/app/stats
+./uspace/dist/app/taskdump
+./uspace/dist/app/tasks
+./uspace/dist/app/tester
+./uspace/dist/app/test_serial
+./uspace/dist/app/tetris
+./uspace/dist/app/top
+./uspace/dist/app/trace
+./uspace/dist/app/usb
+./uspace/dist/app/vuk
+./uspace/dist/cfg/net/general
+./uspace/dist/cfg/net/lo
+./uspace/dist/cfg/net/ne2k
+./uspace/dist/drv/isa/
+./uspace/dist/drv/ns8250/
+./uspace/dist/drv/pciintel/
+./uspace/dist/drv/root/
+./uspace/dist/drv/rootia32/
+./uspace/dist/drv/uhci/
+./uspace/dist/drv/usbkbd/
+./uspace/dist/drv/vhc/
+./uspace/dist/srv/arp
+./uspace/dist/srv/ata_bd
+./uspace/dist/srv/char_ms
+./uspace/dist/srv/clip
+./uspace/dist/srv/console
+./uspace/dist/srv/devfs
+./uspace/dist/srv/devman
+./uspace/dist/srv/dp8390
+./uspace/dist/srv/eth
+./uspace/dist/srv/fat
+./uspace/dist/srv/fb
+./uspace/dist/srv/file_bd
+./uspace/dist/srv/g_part
+./uspace/dist/srv/i8042
+./uspace/dist/srv/icmp
+./uspace/dist/srv/ip
+./uspace/dist/srv/kbd
+./uspace/dist/srv/lo
+./uspace/dist/srv/mbr_part
+./uspace/dist/srv/net
+./uspace/dist/srv/netstart
+./uspace/dist/srv/nildummy
+./uspace/dist/srv/pci
+./uspace/dist/srv/taskmon
+./uspace/dist/srv/tcp
+./uspace/dist/srv/tmpfs
+./uspace/dist/srv/udp
+./uspace/dist/srv/vhcd
+./uspace/drv/root/root
+./uspace/drv/isa/isa
+./uspace/drv/ns8250/ns8250
+./uspace/drv/pciintel/pciintel
+./uspace/drv/rootia32/rootia32
+./uspace/drv/uhci/uhci
+./uspace/drv/usbkbd/usbkbd
+./uspace/drv/vhc/vhc
+./uspace/srv/bd/ata_bd/ata_bd
+./uspace/srv/bd/file_bd/file_bd
+./uspace/srv/bd/gxe_bd/gxe_bd
+./uspace/srv/bd/part/guid_part/g_part
+./uspace/srv/bd/part/mbr_part/mbr_part
+./uspace/srv/bd/rd/rd
+./uspace/srv/clip/clip
+./uspace/srv/devman/devman
+./uspace/srv/devmap/devmap
+./uspace/srv/fs/devfs/devfs
+./uspace/srv/fs/fat/fat
+./uspace/srv/fs/tmpfs/tmpfs
+./uspace/srv/hid/adb_mouse/adb_ms
+./uspace/srv/hid/char_mouse/char_ms
+./uspace/srv/hid/console/console
+./uspace/srv/hid/fb/fb
+./uspace/srv/hid/kbd/kbd
+./uspace/srv/hid/s3c24xx_ts/s3c24ts
+./uspace/srv/hw/bus/pci/pci
+./uspace/srv/hw/char/i8042/i8042
+./uspace/srv/hw/char/s3c24xx_uart/s3c24ser
+./uspace/srv/hw/netif/dp8390/dp8390
+./uspace/srv/loader/loader
+./uspace/srv/net/cfg/lo
+./uspace/srv/net/cfg/ne2k
+./uspace/srv/net/il/arp/arp
+./uspace/srv/net/il/ip/ip
+./uspace/srv/net/net/net
+./uspace/srv/net/netif/lo/lo
+./uspace/srv/net/netstart/netstart
+./uspace/srv/net/nil/eth/eth
+./uspace/srv/net/nil/nildummy/nildummy
+./uspace/srv/net/tl/icmp/icmp
+./uspace/srv/net/tl/tcp/tcp
+./uspace/srv/net/tl/udp/udp
+./uspace/srv/ns/ns
+./uspace/srv/taskmon/taskmon
+./uspace/srv/vfs/vfs
+
+# IDE files
+.cproject
+.project
Index: Makefile
===================================================================
--- Makefile	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -79,2 +79,4 @@
 	$(MAKE) -C uspace clean
 	$(MAKE) -C boot clean
+
+-include Makefile.local
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/Makefile.common	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -99,4 +99,5 @@
 	$(USPACE_PATH)/srv/taskmon/taskmon \
 	$(USPACE_PATH)/srv/hw/netif/dp8390/dp8390 \
+	$(USPACE_PATH)/srv/hw/bus/usb/hcd/virtual/vhcd \
 	$(USPACE_PATH)/srv/net/netif/lo/lo \
 	$(USPACE_PATH)/srv/net/il/arp/arp \
@@ -109,5 +110,6 @@
 	
 RD_DRVS = \
-	root
+	root \
+	vhc
 
 RD_DRV_CFG = 
@@ -140,4 +142,5 @@
 	$(USPACE_PATH)/app/ping/ping \
 	$(USPACE_PATH)/app/stats/stats \
+	$(USPACE_PATH)/app/virtusbkbd/vuk \
 	$(USPACE_PATH)/app/tasks/tasks \
 	$(USPACE_PATH)/app/top/top
Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/arch/amd64/Makefile.inc	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -40,5 +40,7 @@
 	pciintel \
 	isa \
-	ns8250
+	ns8250 \
+	uhci \
+	usbkbd
 	
 RD_DRV_CFG += \
Index: boot/arch/arm32/src/main.c
===================================================================
--- boot/arch/arm32/src/main.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/arch/arm32/src/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -61,5 +61,6 @@
 	printf(" %p|%p: bootstrap page table\n", &boot_pt, &boot_pt);
 	printf(" %p|%p: boot info structure\n", &bootinfo, &bootinfo);
-	printf(" %p|%p: kernel entry point\n", PA2KA(BOOT_OFFSET), BOOT_OFFSET);
+	printf(" %p|%p: kernel entry point\n",
+	    (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET);
 	
 	size_t i;
Index: boot/arch/ia64/src/main.c
===================================================================
--- boot/arch/ia64/src/main.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/arch/ia64/src/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -62,10 +62,12 @@
 	
 	printf(" %p|%p: boot info structure\n", &bootinfo, &bootinfo);
-	printf(" %p|%p: kernel entry point\n", KERNEL_ADDRESS, KERNEL_ADDRESS);
-	printf(" %p|%p: loader entry point\n", LOADER_ADDRESS, LOADER_ADDRESS);
+	printf(" %p|%p: kernel entry point\n",
+	    (void *) KERNEL_ADDRESS, (void *) KERNEL_ADDRESS);
+	printf(" %p|%p: loader entry point\n",
+	    (void *) LOADER_ADDRESS, (void *) LOADER_ADDRESS);
 	
 	size_t i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start,
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
 		    components[i].start, components[i].name,
 		    components[i].inflated, components[i].size);
Index: boot/arch/mips32/src/main.c
===================================================================
--- boot/arch/mips32/src/main.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/arch/mips32/src/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -51,14 +51,19 @@
 	
 	printf("\nMemory statistics\n");
-	printf(" %p|%p: CPU map\n", PA2KA(CPUMAP_OFFSET), CPUMAP_OFFSET);
-	printf(" %p|%p: bootstrap stack\n", PA2KA(STACK_OFFSET), STACK_OFFSET);
-	printf(" %p|%p: boot info structure\n", PA2KA(BOOTINFO_OFFSET), BOOTINFO_OFFSET);
-	printf(" %p|%p: kernel entry point\n", PA2KA(BOOT_OFFSET), BOOT_OFFSET);
-	printf(" %p|%p: bootloader entry point\n", PA2KA(LOADER_OFFSET), LOADER_OFFSET);
+	printf(" %p|%p: CPU map\n", (void *) PA2KA(CPUMAP_OFFSET),
+	    (void *) CPUMAP_OFFSET);
+	printf(" %p|%p: bootstrap stack\n", (void *) PA2KA(STACK_OFFSET),
+	    (void *) STACK_OFFSET);
+	printf(" %p|%p: boot info structure\n",
+	    (void *) PA2KA(BOOTINFO_OFFSET), (void *) BOOTINFO_OFFSET);
+	printf(" %p|%p: kernel entry point\n", (void *) PA2KA(BOOT_OFFSET),
+	    (void *) BOOT_OFFSET);
+	printf(" %p|%p: bootloader entry point\n",
+	    (void *) PA2KA(LOADER_OFFSET), (void *) LOADER_OFFSET);
 	
 	size_t i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start,
-		    KSEG2PA(components[i].start), components[i].name,
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
+		    (void *) KSEG2PA(components[i].start), components[i].name,
 		    components[i].inflated, components[i].size);
 	
@@ -91,5 +96,5 @@
 		if (tail >= ((void *) PA2KA(LOADER_OFFSET))) {
 			printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
-			    components[i].name, tail, PA2KA(LOADER_OFFSET));
+			    components[i].name, tail, (void *) PA2KA(LOADER_OFFSET));
 			halt();
 		}
Index: boot/arch/ppc32/src/main.c
===================================================================
--- boot/arch/ppc32/src/main.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/arch/ppc32/src/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -68,10 +68,12 @@
 	printf(" %p|%p: real mode trampoline\n", &real_mode, real_mode_pa);
 	printf(" %p|%p: boot info structure\n", &bootinfo, bootinfo_pa);
-	printf(" %p|%p: kernel entry point\n", PA2KA(BOOT_OFFSET), BOOT_OFFSET);
-	printf(" %p|%p: loader entry point\n", LOADER_ADDRESS, loader_address_pa);
+	printf(" %p|%p: kernel entry point\n",
+	    (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET);
+	printf(" %p|%p: loader entry point\n",
+	    (void *) LOADER_ADDRESS, loader_address_pa);
 	
 	size_t i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start,
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
 		    ofw_translate(components[i].start), components[i].name,
 		    components[i].inflated, components[i].size);
Index: boot/arch/sparc64/src/main.c
===================================================================
--- boot/arch/sparc64/src/main.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/arch/sparc64/src/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -209,13 +209,15 @@
 	void *loader_address_pa = ofw_translate((void *) LOADER_ADDRESS);
 	
-	printf("\nMemory statistics (total %llu MB, starting at %p)\n",
-	    bootinfo.memmap.total >> 20, bootinfo.physmem_start);
-	printf(" %p|%p: boot info structure\n", &bootinfo, bootinfo_pa);
-	printf(" %p|%p: kernel entry point\n", KERNEL_ADDRESS, kernel_address_pa);
-	printf(" %p|%p: loader entry point\n", LOADER_ADDRESS, loader_address_pa);
+	printf("\nMemory statistics (total %" PRIu64 " MB, starting at %p)\n",
+	    bootinfo.memmap.total >> 20, (void *) bootinfo.physmem_start);
+	printf(" %p|%p: boot info structure\n", &bootinfo, (void *) bootinfo_pa);
+	printf(" %p|%p: kernel entry point\n",
+	    (void *) KERNEL_ADDRESS, (void *) kernel_address_pa);
+	printf(" %p|%p: loader entry point\n",
+	    (void *) LOADER_ADDRESS, (void *) loader_address_pa);
 	
 	size_t i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start,
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
 		    ofw_translate(components[i].start), components[i].name,
 		    components[i].inflated, components[i].size);
Index: boot/genarch/src/ofw.c
===================================================================
--- boot/genarch/src/ofw.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/genarch/src/ofw.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -243,5 +243,5 @@
 	void *addr = ofw_claim_virt_internal(virt, len, 0);
 	if (addr != virt) {
-		printf("Error: Unable to claim virtual memory %p (size %u), halting.\n",
+		printf("Error: Unable to claim virtual memory %p (size %zu), halting.\n",
 		    virt, len);
 		halt();
@@ -254,5 +254,5 @@
 	
 	if (addr == NULL) {
-		printf("Error: Unable to claim %u bytes in virtual memory, halting.\n",
+		printf("Error: Unable to claim %zu bytes in virtual memory, halting.\n",
 		    len);
 		halt();
@@ -305,5 +305,5 @@
 	void *addr = ofw_claim_phys_internal(phys, len, 0);
 	if (addr != phys) {
-		printf("Error: Unable to claim physical memory %p (size %u), halting.\n",
+		printf("Error: Unable to claim physical memory %p (size %zu), halting.\n",
 		    phys, len);
 		halt();
@@ -315,5 +315,5 @@
 	void *addr = ofw_claim_phys_internal(NULL, len, alignment);
 	if (addr == NULL) {
-		printf("Error: Unable to claim %u bytes in physical memory, halting.\n",
+		printf("Error: Unable to claim %zu bytes in physical memory, halting.\n",
 		    len);
 		halt();
@@ -343,5 +343,5 @@
 	
 	if (ret != 0) {
-		printf("Error: Unable to map %p to %p (size %u), halting.\n",
+		printf("Error: Unable to map %p to %p (size %zu), halting.\n",
 		    virt, phys, size);
 		halt();
Index: boot/generic/include/printf.h
===================================================================
--- boot/generic/include/printf.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/generic/include/printf.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -36,8 +36,20 @@
 #include <stdarg.h>
 
+#ifndef NVERIFY_PRINTF
+
+#define PRINTF_ATTRIBUTE(start, end) \
+	__attribute__((format(gnu_printf, start, end)))
+
+#else /* NVERIFY_PRINTF */
+
+#define PRINTF_ATTRIBUTE(start, end)
+
+#endif /* NVERIFY_PRINTF */
+
 #define EOF  (-1)
 
 extern int puts(const char *);
-extern int printf(const char *, ...);
+extern int printf(const char *, ...)
+    PRINTF_ATTRIBUTE(1, 2);
 extern int vprintf(const char *, va_list);
 
Index: boot/generic/include/stdint.h
===================================================================
--- boot/generic/include/stdint.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/generic/include/stdint.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -33,27 +33,27 @@
 #define BOOT_STDINT_H_
 
-#define INT8_MIN  (0x80)
-#define INT8_MAX  (0x7F)
+#define INT8_MIN  INT8_C(0x80)
+#define INT8_MAX  INT8_C(0x7F)
 
-#define UINT8_MIN  (0u)
-#define UINT8_MAX  (0xFFu)
+#define UINT8_MIN  UINT8_C(0)
+#define UINT8_MAX  UINT8_C(0xFF)
 
-#define INT16_MIN  (0x8000)
-#define INT16_MAX  (0x7FFF)
+#define INT16_MIN  INT16_C(0x8000)
+#define INT16_MAX  INT16_C(0x7FFF)
 
-#define UINT16_MIN  (0u)
-#define UINT16_MAX  (0xFFFFu)
+#define UINT16_MIN  UINT16_C(0)
+#define UINT16_MAX  UINT16_C(0xFFFF)
 
-#define INT32_MIN  (0x80000000l)
-#define INT32_MAX  (0x7FFFFFFFl)
+#define INT32_MIN  INT32_C(0x80000000)
+#define INT32_MAX  INT32_C(0x7FFFFFFF)
 
-#define UINT32_MIN  (0ul)
-#define UINT32_MAX  (0xFFFFFFFFul)
+#define UINT32_MIN  UINT32_C(0)
+#define UINT32_MAX  UINT32_C(0xFFFFFFFF)
 
-#define INT64_MIN  (0x8000000000000000ll)
-#define INT64_MAX  (0x7FFFFFFFFFFFFFFFll)
+#define INT64_MIN  INT64_C(0x8000000000000000)
+#define INT64_MAX  INT64_C(0x7FFFFFFFFFFFFFFF)
 
-#define UINT64_MIN  (0ull)
-#define UINT64_MAX  (0xFFFFFFFFFFFFFFFFull)
+#define UINT64_MIN  UINT64_C(0)
+#define UINT64_MAX  UINT64_C(0xFFFFFFFFFFFFFFFF)
 
 #endif
Index: boot/generic/include/typedefs.h
===================================================================
--- boot/generic/include/typedefs.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/generic/include/typedefs.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -37,5 +37,5 @@
 #include <arch/types.h>
 
-#define NULL	((void *) 0)
+#define NULL  ((void *) 0)
 
 #define false  0
@@ -43,5 +43,4 @@
 
 typedef uint8_t bool;
-typedef int32_t wchar_t;
 
 #endif
Index: boot/generic/src/printf_core.c
===================================================================
--- boot/generic/src/printf_core.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ boot/generic/src/printf_core.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -79,5 +79,6 @@
 	PrintfQualifierLong,
 	PrintfQualifierLongLong,
-	PrintfQualifierPointer
+	PrintfQualifierPointer,
+	PrintfQualifierSize
 } qualifier_t;
 
@@ -431,6 +432,4 @@
  *  - ""   Signed or unsigned int (default value).@n
  *  - "l"  Signed or unsigned long int.@n
- *         If conversion is "c", the character is wchar_t (wide character).@n
- *         If conversion is "s", the string is wchar_t * (wide string).@n
  *  - "ll" Signed or unsigned long long int.@n
  *
@@ -612,4 +611,9 @@
 				}
 				break;
+			case 'z':
+				qualifier = PrintfQualifierSize;
+				i = nxt;
+				uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+				break;
 			default:
 				/* Default type */
@@ -720,4 +724,8 @@
 				number = (uint64_t) (uintptr_t) va_arg(ap, void *);
 				break;
+			case PrintfQualifierSize:
+				size = sizeof(size_t);
+				number = (uint64_t) va_arg(ap, size_t);
+				break;
 			default:
 				/* Unknown qualifier */
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -313,4 +313,5 @@
 		test/print/print3.c \
 		test/print/print4.c \
+		test/print/print5.c \
 		test/thread/thread1.c
 	
Index: kernel/arch/abs32le/include/istate.h
===================================================================
--- kernel/arch/abs32le/include/istate.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/abs32le/include/istate.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -37,13 +37,18 @@
 
 #ifdef KERNEL
+
 #include <typedefs.h>
 #include <verify.h>
 #include <trace.h>
-#else
+
+#else /* KERNEL */
+
 #include <sys/types.h>
+
 #define NO_TRACE
 #define REQUIRES_EXTENT_MUTABLE(arg)
 #define WRITES(arg)
-#endif
+
+#endif /* KERNEL */
 
 /*
@@ -63,5 +68,5 @@
 	   context originated from user space. */
 	
-	return !(istate->ip & 0x80000000);
+	return !(istate->ip & UINT32_C(0x80000000));
 }
 
Index: kernel/arch/abs32le/include/mm/as.h
===================================================================
--- kernel/arch/abs32le/include/mm/as.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/abs32le/include/mm/as.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -38,8 +38,8 @@
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
 
-#define KERNEL_ADDRESS_SPACE_START_ARCH  ((unsigned long) 0x80000000)
-#define KERNEL_ADDRESS_SPACE_END_ARCH    ((unsigned long) 0xffffffff)
-#define USER_ADDRESS_SPACE_START_ARCH    ((unsigned long) 0x00000000)
-#define USER_ADDRESS_SPACE_END_ARCH      ((unsigned long) 0x7fffffff)
+#define KERNEL_ADDRESS_SPACE_START_ARCH  UINT32_C(0x80000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    UINT32_C(0xffffffff)
+#define USER_ADDRESS_SPACE_START_ARCH    UINT32_C(0x00000000)
+#define USER_ADDRESS_SPACE_END_ARCH      UINT32_C(0x7fffffff)
 
 #define USTACK_ADDRESS_ARCH  (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))
Index: kernel/arch/abs32le/include/mm/page.h
===================================================================
--- kernel/arch/abs32le/include/mm/page.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/abs32le/include/mm/page.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -44,6 +44,6 @@
 #ifdef KERNEL
 
-#define KA2PA(x)  (((uintptr_t) (x)) - 0x80000000)
-#define PA2KA(x)  (((uintptr_t) (x)) + 0x80000000)
+#define KA2PA(x)  (((uintptr_t) (x)) - UINT32_C(0x80000000))
+#define PA2KA(x)  (((uintptr_t) (x)) + UINT32_C(0x80000000))
 
 /*
@@ -65,8 +65,8 @@
 
 /* Macros calculating indices for each level. */
-#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 22) & 0x3ff)
+#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 22) & 0x3ffU)
 #define PTL1_INDEX_ARCH(vaddr)  0
 #define PTL2_INDEX_ARCH(vaddr)  0
-#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x3ff)
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x3ffU)
 
 /* Get PTE address accessors for each level. */
Index: kernel/arch/abs32le/include/types.h
===================================================================
--- kernel/arch/abs32le/include/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/abs32le/include/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -53,24 +53,11 @@
 } fncptr_t;
 
-#define PRIp  "x"  /**< Format for uintptr_t. */
-#define PRIs  "u"  /**< Format for size_t. */
+#define INTN_C(c)   INT32_C(c)
+#define UINTN_C(c)  UINT32_C(c)
 
-#define PRId8   "d"    /**< Format for int8_t. */
-#define PRId16  "d"    /**< Format for int16_t. */
-#define PRId32  "d"    /**< Format for int32_t. */
-#define PRId64  "lld"  /**< Format for int64_t. */
-#define PRIdn   "d"    /**< Format for native_t. */
-
-#define PRIu8   "u"    /**< Format for uint8_t. */
-#define PRIu16  "u"    /**< Format for uint16_t. */
-#define PRIu32  "u"    /**< Format for uint32_t. */
-#define PRIu64  "llu"  /**< Format for uint64_t. */
-#define PRIun   "u"    /**< Format for unative_t. */
-
-#define PRIx8   "x"    /**< Format for hexadecimal (u)int8_t. */
-#define PRIx16  "x"    /**< Format for hexadecimal (u)int16_t. */
-#define PRIx32  "x"    /**< Format for hexadecimal (u)uint32_t. */
-#define PRIx64  "llx"  /**< Format for hexadecimal (u)int64_t. */
-#define PRIxn   "x"    /**< Format for hexadecimal (u)native_t. */
+#define PRIdn  PRId32  /**< Format for native_t. */
+#define PRIun  PRIu32  /**< Format for unative_t. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal unative_t. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: kernel/arch/amd64/include/context.h
===================================================================
--- kernel/arch/amd64/include/context.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/context.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64	
+/** @addtogroup amd64
  * @{
  */
@@ -44,5 +44,5 @@
  * panic sooner or later
  */
-#define SP_DELTA     16
+#define SP_DELTA  16
 
 #define context_set(c, _pc, stack, size) \
Index: kernel/arch/amd64/include/context_offset.h
===================================================================
--- kernel/arch/amd64/include/context_offset.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/context_offset.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,22 +30,22 @@
 #define KERN_amd64_CONTEXT_OFFSET_H_
 
-#define OFFSET_SP  0x0
-#define OFFSET_PC  0x8
-#define OFFSET_RBX 0x10
-#define OFFSET_RBP 0x18
-#define OFFSET_R12 0x20
-#define OFFSET_R13 0x28
-#define OFFSET_R14 0x30
-#define OFFSET_R15 0x38
+#define OFFSET_SP   0x00
+#define OFFSET_PC   0x08
+#define OFFSET_RBX  0x10
+#define OFFSET_RBP  0x18
+#define OFFSET_R12  0x20
+#define OFFSET_R13  0x28
+#define OFFSET_R14  0x30
+#define OFFSET_R15  0x38
 
 #ifdef KERNEL
-# define OFFSET_IPL 0x40
+	#define OFFSET_IPL  0x40
 #else
-# define OFFSET_TLS 0x40
+	#define OFFSET_TLS  0x40
 #endif
 
 #ifdef __ASM__
 
-# ctx: address of the structure with saved context 
+# ctx: address of the structure with saved context
 # pc: return address
 .macro CONTEXT_SAVE_ARCH_CORE ctx:req pc:req
@@ -61,5 +61,5 @@
 .endm
 
-# ctx: address of the structure with saved context 
+# ctx: address of the structure with saved context
 .macro CONTEXT_RESTORE_ARCH_CORE ctx:req pc:req
 	movq OFFSET_R15(\ctx), %r15
@@ -68,5 +68,5 @@
 	movq OFFSET_R12(\ctx), %r12
 	movq OFFSET_RBP(\ctx), %rbp
-	movq OFFSET_RBX(\ctx), %rbx	
+	movq OFFSET_RBX(\ctx), %rbx
 	
 	movq OFFSET_SP(\ctx), %rsp   # ctx->sp -> %rsp
Index: kernel/arch/amd64/include/cpu.h
===================================================================
--- kernel/arch/amd64/include/cpu.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/cpu.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -36,15 +36,15 @@
 #define KERN_amd64_CPU_H_
 
-#define RFLAGS_CF	(1 << 0)
-#define RFLAGS_PF	(1 << 2)
-#define RFLAGS_AF	(1 << 4)
-#define RFLAGS_ZF	(1 << 6)
-#define RFLAGS_SF	(1 << 7)
-#define RFLAGS_TF	(1 << 8)
-#define RFLAGS_IF	(1 << 9)
-#define RFLAGS_DF	(1 << 10)
-#define RFLAGS_OF	(1 << 11)
-#define RFLAGS_NT	(1 << 14)
-#define RFLAGS_RF	(1 << 16)
+#define RFLAGS_CF  (1 << 0)
+#define RFLAGS_PF  (1 << 2)
+#define RFLAGS_AF  (1 << 4)
+#define RFLAGS_ZF  (1 << 6)
+#define RFLAGS_SF  (1 << 7)
+#define RFLAGS_TF  (1 << 8)
+#define RFLAGS_IF  (1 << 9)
+#define RFLAGS_DF  (1 << 10)
+#define RFLAGS_OF  (1 << 11)
+#define RFLAGS_NT  (1 << 14)
+#define RFLAGS_RF  (1 << 16)
 
 #define EFER_MSR_NUM    0xc0000080
Index: kernel/arch/amd64/include/debugger.h
===================================================================
--- kernel/arch/amd64/include/debugger.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/debugger.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -41,9 +41,9 @@
 
 /* Flags that are passed to breakpoint_add function */
-#define BKPOINT_INSTR       0x1
-#define BKPOINT_WRITE       0x2
-#define BKPOINT_READ_WRITE  0x4
+#define BKPOINT_INSTR       0x1U
+#define BKPOINT_WRITE       0x2U
+#define BKPOINT_READ_WRITE  0x4U
 
-#define BKPOINT_CHECK_ZERO  0x8
+#define BKPOINT_CHECK_ZERO  0x8U
 
 
Index: kernel/arch/amd64/include/istate.h
===================================================================
--- kernel/arch/amd64/include/istate.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/istate.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -37,10 +37,15 @@
 
 #ifdef KERNEL
+
 #include <typedefs.h>
 #include <trace.h>
-#else
+
+#else /* KERNEL */
+
 #include <sys/types.h>
+
 #define NO_TRACE
-#endif
+
+#endif /* KERNEL */
 
 /** This is passed to interrupt handlers */
@@ -61,13 +66,13 @@
 	uint64_t r14;
 	uint64_t r15;
-	uint64_t alignment;	/* align rbp_frame on multiple of 16 */
-	uint64_t rbp_frame;	/* imitation of frame pointer linkage */
-	uint64_t rip_frame;	/* imitation of return address linkage */
-	uint64_t error_word;	/* real or fake error word */
+	uint64_t alignment;   /* align rbp_frame on multiple of 16 */
+	uint64_t rbp_frame;   /* imitation of frame pointer linkage */
+	uint64_t rip_frame;   /* imitation of return address linkage */
+	uint64_t error_word;  /* real or fake error word */
 	uint64_t rip;
 	uint64_t cs;
 	uint64_t rflags;
-	uint64_t rsp;		/* only if istate_t is from uspace */
-	uint64_t ss;		/* only if istate_t is from uspace */
+	uint64_t rsp;         /* only if istate_t is from uspace */
+	uint64_t ss;          /* only if istate_t is from uspace */
 } istate_t;
 
@@ -75,5 +80,5 @@
 NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
-	return !(istate->rip & 0x8000000000000000);
+	return !(istate->rip & UINT64_C(0x8000000000000000));
 }
 
Index: kernel/arch/amd64/include/mm/as.h
===================================================================
--- kernel/arch/amd64/include/mm/as.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/mm/as.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -36,14 +36,14 @@
 #define KERN_amd64_AS_H_
 
-#define ADDRESS_SPACE_HOLE_START	0x0000800000000000ULL
-#define ADDRESS_SPACE_HOLE_END		0xffff7fffffffffffULL
+#define ADDRESS_SPACE_HOLE_START  UINT64_C(0x0000800000000000)
+#define ADDRESS_SPACE_HOLE_END    UINT64_C(0xffff7fffffffffff)
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
 
-#define KERNEL_ADDRESS_SPACE_START_ARCH	0xffff800000000000ULL
-#define KERNEL_ADDRESS_SPACE_END_ARCH	0xffffffffffffffffULL
+#define KERNEL_ADDRESS_SPACE_START_ARCH  UINT64_C(0xffff800000000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    UINT64_C(0xffffffffffffffff)
 
-#define USER_ADDRESS_SPACE_START_ARCH	0x0000000000000000ULL
-#define USER_ADDRESS_SPACE_END_ARCH	0x00007fffffffffffULL
+#define USER_ADDRESS_SPACE_START_ARCH  UINT64_C(0x0000000000000000)
+#define USER_ADDRESS_SPACE_END_ARCH    UINT64_C(0x00007fffffffffff)
 
 #define USTACK_ADDRESS_ARCH  (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))
Index: kernel/arch/amd64/include/mm/page.h
===================================================================
--- kernel/arch/amd64/include/mm/page.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/mm/page.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -55,6 +55,6 @@
 #ifndef __ASM__
 
-#define KA2PA(x)  (((uintptr_t) (x)) - 0xffff800000000000)
-#define PA2KA(x)  (((uintptr_t) (x)) + 0xffff800000000000)
+#define KA2PA(x)  (((uintptr_t) (x)) - UINT64_C(0xffff800000000000))
+#define PA2KA(x)  (((uintptr_t) (x)) + UINT64_C(0xffff800000000000))
 
 #else /* __ASM__ */
@@ -78,8 +78,8 @@
 
 /* Macros calculating indices into page tables in each level. */
-#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 39) & 0x1ff)
-#define PTL1_INDEX_ARCH(vaddr)  (((vaddr) >> 30) & 0x1ff)
-#define PTL2_INDEX_ARCH(vaddr)  (((vaddr) >> 21) & 0x1ff)
-#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x1ff)
+#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 39) & 0x1ffU)
+#define PTL1_INDEX_ARCH(vaddr)  (((vaddr) >> 30) & 0x1ffU)
+#define PTL2_INDEX_ARCH(vaddr)  (((vaddr) >> 21) & 0x1ffU)
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x1ffU)
 
 /* Get PTE address accessors for each level. */
@@ -205,5 +205,5 @@
 	pte_t *p = &pt[i];
 	
-	p->addr_12_31 = (a >> 12) & 0xfffff;
+	p->addr_12_31 = (a >> 12) & UINT32_C(0xfffff);
 	p->addr_32_51 = a >> 32;
 }
Index: kernel/arch/amd64/include/pm.h
===================================================================
--- kernel/arch/amd64/include/pm.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/pm.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -75,7 +75,7 @@
 #define AR_WRITABLE   (1 << 1)
 #define AR_READABLE   (1 << 1)
-#define AR_TSS        (0x09)
-#define AR_INTERRUPT  (0x0e)
-#define AR_TRAP       (0x0f)
+#define AR_TSS        (0x09U)
+#define AR_INTERRUPT  (0x0eU)
+#define AR_TRAP       (0x0fU)
 
 #define DPL_KERNEL  (PL_KERNEL << 5)
Index: kernel/arch/amd64/include/types.h
===================================================================
--- kernel/arch/amd64/include/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/include/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -50,26 +50,11 @@
 } fncptr_t;
 
-/* Formats for uintptr_t, size_t */
-#define PRIp  "llx"
-#define PRIs  "llu"
+#define INTN_C(c)   INT64_C(c)
+#define UINTN_C(c)  UINT64_C(c)
 
-/* Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
-#define PRId8   "d"
-#define PRId16  "d"
-#define PRId32  "d"
-#define PRId64  "lld"
-#define PRIdn   "lld"
-
-#define PRIu8   "u"
-#define PRIu16  "u"
-#define PRIu32  "u"
-#define PRIu64  "llu"
-#define PRIun   "llu"
-
-#define PRIx8   "x"
-#define PRIx16  "x"
-#define PRIx32  "x"
-#define PRIx64  "llx"
-#define PRIxn   "llx"
+#define PRIdn  PRId64  /**< Format for native_t. */
+#define PRIun  PRIu64  /**< Format for unative_t. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal unative_t. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
 
 #endif
Index: kernel/arch/amd64/src/boot/memmap.c
===================================================================
--- kernel/arch/amd64/src/boot/memmap.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/src/boot/memmap.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -35,5 +35,5 @@
 #include <arch/boot/memmap.h>
 
-uint8_t e820counter = 0xff;
+uint8_t e820counter = 0xffU;
 e820memmap_t e820table[MEMMAP_E820_MAX_RECORDS];
 
Index: kernel/arch/amd64/src/cpu/cpu.c
===================================================================
--- kernel/arch/amd64/src/cpu/cpu.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/src/cpu/cpu.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -47,12 +47,11 @@
  * Contains only non-MP-Specification specific SMP code.
  */
-#define AMD_CPUID_EBX  0x68747541
-#define AMD_CPUID_ECX  0x444d4163
-#define AMD_CPUID_EDX  0x69746e65
+#define AMD_CPUID_EBX  UINT32_C(0x68747541)
+#define AMD_CPUID_ECX  UINT32_C(0x444d4163)
+#define AMD_CPUID_EDX  UINT32_C(0x69746e65)
 
-#define INTEL_CPUID_EBX  0x756e6547
-#define INTEL_CPUID_ECX  0x6c65746e
-#define INTEL_CPUID_EDX  0x49656e69
-
+#define INTEL_CPUID_EBX  UINT32_C(0x756e6547)
+#define INTEL_CPUID_ECX  UINT32_C(0x6c65746e)
+#define INTEL_CPUID_EDX  UINT32_C(0x49656e69)
 
 enum vendor {
Index: kernel/arch/amd64/src/debugger.c
===================================================================
--- kernel/arch/amd64/src/debugger.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/src/debugger.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -126,5 +126,5 @@
 	/* Disable breakpoint in DR7 */
 	unative_t dr7 = read_dr7();
-	dr7 &= ~(0x2 << (curidx * 2));
+	dr7 &= ~(0x02U << (curidx * 2));
 	
 	/* Setup DR register */
@@ -147,24 +147,24 @@
 		
 		/* Set type to requested breakpoint & length*/
-		dr7 &= ~(0x3 << (16 + 4 * curidx));
-		dr7 &= ~(0x3 << (18 + 4 * curidx));
+		dr7 &= ~(0x03U << (16 + 4 * curidx));
+		dr7 &= ~(0x03U << (18 + 4 * curidx));
 		
 		if (!(flags & BKPOINT_INSTR)) {
 #ifdef __32_BITS__
-			dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx);
+			dr7 |= ((unative_t) 0x03U) << (18 + 4 * curidx);
 #endif
 			
 #ifdef __64_BITS__
-			dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx);
+			dr7 |= ((unative_t) 0x02U) << (18 + 4 * curidx);
 #endif
 			
 			if ((flags & BKPOINT_WRITE))
-				dr7 |= ((unative_t) 0x1) << (16 + 4 * curidx);
+				dr7 |= ((unative_t) 0x01U) << (16 + 4 * curidx);
 			else if ((flags & BKPOINT_READ_WRITE))
-				dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx);
+				dr7 |= ((unative_t) 0x03U) << (16 + 4 * curidx);
 		}
 		
 		/* Enable global breakpoint */
-		dr7 |= 0x2 << (curidx * 2);
+		dr7 |= 0x02U << (curidx * 2);
 		
 		write_dr7(dr7);
@@ -230,14 +230,14 @@
 				return;
 			
-			printf("*** Found ZERO on address %" PRIp " (slot %d) ***\n",
-			    breakpoints[slot].address, slot);
+			printf("*** Found ZERO on address %p (slot %d) ***\n",
+			    (void *) breakpoints[slot].address, slot);
 		} else {
-			printf("Data watchpoint - new data: %" PRIp "\n",
+			printf("Data watchpoint - new data: %#" PRIxn "\n",
 			    *((unative_t *) breakpoints[slot].address));
 		}
 	}
 	
-	printf("Reached breakpoint %d:%" PRIp " (%s)\n", slot, getip(istate),
-	    symtab_fmt_name_lookup(getip(istate)));
+	printf("Reached breakpoint %d:%p (%s)\n", slot,
+	    (void *) getip(istate), symtab_fmt_name_lookup(getip(istate)));
 	
 #ifdef CONFIG_KCONSOLE
@@ -363,12 +363,12 @@
 			
 #ifdef __32_BITS__
-			printf("%-4u %7" PRIs " %p %s\n", i,
-			    breakpoints[i].counter, breakpoints[i].address,
+			printf("%-4u %7zu %p %s\n", i,
+			    breakpoints[i].counter, (void *) breakpoints[i].address,
 			    symbol);
 #endif
 			
 #ifdef __64_BITS__
-			printf("%-4u %7" PRIs " %p %s\n", i,
-			    breakpoints[i].counter, breakpoints[i].address,
+			printf("%-4u %7zu %p %s\n", i,
+			    breakpoints[i].counter, (void *) breakpoints[i].address,
 			    symbol);
 #endif
@@ -405,7 +405,8 @@
 		flags = BKPOINT_WRITE;
 	
-	printf("Adding breakpoint on address: %p\n", argv->intval);
-	
-	int id = breakpoint_add((void *)argv->intval, flags, -1);
+	printf("Adding breakpoint on address: %p\n",
+	    (void *) argv->intval);
+	
+	int id = breakpoint_add((void *) argv->intval, flags, -1);
 	if (id < 0)
 		printf("Add breakpoint failed.\n");
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/src/interrupt.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -65,18 +65,28 @@
 void istate_decode(istate_t *istate)
 {
-	printf("cs =%p\trip=%p\trfl=%p\terr=%p\n",
-	    istate->cs, istate->rip, istate->rflags, istate->error_word);
-
+	printf("cs =%#0" PRIx64 "\trip=%p\t"
+	    "rfl=%#0" PRIx64 "\terr=%#0" PRIx64 "\n",
+	    istate->cs, (void *) istate->rip,
+	    istate->rflags, istate->error_word);
+	
 	if (istate_from_uspace(istate))
-		printf("ss =%p\n", istate->ss);
-	
-	printf("rax=%p\trbx=%p\trcx=%p\trdx=%p\n",
+		printf("ss =%#0" PRIx64 "\n", istate->ss);
+	
+	printf("rax=%#0" PRIx64 "\trbx=%#0" PRIx64 "\t"
+	    "rcx=%#0" PRIx64 "\trdx=%#0" PRIx64 "\n",
 	    istate->rax, istate->rbx, istate->rcx, istate->rdx);
+	
 	printf("rsi=%p\trdi=%p\trbp=%p\trsp=%p\n",
-	    istate->rsi, istate->rdi, istate->rbp,
-	    istate_from_uspace(istate) ? istate->rsp : (uintptr_t)&istate->rsp);
-	printf("r8 =%p\tr9 =%p\tr10=%p\tr11=%p\n",
+	    (void *) istate->rsi, (void *) istate->rdi,
+	    (void *) istate->rbp,
+	    istate_from_uspace(istate) ? ((void *) istate->rsp) :
+	    &istate->rsp);
+	
+	printf("r8 =%#0" PRIx64 "\tr9 =%#0" PRIx64 "\t"
+	    "r10=%#0" PRIx64 "\tr11=%#0" PRIx64 "\n",
 	    istate->r8, istate->r9, istate->r10, istate->r11);
-	printf("r12=%p\tr13=%p\tr14=%p\tr15=%p\n",
+	
+	printf("r12=%#0" PRIx64 "\tr13=%#0" PRIx64 "\t"
+	    "r14=%#0" PRIx64 "\tr15=%#0" PRIx64 "\n",
 	    istate->r12, istate->r13, istate->r14, istate->r15);
 }
Index: kernel/arch/amd64/src/mm/page.c
===================================================================
--- kernel/arch/amd64/src/mm/page.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/src/mm/page.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -89,5 +89,5 @@
 	
 	if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
-		fault_if_from_uspace(istate, "Page fault: %#x.", page);
+		fault_if_from_uspace(istate, "Page fault: %p.", (void *) page);
 		panic_memtrap(istate, access, page, NULL);
 	}
@@ -97,6 +97,6 @@
 {
 	if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
-		panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr,
-		    size);
+		panic("Unable to map physical memory %p (%zu bytes).",
+		    (void *) physaddr, size);
 	
 	uintptr_t virtaddr = PA2KA(last_frame);
Index: kernel/arch/amd64/src/pm.c
===================================================================
--- kernel/arch/amd64/src/pm.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/amd64/src/pm.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -28,5 +28,5 @@
  */
 
-/** @addtogroup amd64	
+/** @addtogroup amd64
  * @{
  */
@@ -52,57 +52,57 @@
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 	/* KTEXT descriptor */
-	{ .limit_0_15  = 0xffff, 
-	  .base_0_15   = 0, 
-	  .base_16_23  = 0, 
-	  .access      = AR_PRESENT | AR_CODE | DPL_KERNEL | AR_READABLE, 
-	  .limit_16_19 = 0xf, 
-	  .available   = 0, 
-	  .longmode    = 1, 
+	{ .limit_0_15  = 0xffffU,
+	  .base_0_15   = 0,
+	  .base_16_23  = 0,
+	  .access      = AR_PRESENT | AR_CODE | DPL_KERNEL | AR_READABLE,
+	  .limit_16_19 = 0x0fU,
+	  .available   = 0,
+	  .longmode    = 1,
 	  .special     = 0,
-	  .granularity = 1, 
+	  .granularity = 1,
 	  .base_24_31  = 0 },
 	/* KDATA descriptor */
-	{ .limit_0_15  = 0xffff, 
-	  .base_0_15   = 0, 
-	  .base_16_23  = 0, 
-	  .access      = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 
-	  .limit_16_19 = 0xf, 
-	  .available   = 0, 
-	  .longmode    = 0, 
-	  .special     = 0, 
-	  .granularity = 1, 
+	{ .limit_0_15  = 0xffffU,
+	  .base_0_15   = 0,
+	  .base_16_23  = 0,
+	  .access      = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL,
+	  .limit_16_19 = 0x0fU,
+	  .available   = 0,
+	  .longmode    = 0,
+	  .special     = 0,
+	  .granularity = 1,
 	  .base_24_31  = 0 },
 	/* UDATA descriptor */
-	{ .limit_0_15  = 0xffff, 
-	  .base_0_15   = 0, 
-	  .base_16_23  = 0, 
-	  .access      = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 
-	  .limit_16_19 = 0xf, 
-	  .available   = 0, 
-	  .longmode    = 0, 
-	  .special     = 1, 
-	  .granularity = 1, 
+	{ .limit_0_15  = 0xffffU,
+	  .base_0_15   = 0,
+	  .base_16_23  = 0,
+	  .access      = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER,
+	  .limit_16_19 = 0x0fU,
+	  .available   = 0,
+	  .longmode    = 0,
+	  .special     = 1,
+	  .granularity = 1,
 	  .base_24_31  = 0 },
 	/* UTEXT descriptor */
-	{ .limit_0_15  = 0xffff, 
-	  .base_0_15   = 0, 
-	  .base_16_23  = 0, 
-	  .access      = AR_PRESENT | AR_CODE | DPL_USER, 
-	  .limit_16_19 = 0xf, 
-	  .available   = 0, 
-	  .longmode    = 1, 
-	  .special     = 0, 
-	  .granularity = 1, 
+	{ .limit_0_15  = 0xffffU,
+	  .base_0_15   = 0,
+	  .base_16_23  = 0,
+	  .access      = AR_PRESENT | AR_CODE | DPL_USER,
+	  .limit_16_19 = 0x0fU,
+	  .available   = 0,
+	  .longmode    = 1,
+	  .special     = 0,
+	  .granularity = 1,
 	  .base_24_31  = 0 },
 	/* KTEXT 32-bit protected, for protected mode before long mode */
-	{ .limit_0_15  = 0xffff, 
-	  .base_0_15   = 0, 
-	  .base_16_23  = 0, 
-	  .access      = AR_PRESENT | AR_CODE | DPL_KERNEL | AR_READABLE, 
-	  .limit_16_19 = 0xf, 
-	  .available   = 0, 
-	  .longmode    = 0, 
+	{ .limit_0_15  = 0xffffU,
+	  .base_0_15   = 0,
+	  .base_16_23  = 0,
+	  .access      = AR_PRESENT | AR_CODE | DPL_KERNEL | AR_READABLE,
+	  .limit_16_19 = 0x0fU,
+	  .available   = 0,
+	  .longmode    = 0,
 	  .special     = 1,
-	  .granularity = 1, 
+	  .granularity = 1,
 	  .base_24_31  = 0 },
 	/* TSS descriptor - set up will be completed later,
@@ -111,7 +111,8 @@
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 	/* VESA Init descriptor */
-#ifdef CONFIG_FB	
-	{ 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | DPL_KERNEL,
-	  0xf, 0, 0, 0, 0, 0
+#ifdef CONFIG_FB
+	{
+		0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | DPL_KERNEL,
+		    0xf, 0, 0, 0, 0, 0
 	}
 #endif
@@ -129,8 +130,8 @@
 {
 	tss_descriptor_t *td = (tss_descriptor_t *) d;
-
-	td->base_0_15 = base & 0xffff;
-	td->base_16_23 = ((base) >> 16) & 0xff;
-	td->base_24_31 = ((base) >> 24) & 0xff;
+	
+	td->base_0_15 = base & 0xffffU;
+	td->base_16_23 = ((base) >> 16) & 0xffU;
+	td->base_24_31 = ((base) >> 24) & 0xffU;
 	td->base_32_63 = ((base) >> 32);
 }
@@ -140,6 +141,6 @@
 	tss_descriptor_t *td = (tss_descriptor_t *) d;
 	
-	td->limit_0_15 = limit & 0xffff;
-	td->limit_16_19 = (limit >> 16) & 0xf;
+	td->limit_0_15 = limit & 0xffffU;
+	td->limit_16_19 = (limit >> 16) & 0x0fU;
 }
 
@@ -149,6 +150,6 @@
 	 * Offset is a linear address.
 	 */
-	d->offset_0_15 = offset & 0xffff;
-	d->offset_16_31 = offset >> 16 & 0xffff;
+	d->offset_0_15 = offset & 0xffffU;
+	d->offset_16_31 = (offset >> 16) & 0xffffU;
 	d->offset_32_63 = offset >> 32;
 }
@@ -165,16 +166,16 @@
 {
 	idescriptor_t *d;
-	int i;
-
+	unsigned int i;
+	
 	for (i = 0; i < IDT_ITEMS; i++) {
 		d = &idt[i];
-
+		
 		d->unused = 0;
 		d->selector = GDT_SELECTOR(KTEXT_DES);
-
+		
 		d->present = 1;
-		d->type = AR_INTERRUPT;	/* masking interrupt */
+		d->type = AR_INTERRUPT;  /* masking interrupt */
 	}
-
+	
 	d = &idt[0];
 	idt_setoffset(d++, (uintptr_t) &int_0);
Index: kernel/arch/arm32/include/types.h
===================================================================
--- kernel/arch/arm32/include/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/arm32/include/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -57,24 +57,11 @@
 } fncptr_t;
 
-#define PRIp "x"  /**< Format for uintptr_t. */
-#define PRIs "u"  /**< Format for size_t. */
+#define INTN_C(c)   INT32_C(c)
+#define UINTN_C(c)  UINT32_C(c)
 
-#define PRId8 "d"     /**< Format for int8_t. */
-#define PRId16 "d"    /**< Format for int16_t. */
-#define PRId32 "d"    /**< Format for int32_t. */
-#define PRId64 "lld"  /**< Format for int64_t. */
-#define PRIdn "d"     /**< Format for native_t. */
-
-#define PRIu8 "u"     /**< Format for uint8_t. */
-#define PRIu16 "u"    /**< Format for uint16_t. */
-#define PRIu32 "u"    /**< Format for uint32_t. */
-#define PRIu64 "llu"  /**< Format for uint64_t. */
-#define PRIun "u"     /**< Format for unative_t. */
-
-#define PRIx8 "x"     /**< Format for hexadecimal (u)int8_t. */
-#define PRIx16 "x"    /**< Format for hexadecimal (u)int16_t. */
-#define PRIx32 "x"    /**< Format for hexadecimal (u)uint32_t. */
-#define PRIx64 "llx"  /**< Format for hexadecimal (u)int64_t. */
-#define PRIxn "x"     /**< Format for hexadecimal (u)native_t. */
+#define PRIdn  PRId32  /**< Format for native_t. */
+#define PRIun  PRIu32  /**< Format for unative_t. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal unative_t. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: kernel/arch/arm32/src/exception.c
===================================================================
--- kernel/arch/arm32/src/exception.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/arm32/src/exception.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -175,12 +175,17 @@
 void istate_decode(istate_t *istate)
 {
-	printf("r0 =%#0.8lx\tr1 =%#0.8lx\tr2 =%#0.8lx\tr3 =%#0.8lx\n",
+	printf("r0 =%#0" PRIx32 "\tr1 =%#0" PRIx32 "\t"
+	    "r2 =%#0" PRIx32 "\tr3 =%#0" PRIx32 "\n",
 	    istate->r0, istate->r1, istate->r2, istate->r3);
-	printf("r4 =%#0.8lx\tr5 =%#0.8lx\tr6 =%#0.8lx\tr7 =%#0.8lx\n",
+	printf("r4 =%#" PRIx32 "\tr5 =%#0" PRIx32 "\t"
+	    "r6 =%#0" PRIx32 "\tr7 =%#0" PRIx32 "\n",
 	    istate->r4, istate->r5, istate->r6, istate->r7);
-	printf("r8 =%#0.8lx\tr9 =%#0.8lx\tr10=%#0.8lx\tfp =%#0.8lx\n",
-	    istate->r8, istate->r9, istate->r10, istate->fp);
-	printf("r12=%#0.8lx\tsp =%#0.8lx\tlr =%#0.8lx\tspsr=%#0.8lx\n",
-	    istate->r12, istate->sp, istate->lr, istate->spsr);
+	printf("r8 =%#0" PRIx32 "\tr9 =%#0" PRIx32 "\t"
+	    "r10=%#0" PRIx32 "\tfp =%p\n",
+	    istate->r8, istate->r9, istate->r10,
+	    (void *) istate->fp);
+	printf("r12=%#0" PRIx32 "\tsp =%p\tlr =%p\tspsr=%p\n",
+	    istate->r12, (void *) istate->sp,
+	    (void *) istate->lr, (void *) istate->spsr);
 }
 
Index: kernel/arch/arm32/src/mm/page.c
===================================================================
--- kernel/arch/arm32/src/mm/page.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/arm32/src/mm/page.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -93,5 +93,5 @@
 	    KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) {
 		panic("Unable to map physical memory %p (%d bytes).",
-		    physaddr, size);
+		    (void *) physaddr, size);
 	}
 	
Index: kernel/arch/arm32/src/mm/page_fault.c
===================================================================
--- kernel/arch/arm32/src/mm/page_fault.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/arm32/src/mm/page_fault.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -141,5 +141,6 @@
 	if (instr.condition == 0xf) {
 		panic("page_fault - instruction does not access memory "
-		    "(instr_code: %x, badvaddr:%x).", instr, badvaddr);
+		    "(instr_code: %#0" PRIx32 ", badvaddr:%p).",
+		    instr_union.pc, (void *) badvaddr);
 		return PF_ACCESS_EXEC;
 	}
@@ -160,5 +161,6 @@
 
 	panic("page_fault - instruction doesn't access memory "
-	    "(instr_code: %x, badvaddr:%x).", instr, badvaddr);
+	    "(instr_code: %#0" PRIx32 ", badvaddr:%p).",
+	    instr_union.pc, (void *) badvaddr);
 
 	return PF_ACCESS_EXEC;
Index: kernel/arch/ia32/include/boot/boot.h
===================================================================
--- kernel/arch/ia32/include/boot/boot.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/boot/boot.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -38,5 +38,5 @@
 #define BOOT_OFFSET      0x108000
 #define AP_BOOT_OFFSET   0x8000
-#define BOOT_STACK_SIZE  0x400
+#define BOOT_STACK_SIZE  0x0400
 
 #define MULTIBOOT_HEADER_MAGIC  0x1BADB002
Index: kernel/arch/ia32/include/boot/memmap.h
===================================================================
--- kernel/arch/ia32/include/boot/memmap.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/boot/memmap.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -70,5 +70,5 @@
 
 extern e820memmap_t e820table[MEMMAP_E820_MAX_RECORDS];
-extern uint8_t e820counter; 
+extern uint8_t e820counter;
 
 #endif
Index: kernel/arch/ia32/include/context.h
===================================================================
--- kernel/arch/ia32/include/context.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/context.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -40,5 +40,5 @@
 #include <typedefs.h>
 
-#define STACK_ITEM_SIZE	4
+#define STACK_ITEM_SIZE  4
 
 /*
@@ -48,5 +48,5 @@
  * One item is put onto stack to support get_stack_base().
  */
-#define SP_DELTA	(8 + STACK_ITEM_SIZE)
+#define SP_DELTA  (8 + STACK_ITEM_SIZE)
 
 #define context_set(c, _pc, stack, size) \
Index: kernel/arch/ia32/include/context_offset.h
===================================================================
--- kernel/arch/ia32/include/context_offset.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/context_offset.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -36,33 +36,32 @@
 #define KERN_ia32_CONTEXT_OFFSET_H_
 
-#define OFFSET_SP  0x0
-#define OFFSET_PC  0x4
-#define OFFSET_EBX 0x8
-#define OFFSET_ESI 0xC
-#define OFFSET_EDI 0x10
-#define OFFSET_EBP 0x14
+#define OFFSET_SP   0x00
+#define OFFSET_PC   0x04
+#define OFFSET_EBX  0x08
+#define OFFSET_ESI  0x0C
+#define OFFSET_EDI  0x10
+#define OFFSET_EBP  0x14
 
-#ifdef KERNEL 
-# define OFFSET_IPL 0x18
+#ifdef KERNEL
+	#define OFFSET_IPL  0x18
 #else
-# define OFFSET_TLS 0x18
+	#define OFFSET_TLS  0x18
 #endif
 
+#ifdef __ASM__
 
-#ifdef __ASM__ 
-
-# ctx: address of the structure with saved context 
+# ctx: address of the structure with saved context
 # pc: return address
 
 .macro CONTEXT_SAVE_ARCH_CORE ctx:req pc:req
-	movl %esp,OFFSET_SP(\ctx)	# %esp -> ctx->sp	
+	movl %esp,OFFSET_SP(\ctx)	# %esp -> ctx->sp
 	movl \pc,OFFSET_PC(\ctx)	# %eip -> ctx->pc
-	movl %ebx,OFFSET_EBX(\ctx)	# %ebx -> ctx->ebx	
-	movl %esi,OFFSET_ESI(\ctx)	# %esi -> ctx->esi	
-	movl %edi,OFFSET_EDI(\ctx)	# %edi -> ctx->edi	
-	movl %ebp,OFFSET_EBP(\ctx)	# %ebp -> ctx->ebp	
+	movl %ebx,OFFSET_EBX(\ctx)	# %ebx -> ctx->ebx
+	movl %esi,OFFSET_ESI(\ctx)	# %esi -> ctx->esi
+	movl %edi,OFFSET_EDI(\ctx)	# %edi -> ctx->edi
+	movl %ebp,OFFSET_EBP(\ctx)	# %ebp -> ctx->ebp
 .endm
 
-# ctx: address of the structure with saved context 
+# ctx: address of the structure with saved context
 
 .macro CONTEXT_RESTORE_ARCH_CORE ctx:req pc:req
@@ -75,5 +74,5 @@
 .endm
 
-#endif /* __ASM__ */ 
+#endif /* __ASM__ */
 
 #endif
@@ -81,3 +80,2 @@
 /** @}
  */
-
Index: kernel/arch/ia32/include/cpu.h
===================================================================
--- kernel/arch/ia32/include/cpu.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/cpu.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -44,7 +44,7 @@
 
 /* Support for SYSENTER and SYSEXIT */
-#define IA32_MSR_SYSENTER_CS	0x174
-#define IA32_MSR_SYSENTER_ESP	0x175
-#define IA32_MSR_SYSENTER_EIP	0x176
+#define IA32_MSR_SYSENTER_CS   0x174U
+#define IA32_MSR_SYSENTER_ESP  0x175U
+#define IA32_MSR_SYSENTER_EIP  0x176U
 
 #ifndef __ASM__
Index: kernel/arch/ia32/include/drivers/i8259.h
===================================================================
--- kernel/arch/ia32/include/drivers/i8259.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/drivers/i8259.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -39,8 +39,8 @@
 #include <arch/interrupt.h>
 
-#define PIC_PIC0PORT1  ((ioport8_t *) 0x20)
-#define PIC_PIC0PORT2  ((ioport8_t *) 0x21)
-#define PIC_PIC1PORT1  ((ioport8_t *) 0xa0)
-#define PIC_PIC1PORT2  ((ioport8_t *) 0xa1)
+#define PIC_PIC0PORT1  ((ioport8_t *) 0x20U)
+#define PIC_PIC0PORT2  ((ioport8_t *) 0x21U)
+#define PIC_PIC1PORT1  ((ioport8_t *) 0xa0U)
+#define PIC_PIC1PORT2  ((ioport8_t *) 0xa1U)
 
 #define PIC_NEEDICW4  (1 << 0)
Index: kernel/arch/ia32/include/istate.h
===================================================================
--- kernel/arch/ia32/include/istate.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/istate.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -37,10 +37,15 @@
 
 #ifdef KERNEL
+
 #include <typedefs.h>
 #include <trace.h>
-#else
+
+#else /* KERNEL */
+
 #include <sys/types.h>
+
 #define NO_TRACE
-#endif
+
+#endif /* KERNEL */
 
 typedef struct istate {
@@ -77,5 +82,5 @@
 NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
-	return !(istate->eip & 0x80000000);
+	return !(istate->eip & UINT32_C(0x80000000));
 }
 
Index: kernel/arch/ia32/include/mm/as.h
===================================================================
--- kernel/arch/ia32/include/mm/as.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/mm/as.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -36,12 +36,12 @@
 #define KERN_ia32_AS_H_
 
-#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	0
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
 
-#define KERNEL_ADDRESS_SPACE_START_ARCH		((unsigned long) 0x80000000)
-#define KERNEL_ADDRESS_SPACE_END_ARCH		((unsigned long) 0xffffffff)
-#define USER_ADDRESS_SPACE_START_ARCH		((unsigned long) 0x00000000)
-#define USER_ADDRESS_SPACE_END_ARCH		((unsigned long) 0x7fffffff)
+#define KERNEL_ADDRESS_SPACE_START_ARCH  UINT32_C(0x80000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    UINT32_C(0xffffffff)
+#define USER_ADDRESS_SPACE_START_ARCH    UINT32_C(0x00000000)
+#define USER_ADDRESS_SPACE_END_ARCH      UINT32_C(0x7fffffff)
 
-#define USTACK_ADDRESS_ARCH	(USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))
+#define USTACK_ADDRESS_ARCH  (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))
 
 typedef struct {
@@ -50,7 +50,7 @@
 #include <genarch/mm/as_pt.h>
 
-#define as_constructor_arch(as, flags)		(as != as)
-#define as_destructor_arch(as)			(as != as)
-#define as_create_arch(as, flags)		(as != as)
+#define as_constructor_arch(as, flags)  (as != as)
+#define as_destructor_arch(as)          (as != as)
+#define as_create_arch(as, flags)       (as != as)
 #define as_install_arch(as)
 #define as_deinstall_arch(as)
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/mm/page.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -39,16 +39,20 @@
 #include <trace.h>
 
-#define PAGE_WIDTH	FRAME_WIDTH
-#define PAGE_SIZE	FRAME_SIZE
+#define PAGE_WIDTH  FRAME_WIDTH
+#define PAGE_SIZE   FRAME_SIZE
 
 #ifdef KERNEL
 
 #ifndef __ASM__
-#	define KA2PA(x)	(((uintptr_t) (x)) - 0x80000000)
-#	define PA2KA(x)	(((uintptr_t) (x)) + 0x80000000)
-#else
-#	define KA2PA(x)	((x) - 0x80000000)
-#	define PA2KA(x)	((x) + 0x80000000)
-#endif
+
+#define KA2PA(x)  (((uintptr_t) (x)) - UINT32_C(0x80000000))
+#define PA2KA(x)  (((uintptr_t) (x)) + UINT32_C(0x80000000))
+
+#else /* __ASM__ */
+
+#define KA2PA(x)  ((x) - 0x80000000)
+#define PA2KA(x)  ((x) + 0x80000000)
+
+#endif /* __ASM__ */
 
 /*
@@ -58,20 +62,20 @@
 
 /* Number of entries in each level. */
-#define PTL0_ENTRIES_ARCH	1024
-#define PTL1_ENTRIES_ARCH	0
-#define PTL2_ENTRIES_ARCH	0
-#define PTL3_ENTRIES_ARCH	1024
+#define PTL0_ENTRIES_ARCH  1024
+#define PTL1_ENTRIES_ARCH  0
+#define PTL2_ENTRIES_ARCH  0
+#define PTL3_ENTRIES_ARCH  1024
 
 /* Page table sizes for each level. */
-#define PTL0_SIZE_ARCH		ONE_FRAME
-#define PTL1_SIZE_ARCH		0
-#define PTL2_SIZE_ARCH		0
-#define PTL3_SIZE_ARCH		ONE_FRAME
+#define PTL0_SIZE_ARCH  ONE_FRAME
+#define PTL1_SIZE_ARCH  0
+#define PTL2_SIZE_ARCH  0
+#define PTL3_SIZE_ARCH  ONE_FRAME
 
 /* Macros calculating indices for each level. */
-#define PTL0_INDEX_ARCH(vaddr)	(((vaddr) >> 22) & 0x3ff)
-#define PTL1_INDEX_ARCH(vaddr)	0
-#define PTL2_INDEX_ARCH(vaddr)	0
-#define PTL3_INDEX_ARCH(vaddr)	(((vaddr) >> 12) & 0x3ff)
+#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 22) & 0x3ffU)
+#define PTL1_INDEX_ARCH(vaddr)  0
+#define PTL2_INDEX_ARCH(vaddr)  0
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x3ffU)
 
 /* Get PTE address accessors for each level. */
@@ -122,5 +126,5 @@
 #define PTE_WRITABLE_ARCH(p) \
 	((p)->writeable != 0)
-#define PTE_EXECUTABLE_ARCH(p)			1
+#define PTE_EXECUTABLE_ARCH(p)  1
 
 #ifndef __ASM__
@@ -144,5 +148,5 @@
 
 /** When bit on this position is 1, a reserved bit was set in page directory. */ 
-#define PFERR_CODE_RSVD		(1 << 3)	
+#define PFERR_CODE_RSVD		(1 << 3)
 
 /** Page Table Entry. */
Index: kernel/arch/ia32/include/smp/ap.h
===================================================================
--- kernel/arch/ia32/include/smp/ap.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/smp/ap.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
Index: kernel/arch/ia32/include/smp/apic.h
===================================================================
--- kernel/arch/ia32/include/smp/apic.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/smp/apic.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -49,63 +49,63 @@
 
 /** Delivery modes. */
-#define DELMOD_FIXED    0x0
-#define DELMOD_LOWPRI   0x1
-#define DELMOD_SMI      0x2
+#define DELMOD_FIXED    0x0U
+#define DELMOD_LOWPRI   0x1U
+#define DELMOD_SMI      0x2U
 /* 0x3 reserved */
-#define DELMOD_NMI      0x4
-#define DELMOD_INIT     0x5
-#define DELMOD_STARTUP  0x6
-#define DELMOD_EXTINT   0x7
+#define DELMOD_NMI      0x4U
+#define DELMOD_INIT     0x5U
+#define DELMOD_STARTUP  0x6U
+#define DELMOD_EXTINT   0x7U
 
 /** Destination modes. */
-#define DESTMOD_PHYS   0x0
-#define DESTMOD_LOGIC  0x1
+#define DESTMOD_PHYS   0x0U
+#define DESTMOD_LOGIC  0x1U
 
 /** Trigger Modes. */
-#define TRIGMOD_EDGE   0x0
-#define TRIGMOD_LEVEL  0x1
+#define TRIGMOD_EDGE   0x0U
+#define TRIGMOD_LEVEL  0x1U
 
 /** Levels. */
-#define LEVEL_DEASSERT  0x0
-#define LEVEL_ASSERT    0x1
+#define LEVEL_DEASSERT  0x0U
+#define LEVEL_ASSERT    0x1U
 
 /** Destination Shorthands. */
-#define SHORTHAND_NONE      0x0
-#define SHORTHAND_SELF      0x1
-#define SHORTHAND_ALL_INCL  0x2
-#define SHORTHAND_ALL_EXCL  0x3
+#define SHORTHAND_NONE      0x0U
+#define SHORTHAND_SELF      0x1U
+#define SHORTHAND_ALL_INCL  0x2U
+#define SHORTHAND_ALL_EXCL  0x3U
 
 /** Interrupt Input Pin Polarities. */
-#define POLARITY_HIGH  0x0
-#define POLARITY_LOW   0x1
+#define POLARITY_HIGH  0x0U
+#define POLARITY_LOW   0x1U
 
 /** Divide Values. (Bit 2 is always 0) */
-#define DIVIDE_2    0x0
-#define DIVIDE_4    0x1
-#define DIVIDE_8    0x2
-#define DIVIDE_16   0x3
-#define DIVIDE_32   0x8
-#define DIVIDE_64   0x9
-#define DIVIDE_128  0xa
-#define DIVIDE_1    0xb
+#define DIVIDE_2    0x0U
+#define DIVIDE_4    0x1U
+#define DIVIDE_8    0x2U
+#define DIVIDE_16   0x3U
+#define DIVIDE_32   0x8U
+#define DIVIDE_64   0x9U
+#define DIVIDE_128  0xaU
+#define DIVIDE_1    0xbU
 
 /** Timer Modes. */
-#define TIMER_ONESHOT   0x0
-#define TIMER_PERIODIC  0x1
+#define TIMER_ONESHOT   0x0U
+#define TIMER_PERIODIC  0x1U
 
 /** Delivery status. */
-#define DELIVS_IDLE     0x0
-#define DELIVS_PENDING  0x1
+#define DELIVS_IDLE     0x0U
+#define DELIVS_PENDING  0x1U
 
 /** Destination masks. */
-#define DEST_ALL  0xff
+#define DEST_ALL  0xffU
 
 /** Dest format models. */
-#define MODEL_FLAT     0xf
-#define MODEL_CLUSTER  0x0
+#define MODEL_FLAT     0xfU
+#define MODEL_CLUSTER  0x0U
 
 /** Interrupt Command Register. */
-#define ICRlo  (0x300 / sizeof(uint32_t))
-#define ICRhi  (0x310 / sizeof(uint32_t))
+#define ICRlo  (0x300U / sizeof(uint32_t))
+#define ICRhi  (0x310U / sizeof(uint32_t))
 
 typedef struct {
@@ -135,8 +135,8 @@
 
 /* End Of Interrupt. */
-#define EOI  (0x0b0 / sizeof(uint32_t))
+#define EOI  (0x0b0U / sizeof(uint32_t))
 
 /** Error Status Register. */
-#define ESR  (0x280 / sizeof(uint32_t))
+#define ESR  (0x280U / sizeof(uint32_t))
 
 typedef union {
@@ -157,5 +157,5 @@
 
 /* Task Priority Register */
-#define TPR  (0x080 / sizeof(uint32_t))
+#define TPR  (0x080U / sizeof(uint32_t))
 
 typedef union {
@@ -168,5 +168,5 @@
 
 /** Spurious-Interrupt Vector Register. */
-#define SVR  (0x0f0 / sizeof(uint32_t))
+#define SVR  (0x0f0U / sizeof(uint32_t))
 
 typedef union {
@@ -181,5 +181,5 @@
 
 /** Time Divide Configuration Register. */
-#define TDCR  (0x3e0 / sizeof(uint32_t))
+#define TDCR  (0x3e0U / sizeof(uint32_t))
 
 typedef union {
@@ -192,11 +192,11 @@
 
 /* Initial Count Register for Timer */
-#define ICRT  (0x380 / sizeof(uint32_t))
+#define ICRT  (0x380U / sizeof(uint32_t))
 
 /* Current Count Register for Timer */
-#define CCRT  (0x390 / sizeof(uint32_t))
+#define CCRT  (0x390U / sizeof(uint32_t))
 
 /** LVT Timer register. */
-#define LVT_Tm  (0x320 / sizeof(uint32_t))
+#define LVT_Tm  (0x320U / sizeof(uint32_t))
 
 typedef union {
@@ -214,6 +214,6 @@
 
 /** LVT LINT registers. */
-#define LVT_LINT0  (0x350 / sizeof(uint32_t))
-#define LVT_LINT1  (0x360 / sizeof(uint32_t))
+#define LVT_LINT0  (0x350U / sizeof(uint32_t))
+#define LVT_LINT1  (0x360U / sizeof(uint32_t))
 
 typedef union {
@@ -233,5 +233,5 @@
 
 /** LVT Error register. */
-#define LVT_Err  (0x370 / sizeof(uint32_t))
+#define LVT_Err  (0x370U / sizeof(uint32_t))
 
 typedef union {
@@ -248,5 +248,5 @@
 
 /** Local APIC ID Register. */
-#define L_APIC_ID  (0x020 / sizeof(uint32_t))
+#define L_APIC_ID  (0x020U / sizeof(uint32_t))
 
 typedef union {
@@ -259,13 +259,13 @@
 
 /** Local APIC Version Register */
-#define LAVR       (0x030 / sizeof(uint32_t))
-#define LAVR_Mask  0xff
-
-#define is_local_apic(x)    (((x) & LAVR_Mask & 0xf0) == 0x1)
-#define is_82489DX_apic(x)  ((((x) & LAVR_Mask & 0xf0) == 0x0))
-#define is_local_xapic(x)   (((x) & LAVR_Mask) == 0x14)
+#define LAVR       (0x030U / sizeof(uint32_t))
+#define LAVR_Mask  0xffU
+
+#define is_local_apic(x)    (((x) & LAVR_Mask & 0xf0U) == 0x1U)
+#define is_82489DX_apic(x)  ((((x) & LAVR_Mask & 0xf0U) == 0x0U))
+#define is_local_xapic(x)   (((x) & LAVR_Mask) == 0x14U)
 
 /** Logical Destination Register. */
-#define  LDR  (0x0d0 / sizeof(uint32_t))
+#define  LDR  (0x0d0U / sizeof(uint32_t))
 
 typedef union {
@@ -278,5 +278,5 @@
 
 /** Destination Format Register. */
-#define DFR  (0x0e0 / sizeof(uint32_t))
+#define DFR  (0x0e0U / sizeof(uint32_t))
 
 typedef union {
@@ -289,11 +289,11 @@
 
 /* IO APIC */
-#define IOREGSEL  (0x00 / sizeof(uint32_t))
-#define IOWIN     (0x10 / sizeof(uint32_t))
-
-#define IOAPICID   0x00
-#define IOAPICVER  0x01
-#define IOAPICARB  0x02
-#define IOREDTBL   0x10
+#define IOREGSEL  (0x00U / sizeof(uint32_t))
+#define IOWIN     (0x10U / sizeof(uint32_t))
+
+#define IOAPICID   0x00U
+#define IOAPICVER  0x01U
+#define IOAPICARB  0x02U
+#define IOREDTBL   0x10U
 
 /** I/O Register Select Register. */
Index: kernel/arch/ia32/include/types.h
===================================================================
--- kernel/arch/ia32/include/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/include/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -50,24 +50,11 @@
 } fncptr_t;
 
-#define PRIp "x"  /**< Format for uintptr_t. */
-#define PRIs "u"  /**< Format for size_t. */
+#define INTN_C(c)   INT32_C(c)
+#define UINTN_C(c)  UINT32_C(c)
 
-#define PRId8 "d"     /**< Format for int8_t. */
-#define PRId16 "d"    /**< Format for int16_t. */
-#define PRId32 "d"    /**< Format for int32_t. */
-#define PRId64 "lld"  /**< Format for int64_t. */
-#define PRIdn "d"     /**< Format for native_t. */
-
-#define PRIu8 "u"     /**< Format for uint8_t. */
-#define PRIu16 "u"    /**< Format for uint16_t. */
-#define PRIu32 "u"    /**< Format for uint32_t. */
-#define PRIu64 "llu"  /**< Format for uint64_t. */
-#define PRIun "u"     /**< Format for unative_t. */
-
-#define PRIx8 "x"     /**< Format for hexadecimal (u)int8_t. */
-#define PRIx16 "x"    /**< Format for hexadecimal (u)int16_t. */
-#define PRIx32 "x"    /**< Format for hexadecimal (u)uint32_t. */
-#define PRIx64 "llx"  /**< Format for hexadecimal (u)int64_t. */
-#define PRIxn "x"     /**< Format for hexadecimal (u)native_t. */
+#define PRIdn  PRId32  /**< Format for native_t. */
+#define PRIun  PRIu32  /**< Format for unative_t. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal unative_t. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: kernel/arch/ia32/src/bios/bios.c
===================================================================
--- kernel/arch/ia32/src/bios/bios.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/bios/bios.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -36,5 +36,5 @@
 #include <typedefs.h>
 
-#define BIOS_EBDA_PTR  0x40e
+#define BIOS_EBDA_PTR  0x40eU
 
 uintptr_t ebda = 0;
@@ -43,5 +43,5 @@
 {
 	/* Copy the EBDA address out from BIOS Data Area */
-	ebda = *((uint16_t *) BIOS_EBDA_PTR) * 0x10;
+	ebda = *((uint16_t *) BIOS_EBDA_PTR) * 0x10U;
 }
 
Index: kernel/arch/ia32/src/boot/memmap.c
===================================================================
--- kernel/arch/ia32/src/boot/memmap.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/boot/memmap.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -35,5 +35,5 @@
 #include <arch/boot/memmap.h>
 
-uint8_t e820counter = 0xff;
+uint8_t e820counter = 0xffU;
 e820memmap_t e820table[MEMMAP_E820_MAX_RECORDS];
 
Index: kernel/arch/ia32/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia32/src/cpu/cpu.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/cpu/cpu.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -49,11 +49,11 @@
  * Contains only non-MP-Specification specific SMP code.
  */
-#define AMD_CPUID_EBX  0x68747541
-#define AMD_CPUID_ECX  0x444d4163
-#define AMD_CPUID_EDX  0x69746e65
+#define AMD_CPUID_EBX  UINT32_C(0x68747541)
+#define AMD_CPUID_ECX  UINT32_C(0x444d4163)
+#define AMD_CPUID_EDX  UINT32_C(0x69746e65)
 
-#define INTEL_CPUID_EBX  0x756e6547
-#define INTEL_CPUID_ECX  0x6c65746e
-#define INTEL_CPUID_EDX  0x49656e69
+#define INTEL_CPUID_EBX  UINT32_C(0x756e6547)
+#define INTEL_CPUID_ECX  UINT32_C(0x6c65746e)
+#define INTEL_CPUID_EDX  UINT32_C(0x49656e69)
 
 
@@ -140,19 +140,19 @@
 		if ((info.cpuid_ebx == AMD_CPUID_EBX)
 		    && (info.cpuid_ecx == AMD_CPUID_ECX)
-			&& (info.cpuid_edx == AMD_CPUID_EDX))
+		    && (info.cpuid_edx == AMD_CPUID_EDX))
 			CPU->arch.vendor = VendorAMD;
 		
 		/*
 		 * Check for Intel processor.
-		 */		
+		 */
 		if ((info.cpuid_ebx == INTEL_CPUID_EBX)
 		    && (info.cpuid_ecx == INTEL_CPUID_ECX)
-			&& (info.cpuid_edx == INTEL_CPUID_EDX))
+		    && (info.cpuid_edx == INTEL_CPUID_EDX))
 			CPU->arch.vendor = VendorIntel;
 		
 		cpuid(INTEL_CPUID_STANDARD, &info);
-		CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f;
-		CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f;
-		CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f;						
+		CPU->arch.family = (info.cpuid_eax >> 8) & 0x0fU;
+		CPU->arch.model = (info.cpuid_eax >> 4) & 0x0fU;
+		CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0fU;
 	}
 }
Index: kernel/arch/ia32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia32/src/debug/stacktrace.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/debug/stacktrace.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -37,6 +37,6 @@
 #include <typedefs.h>
 
-#define FRAME_OFFSET_FP_PREV	0
-#define FRAME_OFFSET_RA		1
+#define FRAME_OFFSET_FP_PREV  0
+#define FRAME_OFFSET_RA       1
 
 bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
Index: kernel/arch/ia32/src/drivers/i8254.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8254.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/drivers/i8254.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -54,6 +54,6 @@
 #include <ddi/device.h>
 
-#define CLK_PORT1  ((ioport8_t *) 0x40)
-#define CLK_PORT4  ((ioport8_t *) 0x43)
+#define CLK_PORT1  ((ioport8_t *) 0x40U)
+#define CLK_PORT4  ((ioport8_t *) 0x43U)
 
 #define CLK_CONST     1193180
Index: kernel/arch/ia32/src/drivers/i8259.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8259.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/drivers/i8259.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -121,6 +121,6 @@
 void pic_eoi(void)
 {
-	pio_write_8((ioport8_t *)0x20, 0x20);
-	pio_write_8((ioport8_t *)0xa0, 0x20);
+	pio_write_8((ioport8_t *) 0x20, 0x20);
+	pio_write_8((ioport8_t *) 0xa0, 0x20);
 }
 
Index: kernel/arch/ia32/src/drivers/vesa.c
===================================================================
--- kernel/arch/ia32/src/drivers/vesa.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/drivers/vesa.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -70,5 +70,5 @@
 bool vesa_init(void)
 {
-	if ((vesa_width == 0xffff) || (vesa_height == 0xffff))
+	if ((vesa_width == 0xffffU) || (vesa_height == 0xffffU))
 		return false;
 	
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/interrupt.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -65,17 +65,25 @@
 void istate_decode(istate_t *istate)
 {
-	printf("cs =%p\teip=%p\tefl=%p\terr=%p\n",
-	    istate->cs, istate->eip, istate->eflags, istate->error_word);
-
-	printf("ds =%p\tes =%p\tfs =%p\tgs =%p\n",
+	printf("cs =%#0" PRIx32 "\teip=%p\t"
+	    "efl=%#0" PRIx32 "\terr=%#0" PRIx32 "\n",
+	    istate->cs, (void *) istate->eip,
+	    istate->eflags, istate->error_word);
+	
+	printf("ds =%#0" PRIx32 "\tes =%#0" PRIx32 "\t"
+	    "fs =%#0" PRIx32 "\tgs =%#0" PRIx32 "\n",
 	    istate->ds, istate->es, istate->fs, istate->gs);
+	
 	if (istate_from_uspace(istate))
-		printf("ss =%p\n", istate->ss);
-
-	printf("eax=%p\tebx=%p\tecx=%p\tedx=%p\n",
+		printf("ss =%#0" PRIx32 "\n", istate->ss);
+	
+	printf("eax=%#0" PRIx32 "\tebx=%#0" PRIx32 "\t"
+	    "ecx=%#0" PRIx32 "\tedx=%#0" PRIx32 "\n",
 	    istate->eax, istate->ebx, istate->ecx, istate->edx);
+	
 	printf("esi=%p\tedi=%p\tebp=%p\tesp=%p\n",
-	    istate->esi, istate->edi, istate->ebp,
-	    istate_from_uspace(istate) ? istate->esp : (uintptr_t)&istate->esp);
+	    (void *) istate->esi, (void *) istate->edi,
+	    (void *) istate->ebp,
+	    istate_from_uspace(istate) ? ((void *) istate->esp) :
+	    &istate->esp);
 }
 
@@ -139,7 +147,7 @@
 	);
 	
-	fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR=%#0.8x.",
-	    (unative_t) mxcsr);
-	panic_badtrap(istate, n, "SIMD FP exception, MXCSR=%#0.8x");
+	fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR=%#0" PRIx32 ".",
+	    mxcsr);
+	panic_badtrap(istate, n, "SIMD FP exception");
 }
 
Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/mm/frame.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -44,9 +44,8 @@
 #include <align.h>
 #include <macros.h>
-
 #include <print.h>
 
-#define PHYSMEM_LIMIT32  0x07c000000ull
-#define PHYSMEM_LIMIT64  0x200000000ull
+#define PHYSMEM_LIMIT32  UINT64_C(0x07c000000)
+#define PHYSMEM_LIMIT64  UINT64_C(0x200000000)
 
 size_t hardcoded_unmapped_ktext_size = 0;
Index: kernel/arch/ia32/src/mm/page.c
===================================================================
--- kernel/arch/ia32/src/mm/page.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/mm/page.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -82,5 +82,6 @@
 {
 	if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
-		panic("Unable to map physical memory %p (%d bytes).", physaddr, size);
+		panic("Unable to map physical memory %p (%zu bytes).",
+		    (void *) physaddr, size);
 	
 	uintptr_t virtaddr = PA2KA(last_frame);
Index: kernel/arch/ia32/src/smp/apic.c
===================================================================
--- kernel/arch/ia32/src/smp/apic.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/smp/apic.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -72,6 +72,6 @@
  *
  */
-volatile uint32_t *l_apic = (uint32_t *) 0xfee00000;
-volatile uint32_t *io_apic = (uint32_t *) 0xfec00000;
+volatile uint32_t *l_apic = (uint32_t *) UINT32_C(0xfee00000);
+volatile uint32_t *io_apic = (uint32_t *) UINT32_C(0xfec00000);
 
 uint32_t apic_id_mask = 0;
@@ -184,5 +184,5 @@
 	 * Other interrupts will be forwarded to the lowest priority CPU.
 	 */
-	io_apic_disable_irqs(0xffff);
+	io_apic_disable_irqs(0xffffU);
 	
 	irq_initialize(&l_apic_timer_irq);
@@ -477,5 +477,5 @@
 {
 #ifdef LAPIC_VERBOSE
-	printf("LVT on cpu%" PRIs ", LAPIC ID: %" PRIu8 "\n",
+	printf("LVT on cpu%u, LAPIC ID: %" PRIu8 "\n",
 	    CPU->id, l_apic_id());
 	
Index: kernel/arch/ia32/src/smp/mps.c
===================================================================
--- kernel/arch/ia32/src/smp/mps.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia32/src/smp/mps.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -52,6 +52,6 @@
  */
 
-#define FS_SIGNATURE  0x5f504d5f
-#define CT_SIGNATURE  0x504d4350
+#define FS_SIGNATURE  UINT32_C(0x5f504d5f)
+#define CT_SIGNATURE  UINT32_C(0x504d4350)
 
 static struct mps_fs *fs;
Index: kernel/arch/ia64/include/types.h
===================================================================
--- kernel/arch/ia64/include/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia64/include/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -52,24 +52,11 @@
 } __attribute__((may_alias)) fncptr_t;
 
-#define PRIp "lx"  /**< Format for uintptr_t. */
-#define PRIs "lu"  /**< Format for size_t. */
+#define INTN_C(c)   INT64_C(c)
+#define UINTN_C(c)  UINT64_C(c)
 
-#define PRId8 "d"    /**< Format for int8_t. */
-#define PRId16 "d"   /**< Format for int16_t. */
-#define PRId32 "d"   /**< Format for int32_t. */
-#define PRId64 "ld"  /**< Format for int64_t. */
-#define PRIdn "d"    /**< Format for native_t. */
-
-#define PRIu8 "u"    /**< Format for uint8_t. */
-#define PRIu16 "u"   /**< Format for uint16_t. */
-#define PRIu32 "u"   /**< Format for uint32_t. */
-#define PRIu64 "lu"  /**< Format for uint64_t. */
-#define PRIun "u"    /**< Format for unative_t. */
-
-#define PRIx8 "x"    /**< Format for hexadecimal (u)int8_t. */
-#define PRIx16 "x"   /**< Format for hexadecimal (u)int16_t. */
-#define PRIx32 "x"   /**< Format for hexadecimal (u)uint32_t. */
-#define PRIx64 "lx"  /**< Format for hexadecimal (u)int64_t. */
-#define PRIxn "x"    /**< Format for hexadecimal (u)native_t. */
+#define PRIdn  PRId64  /**< Format for native_t. */
+#define PRIun  PRIu64  /**< Format for unative_t. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal unative_t. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
 
 #endif
Index: kernel/arch/ia64/src/interrupt.c
===================================================================
--- kernel/arch/ia64/src/interrupt.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia64/src/interrupt.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -135,18 +135,19 @@
 void istate_decode(istate_t *istate)
 {
-	printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
-	    istate->ar_bspstore);
-	printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
-	    istate->ar_rsc);
-	printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
-	    istate->ar_pfs);
-	printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
-	    istate->cr_ipsr);
-	
-	printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip, istate->cr_isr.ei,
+	printf("ar.bsp=%p\tar.bspstore=%p\n",
+	    (void *) istate->ar_bsp, (void *) istate->ar_bspstore);
+	printf("ar.rnat=%#0" PRIx64 "\tar.rsc=%#0" PRIx64 "\n",
+	    istate->ar_rnat, istate->ar_rsc);
+	printf("ar.ifs=%#0" PRIx64 "\tar.pfs=%#0" PRIx64 "\n",
+	    istate->ar_ifs, istate->ar_pfs);
+	printf("cr.isr=%#0" PRIx64 "\tcr.ipsr=%#0" PRIx64 "\n",
+	    istate->cr_isr.value, istate->cr_ipsr.value);
+	
+	printf("cr.iip=%#0" PRIx64 ", #%u\t(%s)\n",
+	    istate->cr_iip, istate->cr_isr.ei,
 	    symtab_fmt_name_lookup(istate->cr_iip));
-	printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa,
+	printf("cr.iipa=%#0" PRIx64 "\t(%s)\n", istate->cr_iipa,
 	    symtab_fmt_name_lookup(istate->cr_iipa));
-	printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa,
+	printf("cr.ifa=%#0" PRIx64 "\t(%s)\n", istate->cr_ifa,
 	    symtab_fmt_name_lookup(istate->cr_ifa));
 }
Index: kernel/arch/ia64/src/mm/tlb.c
===================================================================
--- kernel/arch/ia64/src/mm/tlb.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ia64/src/mm/tlb.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -499,5 +499,6 @@
 		page_table_unlock(AS, true);
 		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate, "Page fault at %p.", va);
+			fault_if_from_uspace(istate, "Page fault at %p.",
+			    (void *) va);
 			panic_memtrap(istate, PF_ACCESS_EXEC, va, NULL);
 		}
@@ -556,5 +557,5 @@
 			} else {
 				fault_if_from_uspace(istate,
-				    "IO access fault at %p.", va);
+				    "IO access fault at %p.", (void *) va);
 			}
 		}
@@ -620,5 +621,6 @@
 		 */
 		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate, "Page fault at %p.", va);
+			fault_if_from_uspace(istate, "Page fault at %p.",
+			    (void *) va);
 			panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, NULL);
 		}
@@ -668,5 +670,6 @@
 	} else {
 		if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate, "Page fault at %p.", va);
+			fault_if_from_uspace(istate, "Page fault at %p.",
+			    (void *) va);
 			panic_memtrap(istate, PF_ACCESS_WRITE, va, NULL);
 		}
@@ -704,5 +707,6 @@
 	} else {
 		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate, "Page fault at %p.", va);
+			fault_if_from_uspace(istate, "Page fault at %p.",
+			    (void *) va);
 			panic_memtrap(istate, PF_ACCESS_EXEC, va, NULL);
 		}
@@ -740,5 +744,6 @@
 	} else {
 		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate, "Page fault at %p.", va);
+			fault_if_from_uspace(istate, "Page fault at %p.",
+			    (void *) va);
 			panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, NULL);
 		}
@@ -772,5 +777,6 @@
 	ASSERT(!t->w);
 	if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
-		fault_if_from_uspace(istate, "Page fault at %p.", va);
+		fault_if_from_uspace(istate, "Page fault at %p.",
+		    (void *) va);
 		panic_memtrap(istate, PF_ACCESS_WRITE, va, NULL);
 	}
@@ -812,5 +818,6 @@
 		page_table_unlock(AS, true);
 		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate, "Page fault at %p.", va);
+			fault_if_from_uspace(istate, "Page fault at %p.",
+			    (void *) va);
 			panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, NULL);
 		}
Index: kernel/arch/mips32/include/types.h
===================================================================
--- kernel/arch/mips32/include/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/mips32/include/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -50,24 +50,11 @@
 } fncptr_t;
 
-#define PRIp "x"  /**< Format for uintptr_t. */
-#define PRIs "u"  /**< Format for size_t. */
+#define INTN_C(c)   INT32_C(c)
+#define UINTN_C(c)  UINT32_C(c)
 
-#define PRId8 "d"     /**< Format for int8_t. */
-#define PRId16 "d"    /**< Format for int16_t. */
-#define PRId32 "ld"   /**< Format for int32_t. */
-#define PRId64 "lld"  /**< Format for int64_t. */
-#define PRIdn "d"     /**< Format for native_t. */
-
-#define PRIu8 "u"     /**< Format for uint8_t. */
-#define PRIu16 "u"    /**< Format for uint16_t. */
-#define PRIu32 "u"    /**< Format for uint32_t. */
-#define PRIu64 "llu"  /**< Format for uint64_t. */
-#define PRIun "u"     /**< Format for unative_t. */
-
-#define PRIx8 "x"     /**< Format for hexadecimal (u)int8_t. */
-#define PRIx16 "x"    /**< Format for hexadecimal (u)int16_t. */
-#define PRIx32 "x"    /**< Format for hexadecimal (u)uint32_t. */
-#define PRIx64 "llx"  /**< Format for hexadecimal (u)int64_t. */
-#define PRIxn "x"     /**< Format for hexadecimal (u)native_t. */
+#define PRIdn  PRId32  /**< Format for native_t. */
+#define PRIun  PRIu32  /**< Format for unative_t. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal unative_t. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: kernel/arch/mips32/src/cache.c
===================================================================
--- kernel/arch/mips32/src/cache.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/mips32/src/cache.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -39,5 +39,5 @@
 void cache_error(istate_t *istate)
 {
-	panic("cache_error exception (epc=%p).", istate->epc);
+	panic("cache_error exception (epc=%p).", (void *) istate->epc);
 }
 
Index: kernel/arch/mips32/src/debugger.c
===================================================================
--- kernel/arch/mips32/src/debugger.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/mips32/src/debugger.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -191,5 +191,5 @@
 	}
 	
-	printf("Adding breakpoint on address %p\n", argv->intval);
+	printf("Adding breakpoint on address %p\n", (void *) argv->intval);
 	
 	cur->address = (uintptr_t) argv->intval;
@@ -267,6 +267,6 @@
 			    breakpoints[i].address);
 			
-			printf("%-4u %7" PRIs " %p %-8s %-9s %-10s %s\n", i,
-			    breakpoints[i].counter, breakpoints[i].address,
+			printf("%-4u %7zu %p %-8s %-9s %-10s %s\n", i,
+			    breakpoints[i].counter, (void *) breakpoints[i].address,
 			    ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
 			    "false"), ((breakpoints[i].flags & BKPOINT_ONESHOT)
@@ -366,5 +366,6 @@
 		
 		if (!(cur->flags & BKPOINT_FUNCCALL)) {
-			printf("***Breakpoint %u: %p in %s.\n", i, fireaddr,
+			printf("***Breakpoint %u: %p in %s.\n", i,
+			    (void *) fireaddr,
 			    symtab_fmt_name_lookup(fireaddr));
 		}
@@ -381,5 +382,6 @@
 		cur->flags |= BKPOINT_INPROG;
 	} else {
-		printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
+		printf("***Breakpoint %d: %p in %s.\n", i,
+		    (void *) fireaddr,
 		    symtab_fmt_name_lookup(fireaddr));
 		
Index: kernel/arch/mips32/src/exception.c
===================================================================
--- kernel/arch/mips32/src/exception.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/mips32/src/exception.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -74,22 +74,40 @@
 void istate_decode(istate_t *istate)
 {
-	printf("epc=%p\tsta=%p\tlo =%p\thi =%p\n",
-	    istate->epc, istate->status, istate->lo, istate->hi);
-	printf("a0 =%p\ta1 =%p\ta2 =%p\ta3 =%p\n",
+	printf("epc=%p\tsta=%#0" PRIx32 "\t"
+	    "lo =%#0" PRIx32 "\thi =%#0" PRIx32 "\n",
+	    (void *) istate->epc, istate->status,
+	    istate->lo, istate->hi);
+	
+	printf("a0 =%#0" PRIx32 "\ta1 =%#0" PRIx32 "\t"
+	    "a2 =%#0" PRIx32 "\ta3 =%#0" PRIx32 "\n",
 	    istate->a0, istate->a1, istate->a2, istate->a3);
-	printf("t0 =%p\tt1 =%p\tt2 =%p\tt3 =%p\n",
+	
+	printf("t0 =%#0" PRIx32 "\tt1 =%#0" PRIx32 "\t"
+	    "t2 =%#0" PRIx32 "\tt3 =%#0" PRIx32 "\n",
 	    istate->t0, istate->t1, istate->t2, istate->t3);
-	printf("t4 =%p\tt5 =%p\tt6 =%p\tt7 =%p\n",
+	
+	printf("t4 =%#0" PRIx32 "\tt5 =%#0" PRIx32 "\t"
+	    "t6 =%#0" PRIx32 "\tt7 =%#0" PRIx32 "\n",
 	    istate->t4, istate->t5, istate->t6, istate->t7);
-	printf("t8 =%p\tt9 =%p\tv0 =%p\tv1 =%p\n",
+	
+	printf("t8 =%#0" PRIx32 "\tt9 =%#0" PRIx32 "\t"
+	    "v0 =%#0" PRIx32 "\tv1 =%#0" PRIx32 "\n",
 	    istate->t8, istate->t9, istate->v0, istate->v1);
-	printf("s0 =%p\ts1 =%p\ts2 =%p\ts3 =%p\n",
+	
+	printf("s0 =%#0" PRIx32 "\ts1 =%#0" PRIx32 "\t"
+	    "s2 =%#0" PRIx32 "\ts3 =%#0" PRIx32 "\n",
 	    istate->s0, istate->s1, istate->s2, istate->s3);
-	printf("s4 =%p\ts5 =%p\ts6 =%p\ts7 =%p\n",
+	
+	printf("s4 =%#0" PRIx32 "\ts5 =%#0" PRIx32 "\t"
+	    "s6 =%#0" PRIx32 "\ts7 =%#0" PRIx32 "\n",
 	    istate->s4, istate->s5, istate->s6, istate->s7);
-	printf("s8 =%p\tat =%p\tkt0=%p\tkt1=%p\n",
+	
+	printf("s8 =%#0" PRIx32 "\tat =%#0" PRIx32 "\t"
+	    "kt0=%#0" PRIx32 "\tkt1=%#0" PRIx32 "\n",
 	    istate->s8, istate->at, istate->kt0, istate->kt1);
+	
 	printf("sp =%p\tra =%p\tgp =%p\n",
-	    istate->sp, istate->ra, istate->gp);
+	    (void *) istate->sp, (void *) istate->ra,
+	    (void *) istate->gp);
 }
 
Index: kernel/arch/mips32/src/mm/tlb.c
===================================================================
--- kernel/arch/mips32/src/mm/tlb.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/mips32/src/mm/tlb.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -323,5 +323,6 @@
 	uintptr_t va = cp0_badvaddr_read();
 	
-	fault_if_from_uspace(istate, "TLB Refill Exception on %p.", va);
+	fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
+	    (void *) va);
 	panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Refill Exception.");
 }
@@ -332,5 +333,6 @@
 	uintptr_t va = cp0_badvaddr_read();
 	
-	fault_if_from_uspace(istate, "TLB Invalid Exception on %p.", va);
+	fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
+	    (void *) va);
 	panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Invalid Exception.");
 }
@@ -340,5 +342,6 @@
 	uintptr_t va = cp0_badvaddr_read();
 	
-	fault_if_from_uspace(istate, "TLB Modified Exception on %p.", va);
+	fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
+	    (void *) va);
 	panic_memtrap(istate, PF_ACCESS_WRITE, va, "TLB Modified Exception.");
 }
Index: kernel/arch/ppc32/include/types.h
===================================================================
--- kernel/arch/ppc32/include/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ppc32/include/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -50,26 +50,11 @@
 } fncptr_t;
 
-/** Formats for uintptr_t, size_t */
-#define PRIp  "x"
-#define PRIs  "u"
+#define INTN_C(c)   INT32_C(c)
+#define UINTN_C(c)  UINT32_C(c)
 
-/** Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
-#define PRId8   "d"
-#define PRId16  "d"
-#define PRId32  "d"
-#define PRId64  "lld"
-#define PRIdn   "d"
-
-#define PRIu8   "u"
-#define PRIu16  "u"
-#define PRIu32  "u"
-#define PRIu64  "llu"
-#define PRIun   "u"
-
-#define PRIx8   "x"
-#define PRIx16  "x"
-#define PRIx32  "x"
-#define PRIx64  "llx"
-#define PRIxn   "x"
+#define PRIdn  PRId32  /**< Format for native_t. */
+#define PRIun  PRIu32  /**< Format for unative_t. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal unative_t. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: kernel/arch/ppc32/src/cpu/cpu.c
===================================================================
--- kernel/arch/ppc32/src/cpu/cpu.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ppc32/src/cpu/cpu.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -68,5 +68,5 @@
 	}
 	
-	printf("cpu%" PRIs ": version=%" PRIu16" (%s), revision=%" PRIu16 "\n", cpu->id,
+	printf("cpu%u: version=%" PRIu16" (%s), revision=%" PRIu16 "\n", cpu->id,
 	    cpu->arch.version, name, cpu->arch.revision);
 }
Index: kernel/arch/ppc32/src/interrupt.c
===================================================================
--- kernel/arch/ppc32/src/interrupt.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ppc32/src/interrupt.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -54,26 +54,44 @@
 void istate_decode(istate_t *istate)
 {
-	printf("r0 =%p\tr1 =%p\tr2 =%p\n", istate->r0, istate->sp, istate->r2);
-	printf("r3 =%p\tr4 =%p\tr5 =%p\n", istate->r3, istate->r4, istate->r5);
-	printf("r6 =%p\tr7 =%p\tr8 =%p\n", istate->r6, istate->r7, istate->r8);
-	printf("r9 =%p\tr10=%p\tr11=%p\n",
+	printf("r0 =%#0" PRIx32 "\tr1 =%p\tr2 =%#0" PRIx32 "\n",
+	    istate->r0, (void *) istate->sp, istate->r2);
+	
+	printf("r3 =%#0" PRIx32 "\tr4 =%#0" PRIx32 "\tr5 =%#0" PRIx32 "\n",
+	    istate->r3, istate->r4, istate->r5);
+	
+	printf("r6 =%#0" PRIx32 "\tr7 =%#0" PRIx32 "\tr8 =%#0" PRIx32 "\n",
+	    istate->r6, istate->r7, istate->r8);
+	
+	printf("r9 =%#0" PRIx32 "\tr10=%#0" PRIx32 "\tr11=%#0" PRIx32 "\n",
 	    istate->r9, istate->r10, istate->r11);
-	printf("r12=%p\tr13=%p\tr14=%p\n",
+	
+	printf("r12=%#0" PRIx32 "\tr13=%#0" PRIx32 "\tr14=%#0" PRIx32 "\n",
 	    istate->r12, istate->r13, istate->r14);
-	printf("r15=%p\tr16=%p\tr17=%p\n",
+	
+	printf("r15=%#0" PRIx32 "\tr16=%#0" PRIx32 "\tr17=%#0" PRIx32 "\n",
 	    istate->r15, istate->r16, istate->r17);
-	printf("r18=%p\tr19=%p\tr20=%p\n",
+	
+	printf("r18=%#0" PRIx32 "\tr19=%#0" PRIx32 "\tr20=%#0" PRIx32 "\n",
 	    istate->r18, istate->r19, istate->r20);
-	printf("r21=%p\tr22=%p\tr23=%p\n",
+	
+	printf("r21=%#0" PRIx32 "\tr22=%#0" PRIx32 "\tr23=%#0" PRIx32 "\n",
 	    istate->r21, istate->r22, istate->r23);
-	printf("r24=%p\tr25=%p\tr26=%p\n",
+	
+	printf("r24=%#0" PRIx32 "\tr25=%#0" PRIx32 "\tr26=%#0" PRIx32 "\n",
 	    istate->r24, istate->r25, istate->r26);
-	printf("r27=%p\tr28=%p\tr29=%p\n",
+	
+	printf("r27=%#0" PRIx32 "\tr28=%#0" PRIx32 "\tr29=%#0" PRIx32 "\n",
 	    istate->r27, istate->r28, istate->r29);
-	printf("r30=%p\tr31=%p\n", istate->r30, istate->r31);
-	printf("cr =%p\tpc =%p\tlr =%p\n", istate->cr, istate->pc, istate->lr);
-	printf("ctr=%p\txer=%p\tdar=%p\n",
+	
+	printf("r30=%#0" PRIx32 "\tr31=%#0" PRIx32 "\n",
+	    istate->r30, istate->r31);
+	
+	printf("cr =%#0" PRIx32 "\tpc =%p\tlr =%p\n",
+	    istate->cr, (void *) istate->pc, (void *) istate->lr);
+	
+	printf("ctr=%#0" PRIx32 "\txer=%#0" PRIx32 "\tdar=%#0" PRIx32 "\n",
 	    istate->ctr, istate->xer, istate->dar);
-	printf("srr1=%p\n", istate->srr1);
+	
+	printf("srr1=%p\n", (void *) istate->srr1);
 }
 
@@ -111,5 +129,5 @@
 			 */
 #ifdef CONFIG_DEBUG
-			printf("cpu%" PRIs ": spurious interrupt (inum=%" PRIu8 ")\n",
+			printf("cpu%u: spurious interrupt (inum=%" PRIu8 ")\n",
 			    CPU->id, inum);
 #endif
Index: kernel/arch/ppc32/src/mm/frame.c
===================================================================
--- kernel/arch/ppc32/src/mm/frame.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ppc32/src/mm/frame.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -49,5 +49,5 @@
 	size_t i;
 	for (i = 0; i < memmap.cnt; i++) {
-		printf("%#10x %#10x\n", memmap.zones[i].start,
+		printf("%p %#0zx\n", memmap.zones[i].start,
 		    memmap.zones[i].size);
 	}
Index: kernel/arch/ppc32/src/mm/page.c
===================================================================
--- kernel/arch/ppc32/src/mm/page.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ppc32/src/mm/page.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -49,6 +49,6 @@
 	if (last_frame + ALIGN_UP(size, PAGE_SIZE) >
 	    KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
-		panic("Unable to map physical memory %p (%" PRIs " bytes).",
-		    physaddr, size);
+		panic("Unable to map physical memory %p (%zu bytes).",
+		    (void *) physaddr, size);
 	
 	uintptr_t virtaddr = PA2KA(last_frame);
Index: kernel/arch/ppc32/src/mm/tlb.c
===================================================================
--- kernel/arch/ppc32/src/mm/tlb.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/ppc32/src/mm/tlb.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -111,5 +111,6 @@
 static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
 {
-	fault_if_from_uspace(istate, "PHT Refill Exception on %p.", badvaddr);
+	fault_if_from_uspace(istate, "PHT Refill Exception on %p.",
+	    (void *) badvaddr);
 	panic_memtrap(istate, PF_ACCESS_UNKNOWN, badvaddr,
 	    "PHT Refill Exception.");
@@ -459,11 +460,11 @@
 		length = 0; \
 	\
-	printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \
-	    sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \
-	    lower & 0xffff0000, length, mask, \
+	printf(name ": page=%#0" PRIx32 " frame=%#0" PRIx32 \
+	    " length=%#0" PRIx32 " KB (mask=%#0" PRIx32 ")%s%s\n", \
+	    upper & UINT32_C(0xffff0000), lower & UINT32_C(0xffff0000), \
+	    length, mask, \
 	    ((upper >> 1) & 1) ? " supervisor" : "", \
 	    (upper & 1) ? " user" : "");
 
-
 void tlb_print(void)
 {
@@ -473,6 +474,7 @@
 		uint32_t vsid = sr_get(sr << 28);
 		
-		printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
-		    sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
+		printf("sr[%02" PRIu32 "]: vsid=%#0" PRIx32 " (asid=%" PRIu32 ")"
+		    "%s%s\n", sr, vsid & UINT32_C(0x00ffffff),
+		    (vsid & UINT32_C(0x00ffffff)) >> 4,
 		    ((vsid >> 30) & 1) ? " supervisor" : "",
 		    ((vsid >> 29) & 1) ? " user" : "");
Index: kernel/arch/sparc64/include/types.h
===================================================================
--- kernel/arch/sparc64/include/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/sparc64/include/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -52,26 +52,11 @@
 typedef uint8_t asi_t;
 
-/** Formats for uintptr_t, size_t */
-#define PRIp  "llx"
-#define PRIs  "llu"
+#define INTN_C(c)   INT64_C(c)
+#define UINTN_C(c)  UINT64_C(c)
 
-/** Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
-#define PRId8   "d"
-#define PRId16  "d"
-#define PRId32  "d"
-#define PRId64  "lld"
-#define PRIdn   "lld"
-
-#define PRIu8   "u"
-#define PRIu16  "u"
-#define PRIu32  "u"
-#define PRIu64  "llu"
-#define PRIun   "llu"
-
-#define PRIx8   "x"
-#define PRIx16  "x"
-#define PRIx32  "x"
-#define PRIx64  "llx"
-#define PRIxn   "llx"
+#define PRIdn  PRId64  /**< Format for native_t. */
+#define PRIun  PRIu64  /**< Format for unative_t. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal unative_t. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
 
 #endif
Index: kernel/arch/sparc64/src/console.c
===================================================================
--- kernel/arch/sparc64/src/console.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/sparc64/src/console.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -70,5 +70,5 @@
 	ofw_tree_node_t *screen = ofw_tree_lookup(prop_scr->value);
 	if (!screen)
-		panic("Cannot find %s.", prop_scr->value);
+		panic("Cannot find %s.", (char *) prop_scr->value);
 	
 	scr_init(screen);
@@ -83,5 +83,5 @@
 	ofw_tree_node_t *keyboard = ofw_tree_lookup(prop_kbd->value);
 	if (!keyboard)
-		panic("Cannot find %s.", prop_kbd->value);
+		panic("Cannot find %s.", (char *) prop_kbd->value);
 	
 	kbd_init(keyboard);
Index: kernel/arch/sparc64/src/drivers/pci.c
===================================================================
--- kernel/arch/sparc64/src/drivers/pci.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/sparc64/src/drivers/pci.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -211,5 +211,6 @@
 		 * Unsupported model.
 		 */
-		printf("Unsupported PCI controller model (%s).\n", prop->value);
+		printf("Unsupported PCI controller model (%s).\n",
+		    (char *) prop->value);
 	}
 
Index: kernel/arch/sparc64/src/mm/sun4u/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -360,7 +360,7 @@
 static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
 {
-	printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
-	    "ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
-	    "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
+	printf("%u: vpn=%#" PRIx64 ", context=%u, v=%u, size=%u, nfo=%u, "
+	    "ie=%u, soft2=%#x, pfn=%#x, soft=%#x, l=%u, "
+	    "cp=%u, cv=%u, e=%u, p=%u, w=%u, g=%u\n", i, (uint64_t) t.vpn,
 	    t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
 	    d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
@@ -441,5 +441,5 @@
     uintptr_t va, const char *str)
 {
-	fault_if_from_uspace(istate, "%s, Address=%p.", str, va);
+	fault_if_from_uspace(istate, "%s, address=%p.", str, (void *) va);
 	panic_memtrap(istate, PF_ACCESS_EXEC, va, str);
 }
@@ -451,6 +451,6 @@
 
 	va = tag.vpn << MMU_PAGE_WIDTH;
-	fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
-	    tag.context);
+	fault_if_from_uspace(istate, "%s, page=%p (asid=%u).", str,
+	    (void *) va, tag.context);
 	panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, str);
 }
@@ -462,6 +462,6 @@
 
 	va = tag.vpn << MMU_PAGE_WIDTH;
-	fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
-	    tag.context);
+	fault_if_from_uspace(istate, "%s, page=%p (asid=%u).", str,
+	    (void *) va, tag.context);
 	panic_memtrap(istate, PF_ACCESS_WRITE, va, str);
 }
@@ -484,6 +484,6 @@
 	    sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
 #endif
-	    
-	printf("DTLB SFAR: address=%p\n", sfar);
+	
+	printf("DTLB SFAR: address=%p\n", (void *) sfar);
 	
 	dtlb_sfsr_write(0);
@@ -508,5 +508,5 @@
 #endif
 	    
-	printf("DTLB SFAR: address=%p\n", sfar);
+	printf("DTLB SFAR: address=%p\n", (void *) sfar);
 	
 	dtlb_sfsr_write(0);
Index: kernel/arch/sparc64/src/mm/sun4v/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -358,5 +358,6 @@
     const char *str)
 {
-	fault_if_from_uspace(istate, "%s, Address=%p.", str, va);
+	fault_if_from_uspace(istate, "%s, address=%p.", str,
+	    (void *) va);
 	panic_memtrap(istate, PF_ACCESS_EXEC, va, str);
 }
@@ -365,6 +366,6 @@
     uint64_t page_and_ctx, const char *str)
 {
-	fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str,
-	    DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
+	fault_if_from_uspace(istate, "%s, page=%p (asid=%" PRId64 ").", str,
+	    (void *) DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
 	panic_memtrap(istate, PF_ACCESS_UNKNOWN, DMISS_ADDRESS(page_and_ctx),
 	    str);
@@ -374,6 +375,6 @@
     uint64_t page_and_ctx, const char *str)
 {
-	fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str,
-	    DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
+	fault_if_from_uspace(istate, "%s, page=%p (asid=%" PRId64 ").", str,
+	    (void *) DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
 	panic_memtrap(istate, PF_ACCESS_WRITE, DMISS_ADDRESS(page_and_ctx),
 	    str);
@@ -399,7 +400,6 @@
 	uint64_t errno =  __hypercall_fast3(MMU_DEMAP_ALL, 0, 0,
 		MMU_FLAG_DTLB | MMU_FLAG_ITLB);
-	if (errno != HV_EOK) {
-		panic("Error code = %d.\n", errno);
-	}
+	if (errno != HV_EOK)
+		panic("Error code = %" PRIu64 ".\n", errno);
 }
 
Index: kernel/arch/sparc64/src/sun4v/md.c
===================================================================
--- kernel/arch/sparc64/src/sun4v/md.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/sparc64/src/sun4v/md.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -310,6 +310,6 @@
 	retval = retval;
 	if (retval != HV_EOK) {
-		printf("Could not retrieve machine description, error = %d.\n",
-		    retval);
+		printf("Could not retrieve machine description, "
+		    "error=%" PRIu64 ".\n", retval);
 	}
 }
Index: kernel/arch/sparc64/src/trap/sun4v/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -87,5 +87,5 @@
 		KA2PA(cpu_mondo_queues[CPU->id]),
 		CPU_MONDO_NENTRIES) != HV_EOK)
-			panic("Initializing mondo queue failed on CPU %d.\n",
+			panic("Initializing mondo queue failed on CPU %" PRIu64 ".\n",
 			    CPU->arch.id);
 }
Index: kernel/generic/include/config.h
===================================================================
--- kernel/generic/include/config.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/config.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -66,5 +66,5 @@
 
 typedef struct {
-	size_t cpu_count;            /**< Number of processors detected. */
+	unsigned int cpu_count;      /**< Number of processors detected. */
 	volatile size_t cpu_active;  /**< Number of processors that are up and running. */
 	
Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/cpu.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -83,5 +83,5 @@
 	 * Processor ID assigned by kernel.
 	 */
-	size_t id;
+	unsigned int id;
 	
 	bool active;
Index: kernel/generic/include/interrupt.h
===================================================================
--- kernel/generic/include/interrupt.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/interrupt.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -37,4 +37,5 @@
 
 #include <arch/interrupt.h>
+#include <print.h>
 #include <typedefs.h>
 #include <proc/task.h>
@@ -57,5 +58,6 @@
 extern exc_table_t exc_table[];
 
-extern void fault_if_from_uspace(istate_t *, const char *, ...);
+extern void fault_if_from_uspace(istate_t *, const char *, ...)
+    PRINTF_ATTRIBUTE(2, 3);
 extern iroutine_t exc_register(unsigned int, const char *, bool, iroutine_t);
 extern void exc_dispatch(unsigned int, istate_t *);
Index: kernel/generic/include/macros.h
===================================================================
--- kernel/generic/include/macros.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/macros.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -104,10 +104,10 @@
 #define STRING_ARG(arg)  #arg
 
-#define LOWER32(arg)  (((uint64_t) (arg)) & 0xffffffff)
-#define UPPER32(arg)  (((((uint64_t) arg)) >> 32) & 0xffffffff)
+#define LOWER32(arg)  (((uint64_t) (arg)) & UINT32_C(0xffffffff))
+#define UPPER32(arg)  (((((uint64_t) arg)) >> 32) & UINT32_C(0xffffffff))
 
 #define MERGE_LOUP32(lo, up) \
-	((((uint64_t) (lo)) & 0xffffffff) \
-	    | ((((uint64_t) (up)) & 0xffffffff) << 32))
+	((((uint64_t) (lo)) & UINT32_C(0xffffffff)) \
+	    | ((((uint64_t) (up)) & UINT32_C(0xffffffff)) << 32))
 
 /** Pseudorandom generator
Index: kernel/generic/include/mm/slab.h
===================================================================
--- kernel/generic/include/mm/slab.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/mm/slab.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -126,5 +126,6 @@
 extern void slab_cache_destroy(slab_cache_t *);
 
-extern void * slab_alloc(slab_cache_t *, unsigned int);
+extern void *slab_alloc(slab_cache_t *, unsigned int)
+    __attribute__((malloc));
 extern void slab_free(slab_cache_t *, void *);
 extern size_t slab_reclaim(unsigned int);
@@ -138,5 +139,6 @@
 
 /* malloc support */
-extern void *malloc(size_t, unsigned int);
+extern void *malloc(size_t, unsigned int)
+    __attribute__((malloc));
 extern void *realloc(void *, size_t, unsigned int);
 extern void free(void *);
Index: kernel/generic/include/panic.h
===================================================================
--- kernel/generic/include/panic.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/panic.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -37,4 +37,5 @@
 
 #include <typedefs.h>
+#include <print.h>
 
 #define panic(fmt, ...) \
@@ -62,5 +63,6 @@
 
 extern void panic_common(panic_category_t, struct istate *, int,
-    uintptr_t, const char *, ...) __attribute__ ((noreturn));
+    uintptr_t, const char *, ...) __attribute__ ((noreturn))
+    PRINTF_ATTRIBUTE(5, 6);
 
 #endif
Index: kernel/generic/include/print.h
===================================================================
--- kernel/generic/include/print.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/print.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -39,9 +39,22 @@
 #include <stdarg.h>
 
+#ifndef NVERIFY_PRINTF
+
+#define PRINTF_ATTRIBUTE(start, end) \
+	__attribute__((format(gnu_printf, start, end)))
+
+#else /* NVERIFY_PRINTF */
+
+#define PRINTF_ATTRIBUTE(start, end)
+
+#endif /* NVERIFY_PRINTF */
+
 #define EOF  (-1)
 
 extern int puts(const char *s);
-extern int printf(const char *fmt, ...);
-extern int snprintf(char *str, size_t size, const char *fmt, ...);
+extern int printf(const char *fmt, ...)
+    PRINTF_ATTRIBUTE(1, 2);
+extern int snprintf(char *str, size_t size, const char *fmt, ...)
+    PRINTF_ATTRIBUTE(3, 4);
 
 extern int vprintf(const char *fmt, va_list ap);
Index: kernel/generic/include/stdint.h
===================================================================
--- kernel/generic/include/stdint.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/stdint.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -36,27 +36,27 @@
 #define KERN_STDINT_H_
 
-#define INT8_MIN  (0x80)
-#define INT8_MAX  (0x7F)
+#define INT8_MIN  INT8_C(0x80)
+#define INT8_MAX  INT8_C(0x7F)
 
-#define UINT8_MIN  (0u)
-#define UINT8_MAX  (0xFFu)
+#define UINT8_MIN  UINT8_C(0)
+#define UINT8_MAX  UINT8_C(0xFF)
 
-#define INT16_MIN  (0x8000)
-#define INT16_MAX  (0x7FFF)
+#define INT16_MIN  INT16_C(0x8000)
+#define INT16_MAX  INT16_C(0x7FFF)
 
-#define UINT16_MIN  (0u)
-#define UINT16_MAX  (0xFFFFu)
+#define UINT16_MIN  UINT16_C(0)
+#define UINT16_MAX  UINT16_C(0xFFFF)
 
-#define INT32_MIN  (0x80000000l)
-#define INT32_MAX  (0x7FFFFFFFl)
+#define INT32_MIN  INT32_C(0x80000000)
+#define INT32_MAX  INT32_C(0x7FFFFFFF)
 
-#define UINT32_MIN  (0ul)
-#define UINT32_MAX  (0xFFFFFFFFul)
+#define UINT32_MIN  UINT32_C(0)
+#define UINT32_MAX  UINT32_C(0xFFFFFFFF)
 
-#define INT64_MIN  (0x8000000000000000ll)
-#define INT64_MAX  (0x7FFFFFFFFFFFFFFFll)
+#define INT64_MIN  INT64_C(0x8000000000000000)
+#define INT64_MAX  INT64_C(0x7FFFFFFFFFFFFFFF)
 
-#define UINT64_MIN  (0ull)
-#define UINT64_MAX  (0xFFFFFFFFFFFFFFFFull)
+#define UINT64_MIN  UINT64_C(0)
+#define UINT64_MAX  UINT64_C(0xFFFFFFFFFFFFFFFF)
 
 #endif
Index: kernel/generic/include/synch/spinlock.h
===================================================================
--- kernel/generic/include/synch/spinlock.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/synch/spinlock.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -146,5 +146,5 @@
 	if ((pname)++ > (value)) { \
 		(pname) = 0; \
-		printf("Deadlock probe %s: exceeded threshold %u\n", \
+		printf("Deadlock probe %s: exceeded threshold %u\n" \
 		    "cpu%u: function=%s, line=%u\n", \
 		    #pname, (value), CPU->id, __func__, __LINE__); \
Index: kernel/generic/include/sysinfo/abi.h
===================================================================
--- kernel/generic/include/sysinfo/abi.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/sysinfo/abi.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -66,5 +66,5 @@
  */
 typedef struct {
-	size_t id;               /**< CPU ID as stored by kernel */
+	unsigned int id;         /**< CPU ID as stored by kernel */
 	bool active;             /**< CPU is activate */
 	uint16_t frequency_mhz;  /**< Frequency in MHz */
Index: kernel/generic/include/typedefs.h
===================================================================
--- kernel/generic/include/typedefs.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/include/typedefs.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -40,5 +40,5 @@
 #include <arch/types.h>
 
-#define NULL	((void *) 0)
+#define NULL  ((void *) 0)
 
 #define false  0
@@ -69,6 +69,4 @@
 typedef int32_t devno_t;
 
-typedef int32_t wchar_t;
-
 typedef volatile uint8_t ioport8_t;
 typedef volatile uint16_t ioport16_t;
Index: kernel/generic/src/console/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/console/cmd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -554,4 +554,10 @@
 	}
 	
+	unsigned int _len = (unsigned int) len;
+	if ((_len != len) || (((int) _len) < 0)) {
+		printf("Command length overflow\n");
+		return 1;
+	}
+	
 	for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
 		cmd_info_t *hlp;
@@ -559,5 +565,5 @@
 		
 		spinlock_lock(&hlp->lock);
-		printf("%-*s %s\n", len, hlp->name, hlp->description);
+		printf("%-*s %s\n", _len, hlp->name, hlp->description);
 		spinlock_unlock(&hlp->lock);
 	}
@@ -668,5 +674,5 @@
 		fnc = (unative_t (*)(void)) arch_construct_function(&fptr,
 		    (void *) symaddr, (void *) cmd_call0);
-		printf("Calling %s() (%p)\n", symbol, symaddr);
+		printf("Calling %s() (%p)\n", symbol, (void *) symaddr);
 		printf("Result: %#" PRIxn "\n", fnc());
 		interrupts_restore(ipl);
@@ -685,5 +691,5 @@
 	 */
 	
-	size_t i;
+	unsigned int i;
 	for (i = 0; i < config.cpu_count; i++) {
 		if (!cpus[i].active)
@@ -697,5 +703,5 @@
 			irq_spinlock_unlock(&thread->lock, true);
 			
-			printf("cpu%" PRIs ": ", i);
+			printf("cpu%u: ", i);
 			
 			thread_ready(thread);
@@ -703,5 +709,5 @@
 			thread_detach(thread);
 		} else
-			printf("Unable to create thread for cpu%" PRIs "\n", i);
+			printf("Unable to create thread for cpu%u\n", i);
 	}
 	
@@ -731,6 +737,9 @@
 
 		ipl = interrupts_disable();
-		fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1);
-		printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol);
+		fnc = (unative_t (*)(unative_t, ...))
+		    arch_construct_function(&fptr, (void *) symaddr,
+		    (void *) cmd_call1);
+		printf("Calling f(%#" PRIxn "): %p: %s\n", arg1,
+		    (void *) symaddr, symbol);
 		printf("Result: %#" PRIxn "\n", fnc(arg1));
 		interrupts_restore(ipl);
@@ -765,7 +774,9 @@
 
 		ipl = interrupts_disable();
-		fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2);
+		fnc = (unative_t (*)(unative_t, unative_t, ...))
+		    arch_construct_function(&fptr, (void *) symaddr,
+		    (void *) cmd_call2);
 		printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n", 
-		       arg1, arg2, symaddr, symbol);
+		       arg1, arg2, (void *) symaddr, symbol);
 		printf("Result: %#" PRIxn "\n", fnc(arg1, arg2));
 		interrupts_restore(ipl);
@@ -800,7 +811,9 @@
 
 		ipl = interrupts_disable();
-		fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3);
-		printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n", 
-		       arg1, arg2, arg3, symaddr, symbol);
+		fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...))
+		    arch_construct_function(&fptr, (void *) symaddr,
+		    (void *) cmd_call3);
+		printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n",
+		       arg1, arg2, arg3, (void *) symaddr, symbol);
 		printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3));
 		interrupts_restore(ipl);
@@ -875,5 +888,5 @@
 	
 	if (rc == ENOENT)
-		printf("Symbol %s not found.\n", argv->buffer);
+		printf("Symbol %s not found.\n", (char *) argv->buffer);
 	else if (rc == EINVAL)
 		printf("Invalid address.\n");
@@ -884,5 +897,5 @@
 		if (pointer)
 			addr = *(uintptr_t *) addr;
-		printf("Writing %#" PRIx64 " -> %p\n", arg1, addr);
+		printf("Writing %#" PRIx32" -> %p\n", arg1, (void *) addr);
 		*(uint32_t *) addr = arg1;
 	} else
@@ -1172,8 +1185,15 @@
 	}
 	
+	unsigned int _len = (unsigned int) len;
+	if ((_len != len) || (((int) _len) < 0)) {
+		printf("Command length overflow\n");
+		return;
+	}
+	
 	for (test = tests; test->name != NULL; test++)
-		printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
-	
-	printf("%-*s Run all safe tests\n", len, "*");
+		printf("%-*s %s%s\n", _len, test->name, test->desc,
+		    (test->safe ? "" : " (unsafe)"));
+	
+	printf("%-*s Run all safe tests\n", _len, "*");
 }
 
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/cpu/cpu.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -107,5 +107,5 @@
 void cpu_list(void)
 {
-	size_t i;
+	unsigned int i;
 	
 	for (i = 0; i < config.cpu_count; i++) {
Index: kernel/generic/src/debug/debug.c
===================================================================
--- kernel/generic/src/debug/debug.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/debug/debug.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -52,8 +52,8 @@
 	if (symtab_name_lookup((uintptr_t) call_site, &call_site_sym,
 	    &call_site_off) == EOK)
-		printf("%s+%" PRIp "->%s\n", call_site_sym, call_site_off,
-		    fn_sym);
+		printf("%s()+%p->%s()\n", call_site_sym,
+		    (void *) call_site_off, fn_sym);
 	else
-		printf("->%s\n", fn_sym);
+		printf("->%s()\n", fn_sym);
 }
 
@@ -67,8 +67,8 @@
 	if (symtab_name_lookup((uintptr_t) call_site, &call_site_sym,
 	    &call_site_off) == EOK)
-		printf("%s+%" PRIp "<-%s\n", call_site_sym, call_site_off,
-		    fn_sym);
+		printf("%s()+%p<-%s()\n", call_site_sym,
+		    (void *) call_site_off, fn_sym);
 	else
-		printf("<-%s\n", fn_sym);
+		printf("<-%s()\n", fn_sym);
 }
 
Index: kernel/generic/src/debug/panic.c
===================================================================
--- kernel/generic/src/debug/panic.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/debug/panic.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -42,23 +42,27 @@
 #include <interrupt.h>
 
+#define BANNER_LEFT   "######>"
+#define BANNER_RIGHT  "<######"
+
 void panic_common(panic_category_t cat, istate_t *istate, int access,
     uintptr_t address, const char *fmt, ...)
 {
 	va_list args;
-
+	
 	silent = false;
-
-	printf("\nKERNEL PANIC ");
+	
+	printf("\n%s Kernel panic ", BANNER_LEFT);
 	if (CPU)
-		printf("ON cpu%d ", CPU->id);
-	printf("DUE TO ");
-
+		printf("on cpu%u ", CPU->id);
+	printf("due to ");
+	
 	va_start(args, fmt);
 	if (cat == PANIC_ASSERT) {
-		printf("A FAILED ASSERTION:\n");
+		printf("a failed assertion: %s\n", BANNER_RIGHT);
 		vprintf(fmt, args);
 		printf("\n");
 	} else if (cat == PANIC_BADTRAP) {
-		printf("BAD TRAP %ld.\n", address);
+		printf("bad trap %" PRIun ". %s\n", address,
+		    BANNER_RIGHT);
 		if (fmt) {
 			vprintf(fmt, args);
@@ -66,14 +70,15 @@
 		}
 	} else if (cat == PANIC_MEMTRAP) {
-		printf("A BAD MEMORY ACCESS WHILE ");
+		printf("a bad memory access while ");
 		if (access == PF_ACCESS_READ)
-			printf("LOADING FROM");
+			printf("loading from");
 		else if (access == PF_ACCESS_WRITE)
-			printf("STORING TO");
+			printf("storing to");
 		else if (access == PF_ACCESS_EXEC)
-			printf("BRANCHING TO");
+			printf("branching to");
 		else
-			printf("REFERENCING");
-		printf(" ADDRESS %p.\n", address); 
+			printf("referencing");
+		printf(" address %p. %s\n", (void *) address,
+		    BANNER_RIGHT);
 		if (fmt) {
 			vprintf(fmt, args);
@@ -81,17 +86,18 @@
 		}
 	} else {
-		printf("THE FOLLOWING REASON:\n");
+		printf("the following reason: %s\n",
+		    BANNER_RIGHT);
 		vprintf(fmt, args);
 		printf("\n");
 	}
 	va_end(args);
-
+	
 	printf("\n");
-
+	
 	if (istate) {
 		istate_decode(istate);
 		printf("\n");
 	}
-
+	
 	stack_trace();
 	halt();
Index: kernel/generic/src/debug/stacktrace.c
===================================================================
--- kernel/generic/src/debug/stacktrace.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/debug/stacktrace.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -41,6 +41,5 @@
 #define STACK_FRAMES_MAX	20
 
-void
-stack_trace_ctx(stack_trace_ops_t *ops, stack_trace_context_t *ctx)
+void stack_trace_ctx(stack_trace_ops_t *ops, stack_trace_context_t *ctx)
 {
 	int cnt = 0;
@@ -54,17 +53,18 @@
 		if (ops->symbol_resolve &&
 		    ops->symbol_resolve(ctx->pc, &symbol, &offset)) {
-		    	if (offset)
-				printf("%p: %s+%" PRIp "()\n",
-				    ctx->fp, symbol, offset);
+			if (offset)
+				printf("%p: %s()+%p\n", (void *) ctx->fp,
+				    symbol, (void *) offset);
 			else
-				printf("%p: %s()\n",
-				    ctx->fp, symbol);
-		} else {
-			printf("%p: %p()\n", ctx->fp, ctx->pc);
-		}
+				printf("%p: %s()\n", (void *) ctx->fp, symbol);
+		} else
+			printf("%p: %p()\n", (void *) ctx->fp, (void *) ctx->pc);
+		
 		if (!ops->return_address_get(ctx, &pc))
 			break;
+		
 		if (!ops->frame_pointer_prev(ctx, &fp))
 			break;
+		
 		ctx->fp = fp;
 		ctx->pc = pc;
Index: kernel/generic/src/debug/symtab.c
===================================================================
--- kernel/generic/src/debug/symtab.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/debug/symtab.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -192,5 +192,5 @@
 		uintptr_t addr = uint64_t_le2host(symbol_table[pos].address_le);
 		char *realname = symbol_table[pos].symbol_name;
-		printf("%p: %s\n", addr, realname);
+		printf("%p: %s\n", (void *) addr, realname);
 		pos++;
 	}
Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/interrupt/interrupt.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -176,5 +176,5 @@
 	printf("Task %s (%" PRIu64 ") killed due to an exception at "
 	    "program counter %p.\n", TASK->name, TASK->taskid,
-	    istate_get_pc(istate));
+	    (void *) istate_get_pc(istate));
 	
 	stack_trace_istate(istate);
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/ipc/ipc.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -702,10 +702,10 @@
 	for (i = 0; i < IPC_MAX_PHONES; i++) {
 		if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) {
-			printf("%d: mutex busy\n", i);
+			printf("%zu: mutex busy\n", i);
 			continue;
 		}
 		
 		if (task->phones[i].state != IPC_PHONE_FREE) {
-			printf("%" PRIs ": ", i);
+			printf("%zu: ", i);
 			
 			switch (task->phones[i].state) {
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/main/kinit.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -129,5 +129,5 @@
 		 * For each CPU, create its load balancing thread.
 		 */
-		size_t i;
+		unsigned int i;
 		
 		for (i = 0; i < config.cpu_count; i++) {
@@ -139,5 +139,5 @@
 				thread_ready(thread);
 			} else
-				printf("Unable to create kcpulb thread for cpu" PRIs "\n", i);
+				printf("Unable to create kcpulb thread for cpu%u\n", i);
 		}
 	}
@@ -179,5 +179,5 @@
 	for (i = 0; i < init.cnt; i++) {
 		if (init.tasks[i].addr % FRAME_SIZE) {
-			printf("init[%" PRIs "].addr is not frame aligned\n", i);
+			printf("init[%zu].addr is not frame aligned\n", i);
 			programs[i].task = NULL;
 			continue;
@@ -219,5 +219,5 @@
 			
 			if (rd != RE_OK)
-				printf("Init binary %" PRIs " not used (error %d)\n", i, rd);
+				printf("Init binary %zu not used (error %d)\n", i, rd);
 		}
 	}
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/main/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -183,6 +183,6 @@
 	version_print();
 	
-	LOG("\nconfig.base=%p config.kernel_size=%" PRIs
-	    "\nconfig.stack_base=%p config.stack_size=%" PRIs,
+	LOG("\nconfig.base=%p config.kernel_size=%zu"
+	    "\nconfig.stack_base=%p config.stack_size=%zu",
 	    config.base, config.kernel_size, config.stack_base,
 	    config.stack_size);
@@ -225,5 +225,5 @@
 	slab_enable_cpucache();
 	
-	printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n",
+	printf("Detected %u CPU(s), %" PRIu64 " MiB free memory\n",
 	    config.cpu_count, SIZE2MB(zones_total_size()));
 	
@@ -241,7 +241,6 @@
 		size_t i;
 		for (i = 0; i < init.cnt; i++)
-			LOG("init[%" PRIs "].addr=%p, init[%" PRIs
-			    "].size=%" PRIs, i, init.tasks[i].addr, i,
-			    init.tasks[i].size);
+			LOG("init[%zu].addr=%p, init[%zu].size=%zu",
+			    i, init.tasks[i].addr, i, init.tasks[i].size);
 	} else
 		printf("No init binaries found.\n");
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/mm/as.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -1811,6 +1811,6 @@
 	}
 	
-	panic("Inconsistency detected while adding %" PRIs " pages of used "
-	    "space at %p.", count, page);
+	panic("Inconsistency detected while adding %zu pages of used "
+	    "space at %p.", count, (void *) page);
 }
 
@@ -1991,6 +1991,6 @@
 	
 error:
-	panic("Inconsistency detected while removing %" PRIs " pages of used "
-	    "space from %p.", count, page);
+	panic("Inconsistency detected while removing %zu pages of used "
+	    "space from %p.", count, (void *) page);
 }
 
@@ -2105,7 +2105,8 @@
 			
 			mutex_lock(&area->lock);
-			printf("as_area: %p, base=%p, pages=%" PRIs
-			    " (%p - %p)\n", area, area->base, area->pages,
-			    area->base, area->base + FRAMES2SIZE(area->pages));
+			printf("as_area: %p, base=%p, pages=%zu"
+			    " (%p - %p)\n", area, (void *) area->base,
+			    area->pages, (void *) area->base,
+			    (void *) (area->base + FRAMES2SIZE(area->pages)));
 			mutex_unlock(&area->lock);
 		}
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/mm/frame.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -145,8 +145,9 @@
 			    (!iswithin(zones.info[i].base, zones.info[i].count,
 			    base, count))) {
-				printf("Zone (%p, %p) overlaps with previous zone (%p, %p)!\n",
-				    PFN2ADDR(base), PFN2ADDR(count),
-				    PFN2ADDR(zones.info[i].base),
-				    PFN2ADDR(zones.info[i].count));
+				printf("Zone (%p, %p) overlaps "
+				    "with previous zone (%p %p)!\n",
+				    (void *) PFN2ADDR(base), (void *) PFN2ADDR(count),
+				    (void *) PFN2ADDR(zones.info[i].base),
+				    (void *) PFN2ADDR(zones.info[i].count));
 			}
 			
@@ -1049,6 +1050,6 @@
 		
 #ifdef CONFIG_DEBUG
-		printf("Thread %" PRIu64 " waiting for %" PRIs " frames, "
-		    "%" PRIs " available.\n", THREAD->tid, size, avail);
+		printf("Thread %" PRIu64 " waiting for %zu frames, "
+		    "%zu available.\n", THREAD->tid, size, avail);
 #endif
 		
@@ -1297,15 +1298,15 @@
 		bool available = zone_flags_available(flags);
 		
-		printf("%-4" PRIs, i);
+		printf("%-4zu", i);
 		
 #ifdef __32_BITS__
-		printf("  %10p", base);
+		printf("  %p", (void *) base);
 #endif
 		
 #ifdef __64_BITS__
-		printf(" %18p", base);
+		printf(" %p", (void *) base);
 #endif
 		
-		printf(" %12" PRIs " %c%c%c      ", count,
+		printf(" %12zu %c%c%c      ", count,
 		    available ? 'A' : ' ',
 		    (flags & ZONE_RESERVED) ? 'R' : ' ',
@@ -1313,5 +1314,5 @@
 		
 		if (available)
-			printf("%14" PRIs " %14" PRIs,
+			printf("%14zu %14zu",
 			    free_count, busy_count);
 		
@@ -1354,7 +1355,7 @@
 	bool available = zone_flags_available(flags);
 	
-	printf("Zone number:       %" PRIs "\n", znum);
-	printf("Zone base address: %p\n", base);
-	printf("Zone size:         %" PRIs " frames (%" PRIs " KiB)\n", count,
+	printf("Zone number:       %zu\n", znum);
+	printf("Zone base address: %p\n", (void *) base);
+	printf("Zone size:         %zu frames (%zu KiB)\n", count,
 	    SIZE2KB(FRAMES2SIZE(count)));
 	printf("Zone flags:        %c%c%c\n",
@@ -1364,7 +1365,7 @@
 	
 	if (available) {
-		printf("Allocated space:   %" PRIs " frames (%" PRIs " KiB)\n",
+		printf("Allocated space:   %zu frames (%zu KiB)\n",
 		    busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
-		printf("Available space:   %" PRIs " frames (%" PRIs " KiB)\n",
+		printf("Available space:   %zu frames (%zu KiB)\n",
 		    free_count, SIZE2KB(FRAMES2SIZE(free_count)));
 	}
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/mm/slab.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -890,5 +890,5 @@
 		irq_spinlock_unlock(&slab_cache_lock, true);
 		
-		printf("%-18s %8" PRIs " %8u %8" PRIs " %8ld %8ld %8ld %-5s\n",
+		printf("%-18s %8zu %8u %8zu %8ld %8ld %8ld %-5s\n",
 		    name, size, (1 << order), objects, allocated_slabs,
 		    cached_objs, allocated_objs,
Index: kernel/generic/src/printf/printf_core.c
===================================================================
--- kernel/generic/src/printf/printf_core.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/printf/printf_core.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -83,5 +83,6 @@
 	PrintfQualifierLong,
 	PrintfQualifierLongLong,
-	PrintfQualifierPointer
+	PrintfQualifierPointer,
+	PrintfQualifierSize
 } qualifier_t;
 
@@ -553,7 +554,8 @@
  *  - ""   Signed or unsigned int (default value).@n
  *  - "l"  Signed or unsigned long int.@n
- *         If conversion is "c", the character is wchar_t (wide character).@n
+ *         If conversion is "c", the character is wint_t (wide character).@n
  *         If conversion is "s", the string is wchar_t * (wide string).@n
  *  - "ll" Signed or unsigned long long int.@n
+ *  - "z"  Signed or unsigned ssize_t or site_t.@n
  *
  * CONVERSION:@n
@@ -737,4 +739,9 @@
 				}
 				break;
+			case 'z':
+				qualifier = PrintfQualifierSize;
+				i = nxt;
+				uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+				break;
 			default:
 				/* Default type */
@@ -764,5 +771,5 @@
 			case 'c':
 				if (qualifier == PrintfQualifierLong)
-					retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps);
+					retval = print_wchar(va_arg(ap, wint_t), width, flags, ps);
 				else
 					retval = print_char(va_arg(ap, unsigned int), width, flags, ps);
@@ -850,4 +857,8 @@
 				precision = size << 1;
 				number = (uint64_t) (uintptr_t) va_arg(ap, void *);
+				break;
+			case PrintfQualifierSize:
+				size = sizeof(size_t);
+				number = (uint64_t) va_arg(ap, size_t);
 				break;
 			default:
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/proc/program.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -145,6 +145,6 @@
 		
 		program_loader = image_addr;
-		LOG("Registered program loader at 0x%" PRIp,
-		    image_addr);
+		LOG("Registered program loader at %p",
+		    (void *) image_addr);
 		
 		return EOK;
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/proc/scheduler.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -727,5 +727,5 @@
 		irq_spinlock_lock(&cpus[cpu].lock, true);
 		
-		printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
+		printf("cpu%u: address=%p, nrdy=%" PRIua ", needs_relink=%zu\n",
 		    cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
 		    cpus[cpu].needs_relink);
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/proc/task.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -478,5 +478,5 @@
 #ifdef __32_BITS__
 	if (*additional)
-		printf("%-8" PRIu64 " %9lu %7lu", task->taskid,
+		printf("%-8" PRIu64 " %9" PRIua " %7" PRIua, task->taskid,
 		    atomic_get(&task->refcount), atomic_get(&task->active_calls));
 	else
@@ -489,5 +489,6 @@
 #ifdef __64_BITS__
 	if (*additional)
-		printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c %9lu %7lu",
+		printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c "
+		    "%9" PRIua " %7" PRIua,
 		    task->taskid, ucycles, usuffix, kcycles, ksuffix,
 		    atomic_get(&task->refcount), atomic_get(&task->active_calls));
@@ -501,5 +502,5 @@
 		for (i = 0; i < IPC_MAX_PHONES; i++) {
 			if (task->phones[i].callee)
-				printf(" %" PRIs ":%p", i, task->phones[i].callee);
+				printf(" %zu:%p", i, task->phones[i].callee);
 		}
 		printf("\n");
Index: kernel/generic/src/synch/spinlock.c
===================================================================
--- kernel/generic/src/synch/spinlock.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/synch/spinlock.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -102,7 +102,7 @@
 		
 		if (i++ > DEADLOCK_THRESHOLD) {
-			printf("cpu%u: looping on spinlock %" PRIp ":%s, "
-			    "caller=%" PRIp "(%s)\n", CPU->id, lock, lock->name,
-			    CALLER, symtab_fmt_name_lookup(CALLER));
+			printf("cpu%u: looping on spinlock %p:%s, "
+			    "caller=%p (%s)\n", CPU->id, lock, lock->name,
+			    (void *) CALLER, symtab_fmt_name_lookup(CALLER));
 			
 			i = 0;
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -494,5 +494,5 @@
 			break;
 		case SYSINFO_VAL_DATA:
-			printf("+ %s (%" PRIs" bytes)\n", cur->name,
+			printf("+ %s (%zu bytes)\n", cur->name,
 			    cur->val.data.size);
 			break;
@@ -505,5 +505,5 @@
 			/* N.B.: No data was actually returned (only a dry run) */
 			(void) cur->val.fn_data(cur, &size, true);
-			printf("+ %s (%" PRIs" bytes) [generated]\n", cur->name,
+			printf("+ %s (%zu bytes) [generated]\n", cur->name,
 			    size);
 			break;
Index: kernel/test/avltree/avltree1.c
===================================================================
--- kernel/test/avltree/avltree1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/avltree/avltree1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -202,5 +202,5 @@
 	avltree_create(tree);
 	
-	TPRINTF("Inserting %" PRIs " nodes...", node_count);
+	TPRINTF("Inserting %zu nodes...", node_count);
 	
 	for (i = 0; i < node_count; i++) {
Index: kernel/test/fpu/fpu1_ia64.c
===================================================================
--- kernel/test/fpu/fpu1_ia64.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/fpu/fpu1_ia64.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -161,5 +161,6 @@
 	
 	while (atomic_get(&threads_ok) != total) {
-		TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
+		TPRINTF("Threads left: %" PRIua "\n",
+		    total - atomic_get(&threads_ok));
 		thread_sleep(1);
 	}
Index: kernel/test/fpu/fpu1_x86.c
===================================================================
--- kernel/test/fpu/fpu1_x86.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/fpu/fpu1_x86.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -82,5 +82,6 @@
 		
 		if ((int) (100000000 * e) != E_10e8) {
-			TPRINTF("tid%" PRIu64 ": e*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8);
+			TPRINTF("tid%" PRIu64 ": e*10e8=%" PRIun " should be %" PRIun "\n",
+			    THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8);
 			atomic_inc(&threads_fault);
 			break;
@@ -115,5 +116,6 @@
 		
 		if ((int) (100000000 * pi) != PI_10e8) {
-			TPRINTF("tid%" PRIu64 ": pi*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (100000000 * pi), (unative_t) PI_10e8);
+			TPRINTF("tid%" PRIu64 ": pi*10e8=%" PRIun " should be %" PRIun "\n",
+			    THREAD->tid, (unative_t) (100000000 * pi), (unative_t) PI_10e8);
 			atomic_inc(&threads_fault);
 			break;
@@ -158,5 +160,5 @@
 	
 	while (atomic_get(&threads_ok) != total) {
-		TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
+		TPRINTF("Threads left: %" PRIua "\n", total - atomic_get(&threads_ok));
 		thread_sleep(1);
 	}
Index: kernel/test/fpu/sse1.c
===================================================================
--- kernel/test/fpu/sse1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/fpu/sse1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -142,5 +142,5 @@
 	
 	while (atomic_get(&threads_ok) != total) {
-		TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
+		TPRINTF("Threads left: %" PRIua "\n", total - atomic_get(&threads_ok));
 		thread_sleep(1);
 	}
Index: kernel/test/mm/falloc1.c
===================================================================
--- kernel/test/mm/falloc1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/mm/falloc1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -64,5 +64,6 @@
 				
 				if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) != frames[allocated]) {
-					TPRINTF("Block at address %p (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10);
+					TPRINTF("Block at address %p (size %dK) is not aligned\n",
+					    (void *) frames[allocated], (FRAME_SIZE << order) >> 10);
 					return "Test failed";
 				}
Index: kernel/test/mm/falloc2.c
===================================================================
--- kernel/test/mm/falloc2.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/mm/falloc2.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -85,5 +85,6 @@
 				for (k = 0; k <= (((size_t) FRAME_SIZE << order) - 1); k++) {
 					if (((uint8_t *) frames[i])[k] != val) {
-						TPRINTF("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %#" PRIs "\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
+						TPRINTF("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %zu\n",
+						    THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
 						atomic_inc(&thread_fail);
 						goto cleanup;
@@ -121,5 +122,5 @@
 	
 	while (atomic_get(&thread_count) > 0) {
-		TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
+		TPRINTF("Threads left: %" PRIua "\n", atomic_get(&thread_count));
 		thread_sleep(1);
 	}
Index: kernel/test/mm/mapping1.c
===================================================================
--- kernel/test/mm/mapping1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/mm/mapping1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -39,6 +39,6 @@
 #define PAGE1  (PAGE0 + PAGE_SIZE)
 
-#define VALUE0  0x01234567
-#define VALUE1  0x89abcdef
+#define VALUE0  UINT32_C(0x01234567)
+#define VALUE1  UINT32_C(0x89abcdef)
 
 const char *test_mapping1(void)
@@ -50,20 +50,26 @@
 	frame1 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
 	
-	TPRINTF("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0));
+	TPRINTF("Writing %#" PRIx32 " to physical address %p.\n",
+	    (uint32_t) VALUE0, (void *) KA2PA(frame0));
 	*((uint32_t *) frame0) = VALUE0;
 	
-	TPRINTF("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1));
+	TPRINTF("Writing %#" PRIx32 " to physical address %p.\n",
+	    (uint32_t) VALUE1, (void *) KA2PA(frame1));
 	*((uint32_t *) frame1) = VALUE1;
 	
-	TPRINTF("Mapping virtual address %p to physical address %p.\n", PAGE0, KA2PA(frame0));
+	TPRINTF("Mapping virtual address %p to physical address %p.\n",
+	    (void *) PAGE0, (void *) KA2PA(frame0));
 	page_mapping_insert(AS_KERNEL, PAGE0, KA2PA(frame0), PAGE_PRESENT | PAGE_WRITE);
 	
-	TPRINTF("Mapping virtual address %p to physical address %p.\n", PAGE1, KA2PA(frame1));
+	TPRINTF("Mapping virtual address %p to physical address %p.\n",
+	    (void *) PAGE1, (void *) KA2PA(frame1));
 	page_mapping_insert(AS_KERNEL, PAGE1, KA2PA(frame1), PAGE_PRESENT | PAGE_WRITE);
 	
 	v0 = *((uint32_t *) PAGE0);
 	v1 = *((uint32_t *) PAGE1);
-	TPRINTF("Value at virtual address %p is %#x.\n", PAGE0, v0);
-	TPRINTF("Value at virtual address %p is %#x.\n", PAGE1, v1);
+	TPRINTF("Value at virtual address %p is %#" PRIx32 ".\n",
+	    (void *) PAGE0, v0);
+	TPRINTF("Value at virtual address %p is %#" PRIx32 ".\n",
+	    (void *) PAGE1, v1);
 	
 	if (v0 != VALUE0)
@@ -72,8 +78,10 @@
 		return "Value at v1 not equal to VALUE1";
 	
-	TPRINTF("Writing %#x to virtual address %p.\n", 0, PAGE0);
+	TPRINTF("Writing %#" PRIx32 " to virtual address %p.\n",
+	    (uint32_t) 0, (void *) PAGE0);
 	*((uint32_t *) PAGE0) = 0;
 	
-	TPRINTF("Writing %#x to virtual address %p.\n", 0, PAGE1);
+	TPRINTF("Writing %#" PRIx32 " to virtual address %p.\n",
+	    (uint32_t) 0, (void *) PAGE1);
 	*((uint32_t *) PAGE1) = 0;
 	
@@ -81,6 +89,8 @@
 	v1 = *((uint32_t *) PAGE1);
 	
-	TPRINTF("Value at virtual address %p is %#x.\n", PAGE0, *((uint32_t *) PAGE0));	
-	TPRINTF("Value at virtual address %p is %#x.\n", PAGE1, *((uint32_t *) PAGE1));
+	TPRINTF("Value at virtual address %p is %#" PRIx32 ".\n",
+	    (void *) PAGE0, *((uint32_t *) PAGE0));
+	TPRINTF("Value at virtual address %p is %#" PRIx32 ".\n",
+	    (void *) PAGE1, *((uint32_t *) PAGE1));
 	
 	if (v0 != 0)
Index: kernel/test/print/print1.c
===================================================================
--- kernel/test/print/print1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/print/print1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -48,8 +48,4 @@
 	TPRINTF("Real output:     \"%8.10s\"\n\n", "very long text");
 	
-	TPRINTF("Testing printf(\"%%s\", NULL):\n");
-	TPRINTF("Expected output: \"(NULL)\"\n");
-	TPRINTF("Real output:     \"%s\"\n\n", NULL);
-	
 	return NULL;
 }
Index: kernel/test/print/print2.c
===================================================================
--- kernel/test/print/print2.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/print/print2.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -32,7 +32,7 @@
 const char *test_print2(void)
 {
-	TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n");
-	TPRINTF("Expected output: [a] [  b] [c  ] [ d] [e ]\n");
-	TPRINTF("Real output:     [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e');
+	TPRINTF("Testing printf(\"%%c\", 'a'):\n");
+	TPRINTF("Expected output: [a]\n");
+	TPRINTF("Real output:     [%c]\n\n", 'a');
 	
 	TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", 1, 2, 3, 4, 5):\n");
@@ -48,9 +48,9 @@
 	TPRINTF("Real output:     [%#x] [%#5.3x] [%#-5.3x] [%#3.5x] [%#-3.5x]\n\n", 17, 18, 19, 20, 21);
 	
-	unative_t nat = 0x12345678u;
+	unative_t nat = UINTN_C(0x12345678);
 	
-	TPRINTF("Testing printf(\"%%#" PRIx64 " %%#" PRIx32 " %%#" PRIx16 " %%#" PRIx8 " %%#" PRIxn " %%#" PRIx64 " %%s\", 0x1234567887654321ll, 0x12345678, 0x1234, 0x12, nat, 0x1234567887654321ull, \"Lovely string\"):\n");
+	TPRINTF("Testing printf(\"%%#" PRIx64 " %%#" PRIx32 " %%#" PRIx16 " %%#" PRIx8 " %%#" PRIxn " %%#" PRIx64 " %%s\", (uint64_t) UINT64_C(0x1234567887654321), (uint32_t) UINT32_C(0x12345678), (uint16_t) UINT16_C(0x1234), (uint8_t) UINT8_C(0x12), nat, (uint64_t) UINT64_C(0x1234567887654321), \"Lovely string\"):\n");
 	TPRINTF("Expected output: [0x1234567887654321] [0x12345678] [0x1234] [0x12] [0x12345678] [0x1234567887654321] \"Lovely string\"\n");
-	TPRINTF("Real output:     [%#" PRIx64 "] [%#" PRIx32 "] [%#" PRIx16 "] [%#" PRIx8 "] [%#" PRIxn "] [%#" PRIx64 "] \"%s\"\n\n", 0x1234567887654321ll, 0x12345678, 0x1234, 0x12, nat, 0x1234567887654321ull, "Lovely string");
+	TPRINTF("Real output:     [%#" PRIx64 "] [%#" PRIx32 "] [%#" PRIx16 "] [%#" PRIx8 "] [%#" PRIxn "] [%#" PRIx64 "] \"%s\"\n\n", (uint64_t) UINT64_C(0x1234567887654321), (uint32_t) UINT32_C(0x12345678), (uint16_t) UINT16_C(0x1234), (uint8_t) UINT8_C(0x12), nat, (uint64_t) UINT64_C(0x1234567887654321), "Lovely string");
 	
 	return NULL;
Index: kernel/test/print/print4.c
===================================================================
--- kernel/test/print/print4.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/print/print4.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -44,5 +44,5 @@
 		TPRINTF("  ");
 		for (index = 0; index < 32; index++)
-			TPRINTF("%lc", (wchar_t) ((group << 5) + index));
+			TPRINTF("%lc", (wint_t) ((group << 5) + index));
 		
 		TPRINTF("\n");
@@ -56,5 +56,5 @@
 		uint8_t index;
 		for (index = 0; index < 32; index++)
-			TPRINTF("%lc", (wchar_t) ((group << 5) + index));
+			TPRINTF("%lc", (wint_t) ((group << 5) + index));
 		
 		TPRINTF("\n");
Index: kernel/test/print/print5.c
===================================================================
--- kernel/test/print/print5.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ kernel/test/print/print5.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2005 Josef Cejka
+ * 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.
+ */
+
+/*
+ * This test tests several features of the HelenOS
+ * printf() implementation which go beyond the POSIX
+ * specification and GNU printf() behaviour.
+ *
+ * Therefore we disable printf() argument checking by
+ * the GCC compiler in this source file to avoid false
+ * positives.
+ *
+ */
+#define NVERIFY_PRINTF
+
+#include <print.h>
+#include <test.h>
+
+const char *test_print5(void)
+{
+	TPRINTF("Testing printf(\"%%s\", NULL):\n");
+	TPRINTF("Expected output: \"(NULL)\"\n");
+	TPRINTF("Real output:     \"%s\"\n\n", (char *) NULL);
+	
+	TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n");
+	TPRINTF("Expected output: [a] [  b] [c  ] [ d] [e ]\n");
+	TPRINTF("Real output:     [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e');
+	
+	return NULL;
+}
Index: kernel/test/print/print5.def
===================================================================
--- kernel/test/print/print5.def	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ kernel/test/print/print5.def	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,6 @@
+{
+	"print5",
+	"Extended printf test",
+	&test_print5,
+	true
+},
Index: kernel/test/synch/semaphore1.c
===================================================================
--- kernel/test/synch/semaphore1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/synch/semaphore1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -88,5 +88,6 @@
 		producers = (4 - i) * PRODUCERS;
 		
-		TPRINTF("Creating %d consumers and %d producers...", consumers, producers);
+		TPRINTF("Creating %" PRIua " consumers and %" PRIua " producers...",
+		    consumers, producers);
 		
 		for (j = 0; j < (CONSUMERS + PRODUCERS) / 2; j++) {
@@ -113,5 +114,6 @@
 		
 		while ((items_consumed.count != consumers) || (items_produced.count != producers)) {
-			TPRINTF("%d consumers remaining, %d producers remaining\n", consumers - items_consumed.count, producers - items_produced.count);
+			TPRINTF("%" PRIua " consumers remaining, %" PRIua " producers remaining\n",
+			    consumers - items_consumed.count, producers - items_produced.count);
 			thread_sleep(1);
 		}
Index: kernel/test/test.c
===================================================================
--- kernel/test/test.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/test.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -57,4 +57,5 @@
 #include <print/print3.def>
 #include <print/print4.def>
+#include <print/print5.def>
 #include <thread/thread1.def>
 	{
Index: kernel/test/test.h
===================================================================
--- kernel/test/test.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/test.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -76,4 +76,5 @@
 extern const char *test_print3(void);
 extern const char *test_print4(void);
+extern const char *test_print5(void);
 extern const char *test_thread1(void);
 
Index: kernel/test/thread/thread1.c
===================================================================
--- kernel/test/thread/thread1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ kernel/test/thread/thread1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -76,5 +76,5 @@
 	atomic_set(&finish, 0);
 	while (atomic_get(&threads_finished) < total) {
-		TPRINTF("Threads left: %d\n", total - atomic_get(&threads_finished));
+		TPRINTF("Threads left: %" PRIua "\n", total - atomic_get(&threads_finished));
 		thread_sleep(1);
 	}
Index: tools/autotool.py
===================================================================
--- tools/autotool.py	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ tools/autotool.py	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -49,22 +49,38 @@
 
 PACKAGE_BINUTILS = "usually part of binutils"
-PACKAGE_GCC = "preferably version 4.4.3 or newer"
+PACKAGE_GCC = "preferably version 4.5.1 or newer"
 PACKAGE_CROSS = "use tools/toolchain.sh to build the cross-compiler toolchain"
 
 COMPILER_FAIL = "The compiler is probably not capable to compile HelenOS."
-
-PROBE_HEAD = """#define AUTOTOOL_DECLARE(category, subcategory, tag, name, value) \\
+COMPILER_WARNING = "The compilation of HelenOS might fail."
+
+PROBE_HEAD = """#define AUTOTOOL_DECLARE(category, subcategory, tag, name, strc, conc, value) \\
 	asm volatile ( \\
-		"AUTOTOOL_DECLARE\\t" category "\\t" subcategory "\\t" tag "\\t" name "\\t%[val]\\n" \\
+		"AUTOTOOL_DECLARE\\t" category "\\t" subcategory "\\t" tag "\\t" name "\\t" strc "\\t" conc "\\t%[val]\\n" \\
 		: \\
 		: [val] "n" (value) \\
 	)
 
-#define DECLARE_INTSIZE(tag, type) \\
-	AUTOTOOL_DECLARE("intsize", "unsigned", tag, #type, sizeof(unsigned type)); \\
-	AUTOTOOL_DECLARE("intsize", "signed", tag, #type, sizeof(signed type))
+#define STRING(arg)      STRING_ARG(arg)
+#define STRING_ARG(arg)  #arg
+
+#define DECLARE_BUILTIN_TYPE(tag, type) \\
+	AUTOTOOL_DECLARE("builtin", "", tag, STRING(type), "", "", sizeof(type));
+
+#define DECLARE_INTSIZE(tag, type, strc, conc) \\
+	AUTOTOOL_DECLARE("intsize", "unsigned", tag, #type, strc, conc, sizeof(unsigned type)); \\
+	AUTOTOOL_DECLARE("intsize", "signed", tag, #type, strc, conc, sizeof(signed type));
 
 int main(int argc, char *argv[])
 {
+#ifdef __SIZE_TYPE__
+	DECLARE_BUILTIN_TYPE("size", __SIZE_TYPE__);
+#endif
+#ifdef __WCHAR_TYPE__
+	DECLARE_BUILTIN_TYPE("wchar", __WCHAR_TYPE__);
+#endif
+#ifdef __WINT_TYPE__
+	DECLARE_BUILTIN_TYPE("wint", __WINT_TYPE__);
+#endif
 """
 
@@ -96,4 +112,17 @@
 	
 	sys.exit(1)
+
+def print_warning(msg):
+	"Print a bold error message"
+	
+	sys.stderr.write("\n")
+	sys.stderr.write("######################################################################\n")
+	sys.stderr.write("HelenOS build sanity check warning:\n")
+	sys.stderr.write("\n")
+	sys.stderr.write("%s\n" % "\n".join(msg))
+	sys.stderr.write("######################################################################\n")
+	sys.stderr.write("\n")
+	
+	time.sleep(5)
 
 def sandbox_enter():
@@ -186,4 +215,18 @@
 	check_app([common['STRIP'], "--version"], "GNU strip", details)
 
+def decode_value(value):
+	"Decode integer value"
+	
+	base = 10
+	
+	if ((value.startswith('$')) or (value.startswith('#'))):
+		value = value[1:]
+	
+	if (value.startswith('0x')):
+		value = value[2:]
+		base = 16
+	
+	return int(value, base)
+
 def probe_compiler(common, sizes):
 	"Generate, compile and parse probing source"
@@ -195,5 +238,5 @@
 	
 	for typedef in sizes:
-		outf.write("\tDECLARE_INTSIZE(\"%s\", %s);\n" % (typedef['tag'], typedef['type']))
+		outf.write("\tDECLARE_INTSIZE(\"%s\", %s, %s, %s);\n" % (typedef['tag'], typedef['type'], typedef['strc'], typedef['conc']))
 	
 	outf.write(PROBE_TAIL)
@@ -231,4 +274,12 @@
 	signed_tags = {}
 	
+	unsigned_strcs = {}
+	signed_strcs = {}
+	
+	unsigned_concs = {}
+	signed_concs = {}
+	
+	builtins = {}
+	
 	for j in range(len(lines)):
 		tokens = lines[j].strip().split("\t")
@@ -236,5 +287,5 @@
 		if (len(tokens) > 0):
 			if (tokens[0] == "AUTOTOOL_DECLARE"):
-				if (len(tokens) < 5):
+				if (len(tokens) < 7):
 					print_error(["Malformed declaration in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
 				
@@ -243,33 +294,38 @@
 				tag = tokens[3]
 				name = tokens[4]
-				value = tokens[5]
+				strc = tokens[5]
+				conc = tokens[6]
+				value = tokens[7]
 				
 				if (category == "intsize"):
-					base = 10
-					
-					if ((value.startswith('$')) or (value.startswith('#'))):
-						value = value[1:]
-					
-					if (value.startswith('0x')):
-						value = value[2:]
-						base = 16
-					
 					try:
-						value_int = int(value, base)
+						value_int = decode_value(value)
 					except:
 						print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
 					
 					if (subcategory == "unsigned"):
-						unsigned_sizes[name] = value_int
+						unsigned_sizes[value_int] = name
 						unsigned_tags[tag] = value_int
+						unsigned_strcs[value_int] = strc
+						unsigned_concs[value_int] = conc
 					elif (subcategory == "signed"):
-						signed_sizes[name] = value_int
+						signed_sizes[value_int] = name
 						signed_tags[tag] = value_int
+						signed_strcs[value_int] = strc
+						signed_concs[value_int] = conc
 					else:
 						print_error(["Unexpected keyword \"%s\" in \"%s\" on line %s." % (subcategory, PROBE_OUTPUT, j), COMPILER_FAIL])
-	
-	return {'unsigned_sizes' : unsigned_sizes, 'signed_sizes' : signed_sizes, 'unsigned_tags': unsigned_tags, 'signed_tags': signed_tags}
-
-def detect_uints(probe, bytes):
+				
+				if (category == "builtin"):
+					try:
+						value_int = decode_value(value)
+					except:
+						print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
+					
+					builtins[tag] = {'name': name, 'value': value_int}
+	
+	return {'unsigned_sizes': unsigned_sizes, 'signed_sizes': signed_sizes, 'unsigned_tags': unsigned_tags, 'signed_tags': signed_tags, 'unsigned_strcs': unsigned_strcs, 'signed_strcs': signed_strcs, 'unsigned_concs': unsigned_concs, 'signed_concs': signed_concs, 'builtins': builtins}
+
+def detect_uints(probe, bytes, tags):
 	"Detect correct types for fixed-size integer types"
 	
@@ -278,63 +334,111 @@
 	
 	for b in bytes:
+		if (not b in probe['unsigned_sizes']):
+			print_error(['Unable to find appropriate unsigned integer type for %u bytes' % b,
+			             COMPILER_FAIL])
+		
+		if (not b in probe['signed_sizes']):
+			print_error(['Unable to find appropriate signed integer type for %u bytes' % b,
+			             COMPILER_FAIL])
+		
+		if (not b in probe['unsigned_strcs']):
+			print_error(['Unable to find appropriate unsigned printf formatter for %u bytes' % b,
+			             COMPILER_FAIL])
+		
+		if (not b in probe['signed_strcs']):
+			print_error(['Unable to find appropriate signed printf formatter for %u bytes' % b,
+			             COMPILER_FAIL])
+		
+		if (not b in probe['unsigned_concs']):
+			print_error(['Unable to find appropriate unsigned literal macro for %u bytes' % b,
+			             COMPILER_FAIL])
+		
+		if (not b in probe['signed_concs']):
+			print_error(['Unable to find appropriate signed literal macro for %u bytes' % b,
+			             COMPILER_FAIL])
+		
+		typedefs.append({'oldtype': "unsigned %s" % probe['unsigned_sizes'][b], 'newtype': "uint%u_t" % (b * 8)})
+		typedefs.append({'oldtype': "signed %s" % probe['signed_sizes'][b], 'newtype': "int%u_t" % (b * 8)})
+		
+		macros.append({'oldmacro': "\"%so\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIo%u" % (b * 8)})
+		macros.append({'oldmacro': "\"%su\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIu%u" % (b * 8)})
+		macros.append({'oldmacro': "\"%sx\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIx%u" % (b * 8)})
+		macros.append({'oldmacro': "\"%sX\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIX%u" % (b * 8)})
+		macros.append({'oldmacro': "\"%sd\"" % probe['signed_strcs'][b], 'newmacro': "PRId%u" % (b * 8)})
+		
+		name = probe['unsigned_concs'][b]
+		if ((name.startswith('@')) or (name == "")):
+			macros.append({'oldmacro': "c ## U", 'newmacro': "UINT%u_C(c)" % (b * 8)})
+		else:
+			macros.append({'oldmacro': "c ## U%s" % name, 'newmacro': "UINT%u_C(c)" % (b * 8)})
+		
+		name = probe['unsigned_concs'][b]
+		if ((name.startswith('@')) or (name == "")):
+			macros.append({'oldmacro': "c", 'newmacro': "INT%u_C(c)" % (b * 8)})
+		else:
+			macros.append({'oldmacro': "c ## %s" % name, 'newmacro': "INT%u_C(c)" % (b * 8)})
+	
+	for tag in tags:
+		newmacro = "U%s" % tag
+		if (not tag in probe['unsigned_tags']):
+			print_error(['Unable to find appropriate size macro for %s' % newmacro,
+			             COMPILER_FAIL])
+		
+		oldmacro = "UINT%s" % (probe['unsigned_tags'][tag] * 8)
+		macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro})
+		macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro})
+		
+		newmacro = tag
+		if (not tag in probe['unsigned_tags']):
+			print_error(['Unable to find appropriate size macro for %s' % newmacro,
+			             COMPILER_FAIL])
+		
+		oldmacro = "INT%s" % (probe['signed_tags'][tag] * 8)
+		macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro})
+		macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro})
+	
+	fnd = True
+	
+	if (not 'wchar' in probe['builtins']):
+		print_warning(['The compiler does not provide the macro __WCHAR_TYPE__',
+		               'for defining the compiler-native type wchar_t. We are',
+		               'forced to define wchar_t as a hardwired type int32_t.',
+		               COMPILER_WARNING])
 		fnd = False
-		newtype = "uint%s_t" % (b * 8)
-		
-		for name, value in probe['unsigned_sizes'].items():
-			if (value == b):
-				oldtype = "unsigned %s" % name
-				typedefs.append({'oldtype' : oldtype, 'newtype' : newtype})
-				fnd = True
-				break
-		
-		if (not fnd):
-			print_error(['Unable to find appropriate integer type for %s' % newtype,
-			             COMPILER_FAIL])
-		
-		
+	
+	if (probe['builtins']['wchar']['value'] != 4):
+		print_warning(['The compiler provided macro __WCHAR_TYPE__ for defining',
+		               'the compiler-native type wchar_t is not compliant with',
+		               'HelenOS. We are forced to define wchar_t as a hardwired',
+		               'type int32_t.',
+		               COMPILER_WARNING])
 		fnd = False
-		newtype = "int%s_t" % (b * 8)
-		
-		for name, value in probe['signed_sizes'].items():
-			if (value == b):
-				oldtype = "signed %s" % name
-				typedefs.append({'oldtype' : oldtype, 'newtype' : newtype})
-				fnd = True
-				break
-		
-		if (not fnd):
-			print_error(['Unable to find appropriate integer type for %s' % newtype,
-			             COMPILER_FAIL])
-	
-	for tag in ['CHAR', 'SHORT', 'INT', 'LONG', 'LLONG']:
-		fnd = False;
-		newmacro = "U%s" % tag
-		
-		for name, value in probe['unsigned_tags'].items():
-			if (name == tag):
-				oldmacro = "UINT%s" % (value * 8)
-				macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro})
-				macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro})
-				fnd = True
-				break
-		
-		if (not fnd):
-			print_error(['Unable to find appropriate size macro for %s' % newmacro,
-			             COMPILER_FAIL])
-		
-		fnd = False;
-		newmacro = tag
-		
-		for name, value in probe['signed_tags'].items():
-			if (name == tag):
-				oldmacro = "INT%s" % (value * 8)
-				macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro})
-				macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro})
-				fnd = True
-				break
-		
-		if (not fnd):
-			print_error(['Unable to find appropriate size macro for %s' % newmacro,
-			             COMPILER_FAIL])
+	
+	if (not fnd):
+		macros.append({'oldmacro': "int32_t", 'newmacro': "wchar_t"})
+	else:
+		macros.append({'oldmacro': "__WCHAR_TYPE__", 'newmacro': "wchar_t"})
+	
+	fnd = True
+	
+	if (not 'wint' in probe['builtins']):
+		print_warning(['The compiler does not provide the macro __WINT_TYPE__',
+		               'for defining the compiler-native type wint_t. We are',
+		               'forced to define wint_t as a hardwired type int32_t.',
+		               COMPILER_WARNING])
+		fnd = False
+	
+	if (probe['builtins']['wint']['value'] != 4):
+		print_warning(['The compiler provided macro __WINT_TYPE__ for defining',
+		               'the compiler-native type wint_t is not compliant with',
+		               'HelenOS. We are forced to define wint_t as a hardwired',
+		               'type int32_t.',
+		               COMPILER_WARNING])
+		fnd = False
+	
+	if (not fnd):
+		macros.append({'oldmacro': "int32_t", 'newmacro': "wint_t"})
+	else:
+		macros.append({'oldmacro': "__WINT_TYPE__", 'newmacro': "wint_t"})
 	
 	return {'macros': macros, 'typedefs': typedefs}
@@ -508,13 +612,13 @@
 		probe = probe_compiler(common,
 			[
-				{'type': 'char', 'tag': 'CHAR'},
-				{'type': 'short int', 'tag': 'SHORT'},
-				{'type': 'int', 'tag': 'INT'},
-				{'type': 'long int', 'tag': 'LONG'},
-				{'type': 'long long int', 'tag': 'LLONG'}
+				{'type': 'long long int', 'tag': 'LLONG', 'strc': '"ll"', 'conc': '"LL"'},
+				{'type': 'long int', 'tag': 'LONG', 'strc': '"l"', 'conc': '"L"'},
+				{'type': 'int', 'tag': 'INT', 'strc': '""', 'conc': '""'},
+				{'type': 'short int', 'tag': 'SHORT', 'strc': '"h"', 'conc': '"@"'},
+				{'type': 'char', 'tag': 'CHAR', 'strc': '"hh"', 'conc': '"@@"'}
 			]
 		)
 		
-		maps = detect_uints(probe, [1, 2, 4, 8])
+		maps = detect_uints(probe, [1, 2, 4, 8], ['CHAR', 'SHORT', 'INT', 'LONG', 'LLONG'])
 		
 	finally:
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -46,8 +46,8 @@
 	app/tasks \
 	app/tester \
-	app/test_serial \
 	app/tetris \
 	app/trace \
 	app/top \
+	app/virtusbkbd \
 	app/netecho \
 	app/nettest1 \
@@ -86,5 +86,6 @@
 	srv/net/tl/tcp \
 	srv/net/net \
-	drv/root
+	drv/root \
+	drv/vhc
 
 ## Networking
@@ -116,4 +117,6 @@
 	DIRS += drv/isa
 	DIRS += drv/ns8250
+	DIRS += drv/uhci
+	DIRS += drv/usbkbd
 endif
 
@@ -141,4 +144,14 @@
 	lib/packet \
 	lib/net
+
+ifeq ($(UARCH),amd64)
+	LIBS += lib/usb
+	LIBS += lib/usbvirt
+endif
+
+ifeq ($(UARCH),ia32)
+	LIBS += lib/usb
+	LIBS += lib/usbvirt
+endif
 
 LIBC_BUILD = $(addsuffix .build,$(LIBC))
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/Makefile.common	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -86,4 +86,7 @@
 LIBCLUI_PREFIX = $(LIB_PREFIX)/clui
 
+
+LIBUSB_PREFIX = $(LIB_PREFIX)/usb
+LIBUSBVIRT_PREFIX = $(LIB_PREFIX)/usbvirt
 LIBDRV_PREFIX = $(LIB_PREFIX)/drv
 LIBPACKET_PREFIX = $(LIB_PREFIX)/packet
Index: uspace/app/bdsh/cmds/modules/bdd/bdd.c
===================================================================
--- uspace/app/bdsh/cmds/modules/bdd/bdd.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/bdsh/cmds/modules/bdd/bdd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,4 +30,5 @@
 #include <stdlib.h>
 #include <str.h>
+#include <sys/typefmt.h>
 #include "config.h"
 #include "util.h"
@@ -122,5 +123,5 @@
 		rc = block_read_direct(handle, ba, 1, blk);
 		if (rc != EOK) {
-			printf("%s: Error reading block %llu\n", cmdname, ba);
+			printf("%s: Error reading block %" PRIuOFF64 "\n", cmdname, ba);
 			free(blk);
 			block_fini(handle);
Index: uspace/app/bdsh/cmds/modules/cp/cp.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cp/cp.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/bdsh/cmds/modules/cp/cp.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -95,5 +95,5 @@
 
 	if (vb)
-		printf("%d bytes to copy\n", total);
+		printf("%" PRIu64 " bytes to copy\n", total);
 
 	lseek(fd1, 0, SEEK_SET);
@@ -130,5 +130,5 @@
 		 */
 		if (res != 0) {
-			printf("\n%d more bytes than actually exist were copied\n", res);
+			printf("\n%zd more bytes than actually exist were copied\n", res);
 			goto err;
 		}
@@ -187,5 +187,5 @@
 			return CMD_SUCCESS;
 		case 'v':
-			printf("%d\n", CP_VERSION);
+			printf("%s\n", CP_VERSION);
 			return CMD_SUCCESS;
 		case 'V':
@@ -223,5 +223,5 @@
 
 	if (verbose)
-		printf("%d bytes copied\n", ret);
+		printf("%" PRId64 " bytes copied\n", ret);
 
 	if (ret >= 0)
Index: uspace/app/bdsh/cmds/modules/mkfile/mkfile.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mkfile/mkfile.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/bdsh/cmds/modules/mkfile/mkfile.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -168,5 +168,5 @@
 		rc = write(fd, buffer, to_write);
 		if (rc <= 0) {
-			printf("%s: Error writing file (%d).\n", cmdname, rc);
+			printf("%s: Error writing file (%zd).\n", cmdname, rc);
 			close(fd);
 			return CMD_FAILURE;
@@ -177,5 +177,5 @@
 	rc = close(fd);
 	if (rc != 0) {
-		printf("%s: Error writing file (%d).\n", cmdname, rc);
+		printf("%s: Error writing file (%zd).\n", cmdname, rc);
 		return CMD_FAILURE;
 	}
Index: uspace/app/bdsh/cmds/modules/unmount/unmount.c
===================================================================
--- uspace/app/bdsh/cmds/modules/unmount/unmount.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/bdsh/cmds/modules/unmount/unmount.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -47,5 +47,5 @@
 	} else {
 		help_cmd_unmount(HELP_SHORT);
-		printf("Usage:  %s <mp>\n", cmdname);
+		printf("Usage: %s <mp>\n", cmdname);
 	}
 	return;
@@ -68,5 +68,5 @@
 	rc = unmount(argv[1]);
 	if (rc != EOK) {
-		printf("Unable to unmount %s (rc=%d)\n", argv[1]);
+		printf("Unable to unmount %s (rc=%d)\n", argv[1], rc);
 		return CMD_FAILURE;
 	}
Index: uspace/app/bdsh/exec.c
===================================================================
--- uspace/app/bdsh/exec.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/bdsh/exec.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -133,5 +133,6 @@
 	rc = task_wait(tid, &texit, &retval);
 	if (rc != EOK) {
-		printf("%s: Failed waiting for command (%s)\n", str_error(rc));
+		printf("%s: Failed waiting for command (%s)\n", progname,
+		    str_error(rc));
 	} else if (texit != TASK_EXIT_NORMAL) {
 		printf("%s: Command failed (unexpectedly terminated)\n", progname);
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/edit/edit.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -781,5 +781,5 @@
 			c = str_decode(row_buf, &pos, size);
 			if (c != '\t') {
-				printf("%lc", c);
+				printf("%lc", (wint_t) c);
 				s_column += 1;
 			} else {
@@ -830,5 +830,7 @@
 	int n = printf(" %d, %d: File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
 	    "Ctrl-E Save As", coord.row, coord.column, fname);
-	printf("%*s", scr_columns - 1 - n, "");
+	
+	int pos = scr_columns - 1 - n;
+	printf("%*s", pos, "");
 	fflush(stdout);
 	console_set_style(con, STYLE_NORMAL);
@@ -1153,5 +1155,7 @@
 	console_set_pos(con, 0, scr_rows - 1);
 	console_set_style(con, STYLE_INVERTED);
-	printf(" %*s ", -(scr_columns - 3), str);
+	
+	int pos = -(scr_columns - 3);
+	printf(" %*s ", pos, str);
 	fflush(stdout);
 	console_set_style(con, STYLE_NORMAL);
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/init/init.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -312,4 +312,5 @@
 	getterm("term/vc5", "/app/bdsh", false);
 	getterm("term/vc6", "/app/klog", false);
+	getterm("term/vc7", "/srv/devman", false);
 	
 	return 0;
Index: uspace/app/netecho/netecho.c
===================================================================
--- uspace/app/netecho/netecho.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/netecho/netecho.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -220,5 +220,5 @@
 	// check the buffer size
 	if (size <= 0) {
-		fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
+		fprintf(stderr, "Receive size too small (%zu). Using 1024 bytes instead.\n", size);
 		size = 1024;
 	}
@@ -262,5 +262,5 @@
 		// check the backlog
 		if (backlog <= 0) {
-			fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
+			fprintf(stderr, "Accepted sockets queue size too small (%zu). Using 3 instead.\n", size);
 			backlog = 3;
 		}
@@ -325,5 +325,6 @@
 						break;
 					default:
-						fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
+						fprintf(stderr, "Address family %u (%#x) is not supported.\n",
+						    address->sa_family, address->sa_family);
 					}
 					// parse the source address
@@ -334,5 +335,6 @@
 						} else {
 							data[length] = '\0';
-							printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data);
+							printf("Socket %d received %zu bytes from %s:%d\n%s\n",
+							    socket_id, length, address_string, port, data);
 						}
 					}
Index: uspace/app/nettest1/nettest1.c
===================================================================
--- uspace/app/nettest1/nettest1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/nettest1/nettest1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -356,5 +356,5 @@
 	/* Check data buffer size */
 	if (size <= 0) {
-		fprintf(stderr, "Data buffer size too small (%d). Using 1024 "
+		fprintf(stderr, "Data buffer size too small (%zu). Using 1024 "
 		    "bytes instead.\n", size);
 		size = 1024;
@@ -410,5 +410,5 @@
 	}
 
-	printf("Tested in %d microseconds\n", tv_sub(&time_after,
+	printf("Tested in %ld microseconds\n", tv_sub(&time_after,
 	    &time_before));
 
Index: uspace/app/nettest2/nettest2.c
===================================================================
--- uspace/app/nettest2/nettest2.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/nettest2/nettest2.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -302,5 +302,5 @@
 	/* Check data buffer size. */
 	if (size <= 0) {
-		fprintf(stderr, "Data buffer size too small (%d). Using 1024 "
+		fprintf(stderr, "Data buffer size too small (%zu). Using 1024 "
 		    "bytes instead.\n", size);
 		size = 1024;
@@ -375,5 +375,5 @@
 		printf("\tOK\n");
 
-	printf("sendto + recvfrom tested in %d microseconds\n",
+	printf("sendto + recvfrom tested in %ld microseconds\n",
 	    tv_sub(&time_after, &time_before));
 
@@ -403,5 +403,5 @@
 		printf("\tOK\n");
 
-	printf("sendto, recvfrom tested in %d microseconds\n",
+	printf("sendto, recvfrom tested in %ld microseconds\n",
 	    tv_sub(&time_after, &time_before));
 
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/ping/ping.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -337,5 +337,5 @@
 	}
 	
-	printf("PING %s (%s) %u(%u) bytes of data\n", config.dest_addr,
+	printf("PING %s (%s) %zu(%zu) bytes of data\n", config.dest_addr,
 	    config.dest_str, config.size, config.size);
 	
@@ -378,9 +378,9 @@
 		switch (result) {
 		case ICMP_ECHO:
-			printf("%u bytes from ? (?): icmp_seq=%u ttl=? time=%u.%04u\n",
+			printf("%zu bytes from ? (?): icmp_seq=%u ttl=? time=%ld.%04ld\n",
 				config.size, seq, elapsed / 1000, elapsed % 1000);
 			break;
 		case ETIMEOUT:
-			printf("%u bytes from ? (?): icmp_seq=%u Timed out\n",
+			printf("%zu bytes from ? (?): icmp_seq=%u Timed out\n",
 				config.size, seq);
 			break;
Index: uspace/app/redir/redir.c
===================================================================
--- uspace/app/redir/redir.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/redir/redir.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -78,5 +78,5 @@
 {
 	const char **args;
-	task_id_t id;
+	task_id_t id = 0;
 	int rc;
 
Index: uspace/app/stats/stats.c
===================================================================
--- uspace/app/stats/stats.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/stats/stats.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -56,10 +56,12 @@
 	
 	uint64_t sec = time.tv_sec;
-	printf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64, (sec % DAY) / HOUR,
-	    (sec % HOUR) / MINUTE, sec % MINUTE);
+	printf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64,
+	    (sec % DAY) / HOUR, (sec % HOUR) / MINUTE, sec % MINUTE);
 	
 	sysarg_t uptime = stats_get_uptime();
-	printf(", up %u days, %u hours, %u minutes, %u seconds", uptime / DAY,
-	    (uptime % DAY) / HOUR, (uptime % HOUR) / MINUTE, uptime % MINUTE);
+	printf(", up %" PRIun " days, %" PRIun " hours, "
+	    "%" PRIun " minutes, %" PRIun " seconds",
+	    uptime / DAY, (uptime % DAY) / HOUR,
+	    (uptime % HOUR) / MINUTE, uptime % MINUTE);
 	
 	size_t count;
Index: uspace/app/taskdump/taskdump.c
===================================================================
--- uspace/app/taskdump/taskdump.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/taskdump/taskdump.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -85,5 +85,5 @@
 	rc = connect_task(task_id);
 	if (rc < 0) {
-		printf("Failed connecting to task %" PRIdTASKID ".\n", task_id);
+		printf("Failed connecting to task %" PRIu64 ".\n", task_id);
 		return 1;
 	}
@@ -92,5 +92,5 @@
 	app_symtab = NULL;
 
-	printf("Dumping task '%s' (task ID %" PRIdTASKID ").\n", app_name, task_id);
+	printf("Dumping task '%s' (task ID %" PRIu64 ").\n", app_name, task_id);
 	autoload_syms();
 	putchar('\n');
@@ -126,5 +126,5 @@
 	if (rc < 0) {
 		printf("Error connecting\n");
-		printf("ipc_connect_task(%" PRIdTASKID ") -> %d ", task_id, rc);
+		printf("ipc_connect_task(%" PRIu64 ") -> %d ", task_id, rc);
 		return rc;
 	}
@@ -168,5 +168,5 @@
 				core_file_name = *argv;
 			} else {
-				printf("Uknown option '%s'\n", arg[0]);
+				printf("Uknown option '%c'\n", arg[0]);
 				print_syntax();
 				return -1;
@@ -240,5 +240,5 @@
 	printf("Threads:\n");
 	for (i = 0; i < n_threads; i++) {
-		printf(" [%d] hash: %p\n", 1+i, thash_buf[i]);
+		printf(" [%zu] hash: %p\n", 1 + i, (void *) thash_buf[i]);
 
 		thread_dump(thash_buf[i]);
@@ -284,10 +284,10 @@
 	printf("Address space areas:\n");
 	for (i = 0; i < n_areas; i++) {
-		printf(" [%d] flags: %c%c%c%c base: %p size: %p\n", 1+i,
+		printf(" [%zu] flags: %c%c%c%c base: %p size: %zu\n", 1 + i,
 		    (ainfo_buf[i].flags & AS_AREA_READ) ? 'R' : '-',
 		    (ainfo_buf[i].flags & AS_AREA_WRITE) ? 'W' : '-',
 		    (ainfo_buf[i].flags & AS_AREA_EXEC) ? 'X' : '-',
 		    (ainfo_buf[i].flags & AS_AREA_CACHEABLE) ? 'C' : '-',
-		    ainfo_buf[i].start_addr, ainfo_buf[i].size);
+		    (void *) ainfo_buf[i].start_addr, ainfo_buf[i].size);
 	}
 
@@ -326,5 +326,6 @@
 
 	sym_pc = fmt_sym_address(pc);
-	printf("Thread %p crashed at %s. FP = %p\n", thash, sym_pc, fp);
+	printf("Thread %p crashed at %s. FP = %p\n", (void *) thash,
+	    sym_pc, (void *) fp);
 	free(sym_pc);
 
@@ -334,5 +335,5 @@
 	while (stacktrace_fp_valid(&st, fp)) {
 		sym_pc = fmt_sym_address(pc);
-		printf("  %p: %s\n", fp, sym_pc);
+		printf("  %p: %s\n", (void *) fp, sym_pc);
 		free(sym_pc);
 
@@ -457,7 +458,7 @@
 
 	if (rc == EOK) {
-		rc = asprintf(&str, "%p (%s+%p)", addr, name, offs);
+		rc = asprintf(&str, "%p (%s+%zu)", (void *) addr, name, offs);
 	} else {
-		rc = asprintf(&str, "%p", addr);
+		rc = asprintf(&str, "%p", (void *) addr);
 	}
 
Index: uspace/app/tasks/tasks.c
===================================================================
--- uspace/app/tasks/tasks.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tasks/tasks.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -77,5 +77,5 @@
 		order_suffix(stats_tasks[i].kcycles, &kcycles, &ksuffix);
 		
-		printf("%8" PRIu64 "%8u %8" PRIu64"%c %12"
+		printf("%8" PRIu64 "%8zu %8" PRIu64 "%c %12"
 		    PRIu64 "%c %12" PRIu64 "%c %s\n", stats_tasks[i].task_id,
 		    stats_tasks[i].threads, virtmem, vmsuffix, ucycles, usuffix,
@@ -160,5 +160,5 @@
 	}
 	
-	printf("%s: %u CPU(s) detected\n", NAME, count);
+	printf("%s: %zu CPU(s) detected\n", NAME, count);
 	
 	size_t i;
Index: pace/app/test_serial/Makefile
===================================================================
--- uspace/app/test_serial/Makefile	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ 	(revision )
@@ -1,36 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# 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.
-#
-
-USPACE_PREFIX = ../..
-BINARY = test_serial
-
-SOURCES = \
-	test_serial.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/app/test_serial/test_serial.c
===================================================================
--- uspace/app/test_serial/test_serial.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ 	(revision )
@@ -1,166 +1,0 @@
-/*
- * Copyright (c) 2009 Lenka Trochtova
- * 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 test_serial
- * @brief	test the serial port driver - read from the serial port
- * @{
- */
-/**
- * @file
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ipc/ipc.h>
-#include <sys/types.h>
-#include <async.h>
-#include <ipc/services.h>
-#include <ipc/devman.h>
-#include <devman.h>
-#include <device/char.h>
-#include <str.h>
-#include <ipc/serial_ctl.h>
-
-#define NAME 		"test serial"
-
-
-static void print_usage(void)
-{
-	printf("Usage: \n test_serial count \n where count is the number of "
-	    "characters to be read\n");
-}
-
-int main(int argc, char *argv[])
-{
-	if (argc != 2) {
-		printf(NAME ": incorrect number of arguments.\n");
-		print_usage();
-		return 0;
-	}
-	
-	long int cnt = strtol(argv[1], NULL, 10);
-	
-	int res;
-	res = devman_get_phone(DEVMAN_CLIENT, IPC_FLAG_BLOCKING);
-	devman_handle_t handle;
-	
-	res = devman_device_get_handle("/hw/pci0/00:01.0/com1", &handle,
-	    IPC_FLAG_BLOCKING);
-	if (EOK != res) {
-		printf(NAME ": could not get the device handle, errno = %d.\n",
-		    -res);
-		return 1;
-	}
-	
-	printf(NAME ": trying to read %d characters from device with handle "
-	    "%d.\n", cnt, handle);
-	
-	int phone = devman_device_connect(handle, IPC_FLAG_BLOCKING);
-	if (0 > phone) {
-		printf(NAME ": could not connect to the device, errno = %d.\n",
-		    -res);
-		devman_hangup_phone(DEVMAN_CLIENT);
-		return 2;
-	}
-	
-	char *buf = (char *) malloc(cnt + 1);
-	if (NULL == buf) {
-		printf(NAME ": failed to allocate the input buffer\n");
-		ipc_hangup(phone);
-		devman_hangup_phone(DEVMAN_CLIENT);
-		return 3;
-	}
-	
-	ipcarg_t old_baud, old_par, old_stop, old_word_size;
-	
-	res = ipc_call_sync_0_4(phone, SERIAL_GET_COM_PROPS, &old_baud,
-	    &old_par, &old_word_size, &old_stop);
-	if (EOK != res) {
-		printf(NAME ": failed to get old communication parameters, "
-		    "errno = %d.\n", -res);
-		devman_hangup_phone(DEVMAN_CLIENT);
-		ipc_hangup(phone);
-		free(buf);
-		return 4;
-	}
-	
-	res = ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, 1200,
-	    SERIAL_NO_PARITY, 8, 1);
-	if (EOK != res) {
-		printf(NAME ": failed to set communication parameters, errno = "
-		    "%d.\n", -res);
-		devman_hangup_phone(DEVMAN_CLIENT);
-		ipc_hangup(phone);
-		free(buf);
-		return 4;
-	}
-	
-	int total = 0;
-	int read = 0;
-	while (total < cnt) {
-		read = read_dev(phone, buf, cnt - total);
-		if (0 > read) {
-			printf(NAME ": failed read from device, errno = %d.\n",
-			    -read);
-			ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
-			    old_par, old_word_size, old_stop);
-			ipc_hangup(phone);
-			devman_hangup_phone(DEVMAN_CLIENT);
-			free(buf);
-			return 5;
-		}
-		total += read;
-		if (read > 0) {
-			buf[read] = 0;
-			printf(buf);
-			/*
-			 * Write data back to the device to test the opposite
-			 * direction of data transfer.
-			 */
-			write_dev(phone, buf, read);
-		} else {
-			usleep(100000);
-		}	
-	}
-	
-	const char *the_end = "\n---------\nTHE END\n---------\n";
-	write_dev(phone, (void *)the_end, str_size(the_end));
-	
-	/* restore original communication settings */
-	ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud, old_par,
-	    old_word_size, old_stop);
-	devman_hangup_phone(DEVMAN_CLIENT);
-	ipc_hangup(phone);
-	free(buf);
-	
-	return 0;
-}
-
-/** @}
- */
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -38,4 +38,5 @@
 	print/print3.c \
 	print/print4.c \
+	print/print5.c \
 	console/console1.c \
 	stdio/stdio1.c \
@@ -49,5 +50,6 @@
 	ipc/connect.c \
 	loop/loop1.c \
-	mm/malloc1.c
+	mm/malloc1.c \
+	hw/serial/serial1.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/tester/hw/serial/serial1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2009 Lenka Trochtova
+ * 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 tester
+ * @brief Test the serial port driver - loopback test
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <inttypes.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ipc/ipc.h>
+#include <sys/types.h>
+#include <async.h>
+#include <ipc/services.h>
+#include <ipc/devman.h>
+#include <devman.h>
+#include <device/char.h>
+#include <str.h>
+#include <ipc/serial_ctl.h>
+#include "../../tester.h"
+
+#define DEFAULT_COUNT  1024
+#define DEFAULT_SLEEP  100000
+#define EOT            "####> End of transfer <####\n"
+
+const char *test_serial1(void)
+{
+	size_t cnt;
+	
+	if (test_argc < 1)
+		cnt = DEFAULT_COUNT;
+	else
+		switch (str_size_t(test_argv[0], NULL, 0, true, &cnt)) {
+		case EOK:
+			break;
+		case EINVAL:
+			return "Invalid argument, unsigned integer expected";
+		case EOVERFLOW:
+			return "Argument size overflow";
+		default:
+			return "Unexpected argument error";
+		}
+	
+	int res = devman_get_phone(DEVMAN_CLIENT, IPC_FLAG_BLOCKING);
+	
+	devman_handle_t handle;
+	res = devman_device_get_handle("/hw/pci0/00:01.0/com1", &handle,
+	    IPC_FLAG_BLOCKING);
+	if (res != EOK)
+		return "Could not get serial device handle";
+	
+	int phone = devman_device_connect(handle, IPC_FLAG_BLOCKING);
+	if (phone < 0) {
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return "Unable to connect to serial device";
+	}
+	
+	char *buf = (char *) malloc(cnt + 1);
+	if (buf == NULL) {
+		ipc_hangup(phone);
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return "Failed to allocate input buffer";
+	}
+	
+	ipcarg_t old_baud;
+	ipcarg_t old_par;
+	ipcarg_t old_stop;
+	ipcarg_t old_word_size;
+	
+	res = ipc_call_sync_0_4(phone, SERIAL_GET_COM_PROPS, &old_baud,
+	    &old_par, &old_word_size, &old_stop);
+	if (res != EOK) {
+		free(buf);
+		ipc_hangup(phone);
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return "Failed to get old serial communication parameters";
+	}
+	
+	res = ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, 1200,
+	    SERIAL_NO_PARITY, 8, 1);
+	if (EOK != res) {
+		free(buf);
+		ipc_hangup(phone);
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return "Failed to set serial communication parameters";
+	}
+	
+	TPRINTF("Trying to read %zu characters from serial device "
+	    "(handle=%" PRIun ")\n", cnt, handle);
+	
+	size_t total = 0;
+	while (total < cnt) {
+		ssize_t read = read_dev(phone, buf, cnt - total);
+		
+		if (read < 0) {
+			ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+			    old_par, old_word_size, old_stop);
+			free(buf);
+			ipc_hangup(phone);
+			devman_hangup_phone(DEVMAN_CLIENT);
+			return "Failed read from serial device";
+		}
+		
+		if ((size_t) read > cnt - total) {
+			ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+			    old_par, old_word_size, old_stop);
+			free(buf);
+			ipc_hangup(phone);
+			devman_hangup_phone(DEVMAN_CLIENT);
+			return "Read more data than expected";
+		}
+		
+		TPRINTF("Read %zd bytes\n", read);
+		
+		if (read == 0)
+			usleep(DEFAULT_SLEEP);
+		else {
+			buf[read] = 0;
+			
+			/*
+			 * Write data back to the device to test the opposite
+			 * direction of data transfer.
+			 */
+			ssize_t written = write_dev(phone, buf, read);
+			
+			if (written < 0) {
+				ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+				    old_par, old_word_size, old_stop);
+				free(buf);
+				ipc_hangup(phone);
+				devman_hangup_phone(DEVMAN_CLIENT);
+				return "Failed write to serial device";
+			}
+			
+			if (written != read) {
+				ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+				    old_par, old_word_size, old_stop);
+				free(buf);
+				ipc_hangup(phone);
+				devman_hangup_phone(DEVMAN_CLIENT);
+				return "Written less data than read from serial device";
+			}
+			
+			TPRINTF("Written %zd bytes\n", written);
+		}
+		
+		total += read;
+	}
+	
+	TPRINTF("Trying to write EOT banner to the serial device\n");
+	
+	size_t eot_size = str_size(EOT);
+	ssize_t written = write_dev(phone, (void *) EOT, eot_size);
+	
+	ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+	    old_par, old_word_size, old_stop);
+	free(buf);
+	ipc_hangup(phone);
+	devman_hangup_phone(DEVMAN_CLIENT);
+	
+	if (written < 0)
+		return "Failed to write EOT banner to serial device";
+	
+	if ((size_t) written != eot_size)
+		return "Written less data than the size of the EOT banner "
+		    "to serial device";
+	
+	return NULL;
+}
+
+/** @}
+ */
Index: uspace/app/tester/hw/serial/serial1.def
===================================================================
--- uspace/app/tester/hw/serial/serial1.def	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/tester/hw/serial/serial1.def	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,6 @@
+{
+	"serial1",
+	"Serial loopback test",
+	&test_serial1,
+	false
+},
Index: uspace/app/tester/ipc/ping_pong.c
===================================================================
--- uspace/app/tester/ipc/ping_pong.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/ipc/ping_pong.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -72,5 +72,5 @@
 	}
 	
-	TPRINTF("OK\nCompleted %llu round trips in %u seconds, %llu rt/s.\n",
+	TPRINTF("OK\nCompleted %" PRIu64 " round trips in %u seconds, %" PRIu64 " rt/s.\n",
 	    count, DURATION_SECS, count / DURATION_SECS);
 	
Index: uspace/app/tester/ipc/register.c
===================================================================
--- uspace/app/tester/ipc/register.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/ipc/register.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -27,4 +27,5 @@
  */
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -41,5 +42,5 @@
 	unsigned int i;
 	
-	TPRINTF("Connected phone %#x accepting\n", icall->in_phone_hash);
+	TPRINTF("Connected phone %" PRIun " accepting\n", icall->in_phone_hash);
 	ipc_answer_0(iid, EOK);
 	for (i = 0; i < MAX_CONNECTIONS; i++) {
@@ -57,14 +58,14 @@
 		switch (IPC_GET_METHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
-			TPRINTF("Phone %#x hung up\n", icall->in_phone_hash);
+			TPRINTF("Phone %" PRIun " hung up\n", icall->in_phone_hash);
 			retval = 0;
 			break;
 		case IPC_TEST_METHOD:
-			TPRINTF("Received well known message from %#x: %#x\n",
+			TPRINTF("Received well known message from %" PRIun ": %" PRIun "\n",
 			    icall->in_phone_hash, callid);
 			ipc_answer_0(callid, EOK);
 			break;
 		default:
-			TPRINTF("Received unknown message from %#x: %#x\n",
+			TPRINTF("Received unknown message from %" PRIun ": %" PRIun "\n",
 			    icall->in_phone_hash, callid);
 			ipc_answer_0(callid, ENOENT);
Index: uspace/app/tester/print/print1.c
===================================================================
--- uspace/app/tester/print/print1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/print/print1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -49,8 +49,4 @@
 	TPRINTF("Real output:     \"%8.10s\"\n\n", "very long text");
 	
-	TPRINTF("Testing printf(\"%%s\", NULL):\n");
-	TPRINTF("Expected output: \"(NULL)\"\n");
-	TPRINTF("Real output:     \"%s\"\n\n", NULL);
-	
 	return NULL;
 }
Index: uspace/app/tester/print/print2.c
===================================================================
--- uspace/app/tester/print/print2.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/print/print2.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -33,7 +33,7 @@
 const char *test_print2(void)
 {
-	TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n");
-	TPRINTF("Expected output: [a] [  b] [c  ] [ d] [e ]\n");
-	TPRINTF("Real output:     [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e');
+	TPRINTF("Testing printf(\"%%c\", 'a'):\n");
+	TPRINTF("Expected output: [a]\n");
+	TPRINTF("Real output:     [%c]\n\n", 'a');
 	
 	TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", 1, 2, 3, 4, 5):\n");
Index: uspace/app/tester/print/print4.c
===================================================================
--- uspace/app/tester/print/print4.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/print/print4.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -45,5 +45,5 @@
 		TPRINTF("  ");
 		for (index = 0; index < 32; index++)
-			TPRINTF("%lc", (wchar_t) ((group << 5) + index));
+			TPRINTF("%lc", (wint_t) ((group << 5) + index));
 		
 		TPRINTF("\n");
@@ -57,5 +57,5 @@
 		uint8_t index;
 		for (index = 0; index < 32; index++)
-			TPRINTF("%lc", (wchar_t) ((group << 5) + index));
+			TPRINTF("%lc", (wint_t) ((group << 5) + index));
 		
 		TPRINTF("\n");
Index: uspace/app/tester/print/print5.c
===================================================================
--- uspace/app/tester/print/print5.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/tester/print/print5.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2005 Josef Cejka
+ * 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.
+ */
+
+/*
+ * This test tests several features of the HelenOS
+ * printf() implementation which go beyond the POSIX
+ * specification and GNU printf() behaviour.
+ *
+ * Therefore we disable printf() argument checking by
+ * the GCC compiler in this source file to avoid false
+ * positives.
+ *
+ */
+#define NVERIFY_PRINTF
+
+#include <stdio.h>
+#include <unistd.h>
+#include "../tester.h"
+
+const char *test_print5(void)
+{
+	TPRINTF("Testing printf(\"%%s\", NULL):\n");
+	TPRINTF("Expected output: \"(NULL)\"\n");
+	TPRINTF("Real output:     \"%s\"\n\n", (char *) NULL);
+	
+	TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n");
+	TPRINTF("Expected output: [a] [  b] [c  ] [ d] [e ]\n");
+	TPRINTF("Real output:     [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e');
+	
+	return NULL;
+}
Index: uspace/app/tester/print/print5.def
===================================================================
--- uspace/app/tester/print/print5.def	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/tester/print/print5.def	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,6 @@
+{
+	"print1",
+	"String printf test",
+	&test_print1,
+	true
+},
Index: uspace/app/tester/stdio/stdio1.c
===================================================================
--- uspace/app/tester/stdio/stdio1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/stdio/stdio1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -60,5 +60,5 @@
 	
 	buf[cnt] = '\0';
-	TPRINTF("Read %u bytes, string \"%s\"\n", cnt, buf);
+	TPRINTF("Read %zu bytes, string \"%s\"\n", cnt, buf);
 	
 	TPRINTF("Seek to beginning...");
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/tester.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -51,4 +51,5 @@
 #include "print/print3.def"
 #include "print/print4.def"
+#include "print/print5.def"
 #include "console/console1.def"
 #include "stdio/stdio1.def"
@@ -63,4 +64,5 @@
 #include "loop/loop1.def"
 #include "mm/malloc1.def"
+#include "hw/serial/serial1.def"
 	{NULL, NULL, NULL, false}
 };
@@ -110,8 +112,15 @@
 	}
 	
+	unsigned int _len = (unsigned int) len;
+	if ((_len != len) || (((int) _len) < 0)) {
+		printf("Command length overflow\n");
+		return;
+	}
+	
 	for (test = tests; test->name != NULL; test++)
-		printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
+		printf("%-*s %s%s\n", _len, test->name, test->desc,
+		    (test->safe ? "" : " (unsafe)"));
 	
-	printf("%-*s Run all safe tests\n", len, "*");
+	printf("%-*s Run all safe tests\n", _len, "*");
 }
 
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/tester.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -68,4 +68,5 @@
 extern const char *test_print3(void);
 extern const char *test_print4(void);
+extern const char *test_print5(void);
 extern const char *test_console1(void);
 extern const char *test_stdio1(void);
@@ -80,4 +81,5 @@
 extern const char *test_loop1(void);
 extern const char *test_malloc1(void);
+extern const char *test_serial1(void);
 
 extern test_t tests[];
Index: uspace/app/tester/thread/thread1.c
===================================================================
--- uspace/app/tester/thread/thread1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/thread/thread1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -35,4 +35,5 @@
 #include <stdio.h>
 #include <unistd.h>
+#include <inttypes.h>
 #include "../tester.h"
 
@@ -74,5 +75,6 @@
 	atomic_set(&finish, 0);
 	while (atomic_get(&threads_finished) < total) {
-		TPRINTF("Threads left: %u\n", total - atomic_get(&threads_finished));
+		TPRINTF("Threads left: %" PRIua "\n",
+		    total - atomic_get(&threads_finished));
 		sleep(1);
 	}
Index: uspace/app/tester/vfs/vfs1.c
===================================================================
--- uspace/app/tester/vfs/vfs1.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/tester/vfs/vfs1.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -105,5 +105,5 @@
 	if (cnt < 0)
 		return "write() failed";
-	TPRINTF("Written %d bytes\n", cnt);
+	TPRINTF("Written %zd bytes\n", cnt);
 	
 	if (lseek(fd0, 0, SEEK_SET) != 0)
@@ -116,5 +116,11 @@
 			return "read() failed";
 		
-		TPRINTF("Read %d bytes: \".*s\"\n", cnt, cnt, buf);
+		int _cnt = (int) cnt;
+		if (_cnt != cnt) {
+			/* Count overflow, just to be sure. */
+			TPRINTF("Read %zd bytes\n", cnt);
+		} else {
+			TPRINTF("Read %zd bytes: \"%.*s\"\n", cnt, _cnt, buf);
+		}
 	}
 	
Index: uspace/app/top/screen.c
===================================================================
--- uspace/app/top/screen.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/top/screen.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -150,11 +150,15 @@
 	screen_get_pos(&c, &r);
 	
-	if (c < cols)
-		printf("%.*s", cols - c - 1, str);
+	if (c < cols) {
+		int pos = cols - c - 1;
+		printf("%.*s", pos, str);
+	}
 }
 
 static inline void print_global_head(data_t *data)
 {
-	printf("top - %02lu:%02lu:%02lu up %u days, %02u:%02u:%02u, load average:",
+	printf("top - %02lu:%02lu:%02lu up "
+	    "%" PRIun " days, %02" PRIun ":%02" PRIun ":%02" PRIun ", "
+	    "load average:",
 	    data->hours, data->minutes, data->seconds,
 	    data->udays, data->uhours, data->uminutes, data->useconds);
@@ -171,5 +175,5 @@
 static inline void print_task_summary(data_t *data)
 {
-	printf("tasks: %u total", data->tasks_count);
+	printf("tasks: %zu total", data->tasks_count);
 	screen_newline();
 }
@@ -211,6 +215,6 @@
 	}
 	
-	printf("threads: %u total, %u running, %u ready, %u sleeping, %u lingering, "
-	    "%u other, %u invalid",
+	printf("threads: %zu total, %zu running, %zu ready, "
+	    "%zu sleeping, %zu lingering, %zu other, %zu invalid",
 	    total, running, ready, sleeping, lingering, other, invalid);
 	screen_newline();
@@ -295,5 +299,5 @@
 		order_suffix(task->virtmem, &virtmem, &virtmem_suffix);
 		
-		printf("%-8" PRIu64 " %9u %8" PRIu64 "%c ", task->task_id,
+		printf("%-8" PRIu64 " %9zu %8" PRIu64 "%c ", task->task_id,
 		    task->threads, virtmem, virtmem_suffix);
 		print_percent(perc->virtmem, 2);
Index: uspace/app/trace/ipcp.c
===================================================================
--- uspace/app/trace/ipcp.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/trace/ipcp.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -137,9 +137,9 @@
 
 	if (oper != NULL) {
-		printf("%s (%ld)", oper->name, method);
+		printf("%s (%" PRIun ")", oper->name, method);
 		return;
 	}
 
-	printf("%ld", method);
+	printf("%" PRIun, method);
 }
 
@@ -201,10 +201,11 @@
 
 	if ((display_mask & DM_IPC) != 0) {
-		printf("Call ID: %p, phone: %d, proto: %s, method: ", hash,
-			phone, (proto ? proto->name : "n/a"));
+		printf("Call ID: %p, phone: %d, proto: %s, method: ",
+		    (void *) hash, phone,
+		    (proto ? proto->name : "n/a"));
 		ipc_m_print(proto, IPC_GET_METHOD(*call));
-		printf(" args: (%" PRIuIPCARG ", %" PRIuIPCARG ", %" PRIuIPCARG
-		    ", %" PRIuIPCARG ", %" PRIuIPCARG ")\n", args[1], args[2],
-		    args[3], args[4], args[5]);
+		printf(" args: (%" PRIun ", %" PRIun ", %" PRIun ", "
+		    "%" PRIun ", %" PRIun ")\n",
+		    args[1], args[2], args[3], args[4], args[5]);
 	}
 
@@ -281,8 +282,7 @@
 
 	if ((display_mask & DM_IPC) != 0) {
-		printf("Response to %p: retval=%ld, args = (%" PRIuIPCARG
-		    ", %" PRIuIPCARG ", %" PRIuIPCARG ", %" PRIuIPCARG
-		    ", %" PRIuIPCARG ")\n",
-		    hash, retval, IPC_GET_ARG1(*answer),
+		printf("Response to %p: retval=%" PRIdn ", args = (%" PRIun ", "
+		    "%" PRIun ", %" PRIun ", %" PRIun ", %" PRIun ")\n",
+		    (void *) hash, retval, IPC_GET_ARG1(*answer),
 		    IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer),
 		    IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
@@ -340,5 +340,5 @@
 		/* Not a response */
 		if ((display_mask & DM_IPC) != 0) {
-			printf("Not a response (hash %p)\n", hash);
+			printf("Not a response (hash %p)\n", (void *) hash);
 		}
 		return;
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/app/trace/trace.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -161,5 +161,5 @@
 	if (rc < 0) {
 		printf("Error connecting\n");
-		printf("ipc_connect_task(%" PRIdTASKID ") -> %d ", task_id, rc);
+		printf("ipc_connect_task(%" PRIu64 ") -> %d ", task_id, rc);
 		return rc;
 	}
@@ -200,7 +200,7 @@
 	printf("Threads:");
 	for (i = 0; i < n_threads; i++) {
-		printf(" [%d] (hash %p)", 1+i, thread_hash_buf[i]);
-	}
-	printf("\ntotal of %u threads\n", tb_needed / sizeof(uintptr_t));
+		printf(" [%d] (hash %p)", 1 + i, (void *) thread_hash_buf[i]);
+	}
+	printf("\ntotal of %zu threads\n", tb_needed / sizeof(uintptr_t));
 
 	return 0;
@@ -224,5 +224,5 @@
 	case V_HASH:
 	case V_PTR:
-		printf("%p", val);
+		printf("%p", (void *) val);
 		break;
 
@@ -248,5 +248,5 @@
 	case V_CHAR:
 		if (sval >= 0x20 && sval < 0x7f) {
-			printf("'%c'", sval);
+			printf("'%c'", (char) sval);
 		} else {
 			switch (sval) {
@@ -257,5 +257,5 @@
 			case '\t': printf("'\\t'"); break;
 			case '\\': printf("'\\\\'"); break;
-			default: printf("'\\x%02lX'", val); break;
+			default: printf("'\\x%02" PRIxn "'", val); break;
 			}
 		}
@@ -277,7 +277,7 @@
 
 	putchar('(');
-	if (n > 0) printf("%" PRIdSYSARG, sc_args[0]);
+	if (n > 0) printf("%" PRIun, sc_args[0]);
 	for (i = 1; i < n; i++) {
-		printf(", %" PRIdSYSARG, sc_args[i]);
+		printf(", %" PRIun, sc_args[i]);
 	}
 	putchar(')');
@@ -489,5 +489,5 @@
 {
 	async_serialize_start();
-	printf("New thread, hash 0x%lx\n", hash);
+	printf("New thread, hash %p\n", (void *) hash);
 	async_serialize_end();
 
@@ -510,5 +510,6 @@
 	}
 
-	printf("Start tracing thread [%d] (hash %p).\n", thread_id, thread_hash);
+	printf("Start tracing thread [%u] (hash %p).\n",
+	    thread_id, (void *) thread_hash);
 
 	while (!abort_trace) {
@@ -516,5 +517,5 @@
 		fibril_mutex_lock(&state_lock);
 		if (paused) {
-			printf("Thread [%d] paused. Press R to resume.\n",
+			printf("Thread [%u] paused. Press R to resume.\n",
 			    thread_id);
 
@@ -522,5 +523,5 @@
 				fibril_condvar_wait(&state_cv, &state_lock);
 
-			printf("Thread [%d] resumed.\n", thread_id);
+			printf("Thread [%u] resumed.\n", thread_id);
 		}
 		fibril_mutex_unlock(&state_lock);
@@ -554,5 +555,5 @@
 				break;
 			case UDEBUG_EVENT_THREAD_E:
-				printf("Thread %p exited.\n", val0);
+				printf("Thread %" PRIun " exited.\n", val0);
 				fibril_mutex_lock(&state_lock);
 				abort_trace = true;
@@ -927,5 +928,5 @@
 				}
 			} else {
-				printf("Uknown option '%s'\n", arg[0]);
+				printf("Uknown option '%c'\n", arg[0]);
 				print_syntax();
 				return -1;
@@ -984,9 +985,9 @@
 	rc = connect_task(task_id);
 	if (rc < 0) {
-		printf("Failed connecting to task %" PRIdTASKID ".\n", task_id);
+		printf("Failed connecting to task %" PRIu64 ".\n", task_id);
 		return 1;
 	}
 
-	printf("Connected to task %" PRIdTASKID ".\n", task_id);
+	printf("Connected to task %" PRIu64 ".\n", task_id);
 
 	if (task_ldr != NULL)
Index: uspace/app/virtusbkbd/Makefile
===================================================================
--- uspace/app/virtusbkbd/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+# acronym for virtual usb keyboard
+# (it is really annoying to write long names)
+BINARY = vuk
+
+LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a
+EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX)
+
+SOURCES = \
+	kbdconfig.c \
+	keys.c \
+	stdreq.c \
+	virtusbkbd.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/virtusbkbd/descriptor.h
===================================================================
--- uspace/app/virtusbkbd/descriptor.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/descriptor.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,51 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB keyboard descriptors.
+ */
+#ifndef VUK_DESCRIPTOR_H_
+#define VUK_DESCRIPTOR_H_
+
+typedef struct {
+	uint8_t length;
+	uint8_t type;
+	uint16_t hid_spec_release;
+	uint8_t country_code;
+	uint8_t descriptor_count;
+	uint8_t descriptor1_type;
+	uint16_t descriptor1_length;
+} __attribute__ ((packed)) hid_descriptor_t;
+
+#endif
+/**
+ * @}
+ */
Index: uspace/app/virtusbkbd/items.h
===================================================================
--- uspace/app/virtusbkbd/items.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/items.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,113 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief HID Item related functions.
+ */
+#ifndef VUK_ITEM_H_
+#define VUK_ITEM_H_
+
+#include <sys/types.h>
+
+typedef uint8_t report_descriptor_data_t[];
+
+/* Item types. */
+#define ITEM_MAIN 0
+#define ITEM_GLOBAL 1
+#define ITEM_LOCAL 2
+
+
+
+/* Item tags. */
+
+/* Main item tags. */
+#define TAG_INPUT 8
+#define TAG_OUTPUT 9
+#define TAG_FEATURE 11
+#define TAG_COLLECTION 10
+#define TAG_END_COLLECTION 12
+
+/* Global item tags. */
+#define TAG_USAGE_PAGE 0
+#define TAG_LOGICAL_MINIMUM 1
+#define TAG_LOGICAL_MAXIMUM 2
+#define TAG_REPORT_SIZE 7
+#define TAG_REPORT_COUNT 9
+
+/* Local item tags. */
+#define TAG_USAGE 0
+#define TAG_USAGE_MINIMUM 1
+#define TAG_USAGE_MAXIMUM 2
+
+
+/* Bits for Input, Output and Feature items. */
+#define _IOF(value, shift) ((value) << (shift))
+#define IOF_DATA _IOF(0, 0)
+#define IOF_CONSTANT _IOF(1, 0)
+#define IOF_ARRAY _IOF(0, 1)
+#define IOF_VARIABLE _IOF(1, 1)
+#define IOF_ABSOLUTE _IOF(0, 2)
+#define IOF_RELATIVE _IOF(1, 2)
+/* ... */
+
+/* Collection types. */
+#define COLLECTION_PHYSICAL 0x00
+#define COLLECTION_APPLICATION 0x01
+
+
+/** Creates item prefix.
+ * @param size Item size.
+ * @param type Item type.
+ * @param tag Item tag.
+ */
+#define BUILD_ITEM_PREFIX(size, type, tag) \
+	((size) | ((type) << 2) | ((tag) << 4))
+
+/** Create no-data item.
+ * @param type Item type.
+ * @param tag Item tag.
+ */
+#define ITEM_CREATE0(type, tag) \
+	BUILD_ITEM_PREFIX(0, type, tag)
+
+/** Create item with 1-byte data.
+ * @param type Item type.
+ * @param tag Item tag.
+ * @param data Item data (single byte).
+ */
+#define ITEM_CREATE1(type, tag, data) \
+	BUILD_ITEM_PREFIX(1, type, tag), data
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/app/virtusbkbd/kbdconfig.c
===================================================================
--- uspace/app/virtusbkbd/kbdconfig.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/kbdconfig.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,155 @@
+/*
+ * 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 usb
+ * @{
+ */
+/**
+ * @file
+ * @brief Keyboard configuration.
+ */
+#include "kbdconfig.h"
+#include "keys.h"
+#include <usb/usb.h>
+#include <usb/classes/hid.h>
+#include <usb/classes/hidut.h>
+#include <usb/classes/classes.h>
+
+/** Standard device descriptor. */
+usb_standard_device_descriptor_t std_device_descriptor = {
+	.length = sizeof(usb_standard_device_descriptor_t),
+	.descriptor_type = USB_DESCTYPE_DEVICE,
+	.usb_spec_version = 0x110,
+	.device_class = USB_CLASS_USE_INTERFACE,
+	.device_subclass = 0,
+	.device_protocol = 0,
+	.max_packet_size = 64,
+	.configuration_count = 1
+};
+
+/** Standard interface descriptor. */
+usb_standard_interface_descriptor_t std_interface_descriptor = {
+	.length = sizeof(usb_standard_interface_descriptor_t),
+	.descriptor_type = USB_DESCTYPE_INTERFACE,
+	.interface_number = 0,
+	.alternate_setting = 0,
+	.endpoint_count = 1,
+	.interface_class = USB_CLASS_HID,
+	.interface_subclass = 0,
+	.interface_protocol = USB_HID_PROTOCOL_KEYBOARD,
+	.str_interface = 0
+};
+
+/** USB keyboard report descriptor.
+ * Copied from USB HID 1.11 (section E.6).
+ */
+report_descriptor_data_t report_descriptor = {
+	STD_USAGE_PAGE(USB_HIDUT_PAGE_GENERIC_DESKTOP),
+	USAGE1(USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD),
+	START_COLLECTION(COLLECTION_APPLICATION),
+		STD_USAGE_PAGE(USB_HIDUT_PAGE_KEYBOARD),
+		USAGE_MINIMUM1(224),
+		USAGE_MAXIMUM1(231),
+		LOGICAL_MINIMUM1(0),
+		LOGICAL_MAXIMUM1(1),
+		REPORT_SIZE1(1),
+		REPORT_COUNT1(8),
+		/* Modifiers */
+		INPUT(IOF_DATA | IOF_VARIABLE | IOF_ABSOLUTE),
+		REPORT_COUNT1(1),
+		REPORT_SIZE1(8),
+		/* Reserved */
+		INPUT(IOF_CONSTANT),
+		REPORT_COUNT1(5),
+		REPORT_SIZE1(1),
+		STD_USAGE_PAGE(USB_HIDUT_PAGE_LED),
+		USAGE_MINIMUM1(1),
+		USAGE_MAXIMUM1(5),
+		/* LED states */
+		OUTPUT(IOF_DATA | IOF_VARIABLE | IOF_ABSOLUTE),
+		REPORT_COUNT1(1),
+		REPORT_SIZE1(3),
+		/* LED states padding */
+		OUTPUT(IOF_CONSTANT),
+		REPORT_COUNT1(KB_MAX_KEYS_AT_ONCE),
+		REPORT_SIZE1(8),
+		LOGICAL_MINIMUM1(0),
+		LOGICAL_MAXIMUM1(101),
+		STD_USAGE_PAGE(USB_HIDUT_PAGE_KEYBOARD),
+		USAGE_MINIMUM1(0),
+		USAGE_MAXIMUM1(101),
+		/* Key array */
+		INPUT(IOF_DATA | IOF_ARRAY),
+	END_COLLECTION()
+};
+size_t report_descriptor_size = sizeof(report_descriptor);
+
+/** HID descriptor. */
+hid_descriptor_t hid_descriptor = {
+	.length = sizeof(hid_descriptor_t),
+	.type = 0x21, // HID descriptor
+	.hid_spec_release = 0x101,
+	.country_code = 0,
+	.descriptor_count = 1,
+	.descriptor1_type = 0x22, // Report descriptor
+	.descriptor1_length = sizeof(report_descriptor)
+};
+
+/** Endpoint descriptor. */
+usb_standard_endpoint_descriptor_t endpoint_descriptor = {
+	.length = sizeof(usb_standard_endpoint_descriptor_t),
+	.descriptor_type = USB_DESCTYPE_ENDPOINT,
+	.endpoint_address = 1 | 128,
+	.attributes = USB_TRANSFER_INTERRUPT,
+	.max_packet_size = 8,
+	.poll_interval = 10
+};
+
+/** Standard configuration descriptor. */
+usb_standard_configuration_descriptor_t std_configuration_descriptor = {
+	.length = sizeof(usb_standard_configuration_descriptor_t),
+	.descriptor_type = USB_DESCTYPE_CONFIGURATION,
+	.total_length = 
+		sizeof(usb_standard_configuration_descriptor_t)
+		+ sizeof(std_interface_descriptor)
+		+ sizeof(hid_descriptor)
+		+ sizeof(endpoint_descriptor)
+		,
+	.interface_count = 1,
+	.configuration_number = 1,
+	.str_configuration = 0,
+	.attributes = 128, /* denotes bus-powered device */
+	.max_power = 50
+};
+
+
+
+
+
+/** @}
+ */
Index: uspace/app/virtusbkbd/kbdconfig.h
===================================================================
--- uspace/app/virtusbkbd/kbdconfig.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/kbdconfig.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,60 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB keyboard configuration.
+ */
+#ifndef VUK_KBDCONFIG_H_
+#define VUK_KBDCONFIG_H_
+
+#include <usb/descriptor.h>
+#include "report.h"
+#include "descriptor.h"
+
+extern usb_standard_device_descriptor_t std_device_descriptor;
+
+extern usb_standard_configuration_descriptor_t std_configuration_descriptor;
+
+extern usb_standard_interface_descriptor_t std_interface_descriptor;
+
+extern usb_standard_endpoint_descriptor_t endpoint_descriptor;
+
+
+extern hid_descriptor_t hid_descriptor;
+
+extern report_descriptor_data_t report_descriptor;
+extern size_t report_descriptor_size;
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/app/virtusbkbd/keys.c
===================================================================
--- uspace/app/virtusbkbd/keys.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/keys.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,123 @@
+/*
+ * 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 usb
+ * @{
+ */
+/**
+ * @file
+ * @brief Keyboard keys related structures.
+ */
+#include "keys.h"
+
+/** Initializes keyboard status. */
+void kb_init(kb_status_t *status)
+{
+	status->modifiers = 0;
+	size_t i;
+	for (i = 0; i < KB_MAX_KEYS_AT_ONCE; i++) {
+		status->pressed_keys[i] = 0;
+	}
+}
+
+/** Change pressed modifiers. */
+void kb_change_modifier(kb_status_t *status, kb_key_action_t action,
+    kb_modifier_t modifier)
+{
+	if (action == KB_KEY_DOWN) {
+		status->modifiers = status->modifiers | modifier;
+	} else {
+		status->modifiers = status->modifiers & (~modifier);
+	}
+}
+
+/** Find index of given key in key code array.
+ * @retval (size_t)-1 Key not found.
+ */
+static size_t find_key_index(kb_key_code_t *keys, size_t size, kb_key_code_t key)
+{
+	size_t i;
+	for (i = 0; i < size; i++) {
+		if (keys[i] == key) {
+			return i;
+		}
+	}
+	return (size_t)-1;
+}
+
+/** Change pressed key. */
+void kb_change_key(kb_status_t *status, kb_key_action_t action,
+    kb_key_code_t key_code)
+{
+	size_t pos = find_key_index(status->pressed_keys, KB_MAX_KEYS_AT_ONCE,
+	    key_code);
+	if (action == KB_KEY_DOWN) {
+		if (pos != (size_t)-1) {
+			return;
+		}
+		/*
+		 * Find first free item in the array.
+		 */
+		size_t i;
+		for (i = 0; i < KB_MAX_KEYS_AT_ONCE; i++) {
+			if (status->pressed_keys[i] == 0) {
+				status->pressed_keys[i] = key_code;
+				return;
+			}
+		}
+		// TODO - handle buffer overflow
+	} else {
+		if (pos == (size_t)-1) {
+			return;
+		}
+		status->pressed_keys[pos] = 0;
+	}	
+}
+
+/** Process list of events. */
+void kb_process_events(kb_status_t *status,
+    kb_event_t *events, size_t count,
+    kb_on_status_change on_change)
+{
+	while (count-- > 0) {
+		if (events->normal_key) {
+			kb_change_key(status, events->action,
+			    events->key_change);
+		} else {
+			kb_change_modifier(status, events->action,
+			    events->modifier_change);
+		}
+		if (on_change) {
+			on_change(status);
+		}
+		events++;
+	}
+}
+
+/** @}
+ */
Index: uspace/app/virtusbkbd/keys.h
===================================================================
--- uspace/app/virtusbkbd/keys.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/keys.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,121 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Keyboard keys related structures.
+ */
+#ifndef VUK_KEYS_H_
+#define VUK_KEYS_H_
+
+#include <sys/types.h>
+#include <bool.h>
+
+/** Maximum number of keys that can be pressed simultaneously. */
+#define KB_MAX_KEYS_AT_ONCE 4
+
+/** Key code type. */
+typedef uint8_t kb_key_code_t;
+
+#define USB_HIDUT_KBD_KEY(name, usage_id, l, lc, l1, l2) \
+	KB_KEY_##name = usage_id,
+/** USB key code. */
+typedef enum {
+	#include <usb/classes/hidutkbd.h>
+} key_code_t;
+
+/** Modifier type. */
+typedef uint8_t kb_modifier_t;
+#define _KB_MOD(shift) (1 << (shift))
+#define KB_MOD_LEFT_CTRL _KB_MOD(0)
+#define KB_MOD_LEFT_SHIFT _KB_MOD(1)
+#define KB_MOD_LEFT_ALT _KB_MOD(2)
+#define KB_MOD_LEFT_GUI _KB_MOD(3)
+#define KB_MOD_RIGHT_CTRL _KB_MOD(4)
+#define KB_MOD_RIGHT_SHIFT _KB_MOD(5)
+#define KB_MOD_RIGHT_ALT _KB_MOD(6)
+#define KB_MOD_RIGHT_GUI _KB_MOD(7)
+
+/** Base key action. */
+typedef enum {
+	KB_KEY_DOWN,
+	KB_KEY_UP
+} kb_key_action_t;
+
+/** Keyboard status. */
+typedef struct {
+	/** Bitmap of pressed modifiers. */
+	kb_modifier_t modifiers;
+	/** Array of currently pressed keys. */
+	kb_key_code_t pressed_keys[KB_MAX_KEYS_AT_ONCE];
+} kb_status_t;
+
+/** Callback type for status change. */
+typedef void (*kb_on_status_change)(kb_status_t *);
+
+
+void kb_init(kb_status_t *);
+void kb_change_modifier(kb_status_t *, kb_key_action_t, kb_modifier_t);
+void kb_change_key(kb_status_t *, kb_key_action_t, kb_key_code_t);
+
+/** Keyboard event.
+ * Use macros M_DOWN, M_UP, K_DOWN, K_UP, K_PRESS to generate list
+ * of them.
+ */
+typedef struct {
+	/** Key action. */
+	kb_key_action_t action;
+	/** Switch whether action is about modifier or normal key. */
+	bool normal_key;
+	/** Modifier change. */
+	kb_modifier_t modifier_change;
+	/** Normal key change. */
+	kb_key_code_t key_change;
+} kb_event_t;
+
+#define M_DOWN(mod) \
+	{ KB_KEY_DOWN, false, (mod), 0 }
+#define M_UP(mod) \
+	{ KB_KEY_UP, false, (mod), 0 }
+#define K_DOWN(key) \
+	{ KB_KEY_DOWN, true, 0, (key) }
+#define K_UP(key) \
+	{ KB_KEY_UP, true, 0, (key) }
+#define K_PRESS(key) \
+	K_DOWN(key), K_UP(key)
+
+
+void kb_process_events(kb_status_t *, kb_event_t *, size_t, kb_on_status_change);
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/app/virtusbkbd/report.h
===================================================================
--- uspace/app/virtusbkbd/report.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/report.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,85 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief HID Report Descriptor.
+ */
+#ifndef VUK_REPORT_H_
+#define VUK_REPORT_H_
+
+#include "items.h"
+
+/** Use standard Usage Page. */
+#define STD_USAGE_PAGE(page) \
+	ITEM_CREATE1(ITEM_GLOBAL, TAG_USAGE_PAGE, page)
+
+/** Usage with one byte usage ID. */
+#define USAGE1(usage_id) \
+	ITEM_CREATE1(ITEM_LOCAL, TAG_USAGE, usage_id)
+
+/** Start a collection. */
+#define START_COLLECTION(collection) \
+	ITEM_CREATE1(ITEM_MAIN, TAG_COLLECTION, collection)
+
+/** End a collection. */
+#define END_COLLECTION() \
+	ITEM_CREATE0(ITEM_MAIN, TAG_END_COLLECTION)
+
+
+#define USAGE_MINIMUM1(value) \
+	ITEM_CREATE1(ITEM_LOCAL, TAG_USAGE_MINIMUM, value)
+	
+#define USAGE_MAXIMUM1(value) \
+	ITEM_CREATE1(ITEM_LOCAL, TAG_USAGE_MAXIMUM, value)
+	
+#define LOGICAL_MINIMUM1(value) \
+	ITEM_CREATE1(ITEM_GLOBAL, TAG_LOGICAL_MINIMUM, value)
+
+#define LOGICAL_MAXIMUM1(value) \
+	ITEM_CREATE1(ITEM_GLOBAL, TAG_LOGICAL_MAXIMUM, value)
+
+#define REPORT_SIZE1(size) \
+	ITEM_CREATE1(ITEM_GLOBAL, TAG_REPORT_SIZE, size)
+
+#define REPORT_COUNT1(count) \
+	ITEM_CREATE1(ITEM_GLOBAL, TAG_REPORT_COUNT, count)
+	
+#define INPUT(modifiers) \
+	ITEM_CREATE1(ITEM_MAIN, TAG_INPUT, modifiers)
+
+#define OUTPUT(modifiers) \
+	ITEM_CREATE1(ITEM_MAIN, TAG_OUTPUT, modifiers)
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/app/virtusbkbd/stdreq.c
===================================================================
--- uspace/app/virtusbkbd/stdreq.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/stdreq.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,80 @@
+/*
+ * 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 usb
+ * @{
+ */
+/**
+ * @file
+ * @brief Keyboard configuration.
+ */
+#include <errno.h>
+#include <usb/descriptor.h>
+#include "stdreq.h"
+#include "kbdconfig.h"
+
+static int on_get_descriptor(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data);
+
+usbvirt_standard_device_request_ops_t standard_request_ops = {
+	.on_get_status = NULL,
+	.on_clear_feature = NULL,
+	.on_set_feature = NULL,
+	.on_set_address = NULL,
+	.on_get_descriptor = on_get_descriptor,
+	.on_set_descriptor = NULL,
+	.on_get_configuration = NULL,
+	.on_set_configuration = NULL,
+	.on_get_interface = NULL,
+	.on_set_interface = NULL,
+	.on_synch_frame = NULL
+};
+
+
+static int on_get_descriptor(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data)
+{
+	if (request->value_high == USB_DESCTYPE_HID_REPORT) {
+		/*
+		 * For simplicity, always return the same
+		 * report descriptor.
+		 */
+		int rc = dev->control_transfer_reply(dev, 0,
+		    report_descriptor, report_descriptor_size);
+		
+		return rc;
+	}
+	
+	/* Let the framework handle all the rest. */
+	return EFORWARD;
+}
+
+
+
+/** @}
+ */
Index: uspace/app/virtusbkbd/stdreq.h
===================================================================
--- uspace/app/virtusbkbd/stdreq.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/stdreq.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,45 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Standard device request handlers.
+ */
+#ifndef VUK_STDREQ_H_
+#define VUK_STDREQ_H_
+
+#include <usbvirt/device.h>
+
+extern usbvirt_standard_device_request_ops_t standard_request_ops;
+
+#endif
+/**
+ * @}
+ */
Index: uspace/app/virtusbkbd/virtusbkbd.c
===================================================================
--- uspace/app/virtusbkbd/virtusbkbd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/app/virtusbkbd/virtusbkbd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,237 @@
+/*
+ * 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 usb
+ * @{
+ */
+/**
+ * @file
+ * @brief Virtual USB keyboard.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <vfs/vfs.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <str_error.h>
+#include <bool.h>
+#include <async.h>
+
+#include <usb/usb.h>
+#include <usb/descriptor.h>
+#include <usb/classes/hid.h>
+#include <usbvirt/device.h>
+#include <usbvirt/hub.h>
+
+#include "kbdconfig.h"
+#include "keys.h"
+#include "stdreq.h"
+
+#define LOOPS 5
+#define NAME "virt-usb-kbd"
+
+
+#define __QUOTEME(x) #x
+#define _QUOTEME(x) __QUOTEME(x)
+
+#define VERBOSE_EXEC(cmd, fmt, ...) \
+	(printf("%s: %s" fmt "\n", NAME, _QUOTEME(cmd), __VA_ARGS__), cmd(__VA_ARGS__))
+
+kb_status_t status;
+
+static int on_incoming_data(struct usbvirt_device *dev,
+    usb_endpoint_t endpoint, void *buffer, size_t size)
+{
+	printf("%s: ignoring incomming data to endpoint %d\n", NAME, endpoint);
+	
+	return EOK;
+}
+
+static int on_class_request(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data)
+{	
+	printf("%s: class request (%d)\n", NAME, (int) request->request);
+	
+	return EOK;
+}
+
+static int on_request_for_data(struct usbvirt_device *dev,
+    usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size)
+{
+	if (size < 2 + KB_MAX_KEYS_AT_ONCE) {
+		return EINVAL;
+	}
+	
+	*actual_size = 2 + KB_MAX_KEYS_AT_ONCE;
+	
+	uint8_t data[2 + KB_MAX_KEYS_AT_ONCE];
+	data[0] = status.modifiers;
+	data[1] = 0;
+	
+	size_t i;
+	for (i = 0; i < KB_MAX_KEYS_AT_ONCE; i++) {
+		data[2 + i] = status.pressed_keys[i];
+	}
+	
+	memcpy(buffer, &data, *actual_size);
+	
+	return EOK;
+}
+
+
+/** Keyboard callbacks.
+ * We abuse the fact that static variables are zero-filled.
+ */
+static usbvirt_device_ops_t keyboard_ops = {
+	.standard_request_ops = &standard_request_ops,
+	.on_class_device_request = on_class_request,
+	.on_data = on_incoming_data,
+	.on_data_request = on_request_for_data
+};
+
+usbvirt_device_configuration_extras_t extra_descriptors[] = {
+	{
+		.data = (uint8_t *) &std_interface_descriptor,
+		.length = sizeof(std_interface_descriptor)
+	},
+	{
+		.data = (uint8_t *) &hid_descriptor,
+		.length = sizeof(hid_descriptor)
+	},
+	{
+		.data = (uint8_t *) &endpoint_descriptor,
+		.length = sizeof(endpoint_descriptor)
+	}
+};
+
+/** Keyboard configuration. */
+usbvirt_device_configuration_t configuration = {
+	.descriptor = &std_configuration_descriptor,
+	.extra = extra_descriptors,
+	.extra_count = sizeof(extra_descriptors)/sizeof(extra_descriptors[0])
+};
+
+/** Keyboard standard descriptors. */
+usbvirt_descriptors_t descriptors = {
+	.device = &std_device_descriptor,
+	.configuration = &configuration,
+	.configuration_count = 1,
+};
+
+/** Keyboard device.
+ * Rest of the items will be initialized later.
+ */
+static usbvirt_device_t keyboard_dev = {
+	.ops = &keyboard_ops,
+	.descriptors = &descriptors,
+	.name = "keyboard"
+};
+
+
+static void fibril_sleep(size_t sec)
+{
+	while (sec-- > 0) {
+		async_usleep(1000*1000);
+	}
+}
+
+
+/** Callback when keyboard status changed.
+ *
+ * @param status Current keyboard status.
+ */
+static void on_keyboard_change(kb_status_t *status)
+{
+	printf("%s: Current keyboard status: %02hhx", NAME, status->modifiers);
+	size_t i;
+	for (i = 0; i < KB_MAX_KEYS_AT_ONCE; i++) {
+		printf(" 0x%02X", (int)status->pressed_keys[i]);
+	}
+	printf("\n");
+	
+	fibril_sleep(1);
+}
+
+/** Simulated keyboard events. */
+static kb_event_t keyboard_events[] = {
+	/* Switch to VT6 (Alt+F6) */
+	M_DOWN(KB_MOD_LEFT_ALT),
+	K_PRESS(KB_KEY_F6),
+	M_UP(KB_MOD_LEFT_ALT),
+	/* Type the word 'Hello' */
+	M_DOWN(KB_MOD_LEFT_SHIFT),
+	K_PRESS(KB_KEY_H),
+	M_UP(KB_MOD_LEFT_SHIFT),
+	K_PRESS(KB_KEY_E),
+	K_PRESS(KB_KEY_L),
+	K_PRESS(KB_KEY_L),
+	K_PRESS(KB_KEY_O)
+};
+static size_t keyboard_events_count =
+    sizeof(keyboard_events)/sizeof(keyboard_events[0]);
+
+
+
+int main(int argc, char * argv[])
+{
+	printf("Dump of report descriptor (%u bytes):\n", report_descriptor_size);
+	size_t i;
+	for (i = 0; i < report_descriptor_size; i++) {
+		printf("  0x%02X", report_descriptor[i]);
+		if (((i > 0) && (((i+1) % 10) == 0))
+		    || (i + 1 == report_descriptor_size)) {
+			printf("\n");
+		}
+	}
+	
+	kb_init(&status);
+	
+	
+	int rc = usbvirt_connect(&keyboard_dev);
+	if (rc != EOK) {
+		printf("%s: Unable to start communication with VHCD (%s).\n",
+		    NAME, str_error(rc));
+		return rc;
+	}
+	
+	printf("%s: Simulating keyboard events...\n", NAME);
+	kb_process_events(&status, keyboard_events, keyboard_events_count,
+	    on_keyboard_change);
+	
+	printf("%s: Terminating...\n", NAME);
+	
+	usbvirt_disconnect(&keyboard_dev);
+	
+	return 0;
+}
+
+
+/** @}
+ */
Index: uspace/doc/doxygroups.h
===================================================================
--- uspace/doc/doxygroups.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/doc/doxygroups.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -155,5 +155,5 @@
 	 * @endcond
 	 */
-	
+
 /**
  * @defgroup emul Emulation Libraries
@@ -170,2 +170,13 @@
 	 * @ingroup emul
 	 */
+
+/**
+ * @defgroup usb USB
+ * @ingroup uspace
+ * @brief USB support for HelenOS.
+ */
+	/**
+	 * @defgroup libusb USB library
+	 * @ingroup usb
+	 * @brief Library for creating USB devices drivers.
+	 */
Index: uspace/drv/isa/isa.c
===================================================================
--- uspace/drv/isa/isa.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/drv/isa/isa.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -493,6 +493,5 @@
 	/* Add child devices. */
 	add_legacy_children(dev);
-	printf(NAME ": finished the enumeration of legacy devices\n",
-	    dev->handle);
+	printf(NAME ": finished the enumeration of legacy devices\n");
 
 	return EOK;
Index: uspace/drv/ns8250/ns8250.c
===================================================================
--- uspace/drv/ns8250/ns8250.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/drv/ns8250/ns8250.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -276,5 +276,5 @@
 	if (pio_enable((void *) data->io_addr, REG_COUNT,
 	    (void **) &data->port)) {
-		printf(NAME ": error - cannot gain the port %lx for device "
+		printf(NAME ": error - cannot gain the port %#" PRIx32 " for device "
 		    "%s.\n", data->io_addr, dev->name);
 		return false;
Index: uspace/drv/pciintel/pci.c
===================================================================
--- uspace/drv/pciintel/pci.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/drv/pciintel/pci.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -323,5 +323,5 @@
 	if (range_addr != 0) {
 		printf(NAME ": device %s : ", dev->name);
-		printf("address = %x", range_addr);
+		printf("address = %" PRIx64, range_addr);
 		printf(", size = %x\n", range_size);
 	}
@@ -479,5 +479,5 @@
 	}	
 	
-	printf(NAME ": conf_addr = %x.\n",
+	printf(NAME ": conf_addr = %" PRIx64 ".\n",
 	    hw_resources.resources[0].res.io_range.address);
 	
Index: uspace/drv/root/root.c
===================================================================
--- uspace/drv/root/root.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/drv/root/root.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -45,4 +45,5 @@
 #include <ctype.h>
 #include <macros.h>
+#include <inttypes.h>
 
 #include <driver.h>
@@ -119,4 +120,58 @@
 }
 
+/** Create virtual USB host controller device.
+ * Note that the virtual HC is actually device and driver in one
+ * task.
+ *
+ * @param parent Parent device.
+ * @return Error code.
+ */
+static int add_virtual_usb_host_controller(device_t *parent)
+{
+	printf(NAME ": adding virtual host contoller.\n");
+
+	int rc;
+	device_t *vhc = NULL;
+	match_id_t *match_id = NULL;
+
+	vhc = create_device();
+	if (vhc == NULL) {
+		rc = ENOMEM;
+		goto failure;
+	}
+
+	vhc->name = "vhc";
+	printf(NAME ": the new device's name is %s.\n", vhc->name);
+
+	/* Initialize match id list. */
+	match_id = create_match_id();
+	if (match_id == NULL) {
+		rc = ENOMEM;
+		goto failure;
+	}
+
+	match_id->id = "usb&hc=vhc";
+	match_id->score = 100;
+	add_match_id(&vhc->match_ids, match_id);
+
+	/* Register child device. */
+	rc = child_device_register(vhc, parent);
+	if (rc != EOK)
+		goto failure;
+
+	return EOK;
+
+failure:
+	if (match_id != NULL)
+		match_id->id = NULL;
+
+	if (vhc != NULL) {
+		vhc->name = NULL;
+		delete_device(vhc);
+	}
+
+	return rc;
+}
+
 /** Get the root device.
  *
@@ -126,5 +181,6 @@
 static int root_add_device(device_t *dev)
 {
-	printf(NAME ": root_add_device, device handle = %d\n", dev->handle);
+	printf(NAME ": root_add_device, device handle=%" PRIun "\n",
+	    dev->handle);
 	
 	/* Register root device's children. */
@@ -133,4 +189,10 @@
 		printf(NAME ": failed to add child device for platform.\n");
 	
+	/* Register virtual USB host controller. */
+	int rc = add_virtual_usb_host_controller(dev);
+	if (EOK != rc) {
+		printf(NAME ": failed to add child device - virtual USB HC.\n");
+	}
+
 	return res;
 }
Index: uspace/drv/uhci/Makefile
===================================================================
--- uspace/drv/uhci/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/uhci/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
+BINARY = uhci
+
+SOURCES = \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/uhci/main.c
===================================================================
--- uspace/drv/uhci/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/uhci/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+#include <usb/hcdhubd.h>
+#include <errno.h>
+
+static int enqueue_transfer_out(usb_hc_device_t *hc,
+    usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
+    void *buffer, size_t size,
+    usb_hcd_transfer_callback_out_t callback, void *arg)
+{
+	printf("UHCI: transfer OUT [%d.%d (%s); %u]\n",
+	    dev->address, endpoint->endpoint,
+	    usb_str_transfer_type(endpoint->transfer_type),
+	    size);
+	return ENOTSUP;
+}
+
+static int enqueue_transfer_setup(usb_hc_device_t *hc,
+    usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
+    void *buffer, size_t size,
+    usb_hcd_transfer_callback_out_t callback, void *arg)
+{
+	printf("UHCI: transfer SETUP [%d.%d (%s); %u]\n",
+	    dev->address, endpoint->endpoint,
+	    usb_str_transfer_type(endpoint->transfer_type),
+	    size);
+	return ENOTSUP;
+}
+
+static int enqueue_transfer_in(usb_hc_device_t *hc,
+    usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
+    void *buffer, size_t size,
+    usb_hcd_transfer_callback_in_t callback, void *arg)
+{
+	printf("UHCI: transfer IN [%d.%d (%s); %u]\n",
+	    dev->address, endpoint->endpoint,
+	    usb_str_transfer_type(endpoint->transfer_type),
+	    size);
+	return ENOTSUP;
+}
+
+static usb_hcd_transfer_ops_t uhci_transfer_ops = {
+	.transfer_out = enqueue_transfer_out,
+	.transfer_in = enqueue_transfer_in,
+	.transfer_setup = enqueue_transfer_setup
+};
+
+static int uhci_add_hc(usb_hc_device_t *device)
+{
+	device->transfer_ops = &uhci_transfer_ops;
+
+	/*
+	 * We need to announce the presence of our root hub.
+	 * Commented out until the problem which causes the whole task to
+	 * block is solved.
+	 */
+	//usb_hcd_add_root_hub(device);
+
+	return EOK;
+}
+
+usb_hc_driver_t uhci_driver = {
+	.name = "uhci",
+	.add_hc = uhci_add_hc
+};
+
+int main(int argc, char *argv[])
+{
+	/*
+	 * Do some global initializations.
+	 */
+
+	return usb_hcd_main(&uhci_driver);
+}
Index: uspace/drv/uhci/uhci.ma
===================================================================
--- uspace/drv/uhci/uhci.ma	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/uhci/uhci.ma	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,3 @@
+10 pci/ven=8086&dev=7020
+10 usb&hc=uhci
+10 usb&hc=uhci&hub
Index: uspace/drv/usbkbd/Makefile
===================================================================
--- uspace/drv/usbkbd/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/usbkbd/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
+BINARY = usbkbd
+
+SOURCES = \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/usbkbd/main.c
===================================================================
--- uspace/drv/usbkbd/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/usbkbd/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+#include <usb/usbdrv.h>
+#include <driver.h>
+#include <errno.h>
+
+#define BUFFER_SIZE 32
+
+/* Call this periodically to check keyboard status changes. */
+static void poll_keyboard(device_t *dev)
+{
+	int rc;
+	usb_handle_t handle;
+	char buffer[BUFFER_SIZE];
+	size_t actual_size;
+	usb_endpoint_t poll_endpoint = 1;
+
+	usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
+	    dev);
+	if (my_address < 0) {
+		return;
+	}
+
+	usb_target_t poll_target = {
+		.address = my_address,
+		.endpoint = poll_endpoint
+	};
+
+	rc = usb_drv_async_interrupt_in(dev->parent_phone, poll_target,
+	    buffer, BUFFER_SIZE, &actual_size, &handle);
+	if (rc != EOK) {
+		return;
+	}
+
+	rc = usb_drv_async_wait_for(handle);
+	if (rc != EOK) {
+		return;
+	}
+
+	/*
+	 * If the keyboard answered with NAK, it returned no data.
+	 * This implies that no change happened since last query.
+	 */
+	if (actual_size == 0) {
+		return;
+	}
+
+	/*
+	 * Process pressed keys.
+	 */
+}
+
+static int add_kbd_device(device_t *dev)
+{
+	/* For now, fail immediately. */
+	return ENOTSUP;
+
+	/*
+	 * When everything is okay, connect to "our" HC.
+	 */
+	int phone = usb_drv_hc_connect(dev, 0);
+	if (phone < 0) {
+		/*
+		 * Connecting to HC failed, roll-back and announce
+		 * failure.
+		 */
+		return phone;
+	}
+
+	dev->parent_phone = phone;
+
+	/*
+	 * Just for fun ;-).
+	 */
+	poll_keyboard(dev);
+
+	/*
+	 * Hurrah, device is initialized.
+	 */
+	return EOK;
+}
+
+static driver_ops_t kbd_driver_ops = {
+	.add_device = add_kbd_device,
+};
+
+static driver_t kbd_driver = {
+	.name = "usbkbd",
+	.driver_ops = &kbd_driver_ops
+};
+
+int main(int argc, char *argv[])
+{
+	return driver_main(&kbd_driver);
+}
Index: uspace/drv/usbkbd/usbkbd.ma
===================================================================
--- uspace/drv/usbkbd/usbkbd.ma	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/usbkbd/usbkbd.ma	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,1 @@
+10 usb&class=hid
Index: uspace/drv/vhc/Makefile
===================================================================
--- uspace/drv/vhc/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,50 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBUSBVIRT_PREFIX)/libusbvirt.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIB_PREFIX) \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+BINARY = vhc
+
+SOURCES = \
+	conndev.c \
+	connhost.c \
+	debug.c \
+	devices.c \
+	hc.c \
+	hcd.c \
+	hub.c \
+	hubops.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/vhc/conn.h
===================================================================
--- uspace/drv/vhc/conn.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/conn.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,53 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Connection handling of incoming calls.
+ */
+#ifndef VHCD_CONN_H_
+#define VHCD_CONN_H_
+
+#include <usb/usb.h>
+#include <usb/hcdhubd.h>
+#include "vhcd.h"
+#include "devices.h"
+
+void connection_handler_host(ipcarg_t);
+
+usb_hcd_transfer_ops_t vhc_transfer_ops;
+
+void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *);
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/vhc/conndev.c
===================================================================
--- uspace/drv/vhc/conndev.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/conndev.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,115 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Connection handling of calls from virtual device (implementation).
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <usbvirt/hub.h>
+
+#include "conn.h"
+#include "hc.h"
+#include "hub.h"
+
+#define DEVICE_NAME_MAXLENGTH 32
+
+static int get_device_name(int phone, char *buffer, size_t len)
+{
+	ipc_call_t answer_data;
+	ipcarg_t answer_rc;
+	aid_t req;
+	int rc;
+	
+	req = async_send_0(phone,
+	    IPC_M_USBVIRT_GET_NAME,
+	    &answer_data);
+	
+	rc = async_data_read_start(phone, buffer, len);
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return EINVAL;
+	}
+	
+	async_wait_for(req, &answer_rc);
+	rc = (int)answer_rc;
+	
+	if (IPC_GET_ARG1(answer_data) < len) {
+		len = IPC_GET_ARG1(answer_data);
+	} else {
+		len--;
+	}
+	buffer[len] = 0;
+	
+	return rc;
+}
+
+/** Default handler for IPC methods not handled by DDF.
+ *
+ * @param dev Device handling the call.
+ * @param icallid Call id.
+ * @param icall Call data.
+ */
+void default_connection_handler(device_t *dev,
+    ipc_callid_t icallid, ipc_call_t *icall)
+{
+	ipcarg_t method = IPC_GET_METHOD(*icall);
+
+	if (method == IPC_M_CONNECT_TO_ME) {
+		int callback = IPC_GET_ARG5(*icall);
+		virtdev_connection_t *dev
+		    = virtdev_add_device(callback);
+		if (!dev) {
+			ipc_answer_0(icallid, EEXISTS);
+			ipc_hangup(callback);
+			return;
+		}
+		ipc_answer_0(icallid, EOK);
+
+		char devname[DEVICE_NAME_MAXLENGTH + 1];
+		int rc = get_device_name(callback, devname, DEVICE_NAME_MAXLENGTH);
+
+		dprintf(0, "virtual device connected (name: %s)",
+		    rc == EOK ? devname : "<unknown>");
+
+		/* FIXME: destroy the device when the client disconnects. */
+
+		return;
+	}
+
+	ipc_answer_0(icallid, EINVAL);
+}
+
+
+/**
+ * @}
+ */
Index: uspace/drv/vhc/connhost.c
===================================================================
--- uspace/drv/vhc/connhost.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/connhost.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,173 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Connection handling of calls from host (implementation).
+ */
+#include <assert.h>
+#include <errno.h>
+#include <usb/usb.h>
+
+#include "vhcd.h"
+#include "conn.h"
+#include "hc.h"
+
+typedef struct {
+	usb_direction_t direction;
+	usb_hcd_transfer_callback_out_t out_callback;
+	usb_hcd_transfer_callback_in_t in_callback;
+	usb_hc_device_t *hc;
+	void *arg;
+} transfer_info_t;
+
+static void universal_callback(void *buffer, size_t size,
+    usb_transaction_outcome_t outcome, void *arg)
+{
+	transfer_info_t *transfer = (transfer_info_t *) arg;
+
+	switch (transfer->direction) {
+		case USB_DIRECTION_IN:
+			transfer->in_callback(transfer->hc,
+			    size, outcome,
+			    transfer->arg);
+			break;
+		case USB_DIRECTION_OUT:
+			transfer->out_callback(transfer->hc,
+			    outcome,
+			    transfer->arg);
+			break;
+		default:
+			assert(false && "unreachable");
+			break;
+	}
+
+	free(transfer);
+}
+
+static transfer_info_t *create_transfer_info(usb_hc_device_t *hc,
+    usb_direction_t direction, void *arg)
+{
+	transfer_info_t *transfer = malloc(sizeof(transfer_info_t));
+
+	transfer->direction = direction;
+	transfer->in_callback = NULL;
+	transfer->out_callback = NULL;
+	transfer->arg = arg;
+	transfer->hc = hc;
+
+	return transfer;
+}
+
+static int enqueue_transfer_out(usb_hc_device_t *hc,
+    usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
+    void *buffer, size_t size,
+    usb_hcd_transfer_callback_out_t callback, void *arg)
+{
+	printf(NAME ": transfer OUT [%d.%d (%s); %u]\n",
+	    dev->address, endpoint->endpoint,
+	    usb_str_transfer_type(endpoint->transfer_type),
+	    size);
+
+	transfer_info_t *transfer
+	    = create_transfer_info(hc, USB_DIRECTION_OUT, arg);
+	transfer->out_callback = callback;
+
+	usb_target_t target = {
+		.address = dev->address,
+		.endpoint = endpoint->endpoint
+	};
+
+	hc_add_transaction_to_device(false, target, buffer, size,
+	    universal_callback, transfer);
+
+	return EOK;
+}
+
+static int enqueue_transfer_setup(usb_hc_device_t *hc,
+    usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
+    void *buffer, size_t size,
+    usb_hcd_transfer_callback_out_t callback, void *arg)
+{
+	printf(NAME ": transfer SETUP [%d.%d (%s); %u]\n",
+	    dev->address, endpoint->endpoint,
+	    usb_str_transfer_type(endpoint->transfer_type),
+	    size);
+
+	transfer_info_t *transfer
+	    = create_transfer_info(hc, USB_DIRECTION_OUT, arg);
+	transfer->out_callback = callback;
+
+	usb_target_t target = {
+		.address = dev->address,
+		.endpoint = endpoint->endpoint
+	};
+
+	hc_add_transaction_to_device(true, target, buffer, size,
+	    universal_callback, transfer);
+
+	return EOK;
+}
+
+static int enqueue_transfer_in(usb_hc_device_t *hc,
+    usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
+    void *buffer, size_t size,
+    usb_hcd_transfer_callback_in_t callback, void *arg)
+{
+	printf(NAME ": transfer IN [%d.%d (%s); %u]\n",
+	    dev->address, endpoint->endpoint,
+	    usb_str_transfer_type(endpoint->transfer_type),
+	    size);
+
+	transfer_info_t *transfer
+	    = create_transfer_info(hc, USB_DIRECTION_IN, arg);
+	transfer->in_callback = callback;
+
+	usb_target_t target = {
+		.address = dev->address,
+		.endpoint = endpoint->endpoint
+	};
+
+	hc_add_transaction_from_device(target, buffer, size,
+	    universal_callback, transfer);
+
+	return EOK;
+}
+
+
+usb_hcd_transfer_ops_t vhc_transfer_ops = {
+	.transfer_out = enqueue_transfer_out,
+	.transfer_in = enqueue_transfer_in,
+	.transfer_setup = enqueue_transfer_setup
+};
+
+/**
+ * @}
+ */
Index: uspace/drv/vhc/debug.c
===================================================================
--- uspace/drv/vhc/debug.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/debug.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,78 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Debugging support.
+ */
+#include <stdio.h>
+#include <ipc/ipc.h>
+
+#include "vhcd.h"
+
+/** Current debug level. */
+int debug_level = 0;
+
+/** Debugging printf.
+ * This function is intended for single-line messages as it
+ * automatically prints debugging prefix at the beginning of the
+ * line.
+ *
+ * @see printf
+ * @param level Debugging level.
+ */
+void dprintf(int level, const char *format, ...)
+{
+	if (level > debug_level) {
+		return;
+	}
+	
+	printf("%s(%d): ", NAME, level);
+	va_list args;
+	va_start(args, format);
+	vprintf(format, args);
+	va_end(args);
+	printf("\n");
+}
+
+/** Debug print informing of invalid call.
+ */
+void dprintf_inval_call(int level, ipc_call_t call, ipcarg_t phone_hash)
+{
+	dprintf(level, "phone%#x: invalid call [%u (%u, %u, %u, %u, %u)]",
+	    phone_hash,
+	    IPC_GET_METHOD(call),
+	    IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call),
+	    IPC_GET_ARG4(call), IPC_GET_ARG5(call));
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/vhc/devices.c
===================================================================
--- uspace/drv/vhc/devices.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/devices.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,186 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual device management (implementation).
+ */
+
+#include <ipc/ipc.h>
+#include <adt/list.h>
+#include <bool.h>
+#include <async.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usbvirt/hub.h>
+
+#include "devices.h"
+#include "hub.h"
+#include "vhcd.h"
+
+#define list_foreach(pos, head) \
+	for (pos = (head)->next; pos != (head); \
+        	pos = pos->next)
+
+static LIST_INITIALIZE(devices);
+
+/** Create virtual device.
+ *
+ * @param address USB address.
+ * @param phone Callback phone.
+ * @return New device.
+ * @retval NULL Out of memory or address already occupied.
+ */
+virtdev_connection_t *virtdev_add_device(int phone)
+{
+	virtdev_connection_t *dev = (virtdev_connection_t *)
+	    malloc(sizeof(virtdev_connection_t));
+	dev->phone = phone;
+	list_append(&dev->link, &devices);
+	
+	hub_add_device(dev);
+	
+	return dev;
+}
+
+/** Destroy virtual device.
+ */
+void virtdev_destroy_device(virtdev_connection_t *dev)
+{
+	hub_remove_device(dev);
+	list_remove(&dev->link);
+	free(dev);
+}
+
+/** Send data to all connected devices.
+ *
+ * @param transaction Transaction to be sent over the bus.
+ */
+usb_transaction_outcome_t virtdev_send_to_all(transaction_t *transaction)
+{
+	link_t *pos;
+	list_foreach(pos, &devices) {
+		virtdev_connection_t *dev
+		    = list_get_instance(pos, virtdev_connection_t, link);
+		
+		if (!hub_can_device_signal(dev)) {
+			continue;
+		}
+		
+		ipc_call_t answer_data;
+		ipcarg_t answer_rc;
+		aid_t req;
+		int rc = EOK;
+		int method = IPC_M_USBVIRT_TRANSACTION_SETUP;
+		
+		switch (transaction->type) {
+			case USBVIRT_TRANSACTION_SETUP:
+				method = IPC_M_USBVIRT_TRANSACTION_SETUP;
+				break;
+			case USBVIRT_TRANSACTION_IN:
+				method = IPC_M_USBVIRT_TRANSACTION_IN;
+				break;
+			case USBVIRT_TRANSACTION_OUT:
+				method = IPC_M_USBVIRT_TRANSACTION_OUT;
+				break;
+		}
+		
+		req = async_send_3(dev->phone,
+		    method,
+		    transaction->target.address,
+		    transaction->target.endpoint,
+		    transaction->len,
+		    &answer_data);
+		
+		if (transaction->len > 0) {
+			if (transaction->type == USBVIRT_TRANSACTION_IN) {
+				rc = async_data_read_start(dev->phone,
+				    transaction->buffer, transaction->len);
+			} else {
+				rc = async_data_write_start(dev->phone,
+				    transaction->buffer, transaction->len);
+			}
+		}
+		
+		if (rc != EOK) {
+			async_wait_for(req, NULL);
+		} else {
+			async_wait_for(req, &answer_rc);
+			rc = (int)answer_rc;
+		}
+	}
+	
+	/*
+	 * Send the data to the virtual hub as well
+	 * (if the address matches).
+	 */
+	if (virthub_dev.address == transaction->target.address) {
+		size_t tmp;
+		dprintf(3, "sending `%s' transaction to hub",
+		    usbvirt_str_transaction_type(transaction->type));
+		switch (transaction->type) {
+			case USBVIRT_TRANSACTION_SETUP:
+				virthub_dev.transaction_setup(&virthub_dev,
+				    transaction->target.endpoint,
+				    transaction->buffer, transaction->len);
+				break;
+				
+			case USBVIRT_TRANSACTION_IN:
+				virthub_dev.transaction_in(&virthub_dev,
+				    transaction->target.endpoint,
+				    transaction->buffer, transaction->len,
+				    &tmp);
+				if (tmp < transaction->len) {
+					transaction->len = tmp;
+				}
+				break;
+				
+			case USBVIRT_TRANSACTION_OUT:
+				virthub_dev.transaction_out(&virthub_dev,
+				    transaction->target.endpoint,
+				    transaction->buffer, transaction->len);
+				break;
+		}
+		dprintf(4, "transaction on hub processed...");
+	}
+	
+	/*
+	 * TODO: maybe screw some transactions to get more
+	 * real-life image.
+	 */
+	return USB_OUTCOME_OK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/vhc/devices.h
===================================================================
--- uspace/drv/vhc/devices.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/devices.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,59 @@
+/*
+ * 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 usb
+ * @{
+ */ 
+/** @file
+ * @brief Virtual device management.
+ */
+#ifndef VHCD_DEVICES_H_
+#define VHCD_DEVICES_H_
+
+#include <adt/list.h>
+#include <usb/usb.h>
+
+#include "hc.h"
+
+/** Connected virtual device. */
+typedef struct {
+	/** Phone used when sending data to device. */
+	int phone;
+	/** Linked-list handle. */
+	link_t link;
+} virtdev_connection_t;
+
+virtdev_connection_t *virtdev_add_device(int);
+virtdev_connection_t *virtdev_get_mine(void);
+void virtdev_destroy_device(virtdev_connection_t *);
+usb_transaction_outcome_t virtdev_send_to_all(transaction_t *);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/vhc/hc.c
===================================================================
--- uspace/drv/vhc/hc.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/hc.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,186 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual HC (implementation).
+ */
+
+#include <ipc/ipc.h>
+#include <adt/list.h>
+#include <bool.h>
+#include <async.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usbvirt/hub.h>
+
+#include "vhcd.h"
+#include "hc.h"
+#include "devices.h"
+#include "hub.h"
+
+#define USLEEP_BASE (500 * 1000)
+
+#define USLEEP_VAR 5000
+
+#define SHORTENING_VAR 15
+
+#define PROB_OUTCOME_BABBLE 5
+#define PROB_OUTCOME_CRCERROR 7
+
+#define PROB_TEST(var, new_value, prob, number) \
+	do { \
+		if (((number) % (prob)) == 0) { \
+			var = (new_value); \
+		} \
+	} while (0)
+
+static link_t transaction_list;
+
+#define TRANSACTION_FORMAT "T[%d:%d %s (%d)]"
+#define TRANSACTION_PRINTF(t) \
+	(t).target.address, (t).target.endpoint, \
+	usbvirt_str_transaction_type((t).type), \
+	(int)(t).len
+
+#define transaction_get_instance(lnk) \
+	list_get_instance(lnk, transaction_t, link)
+
+static inline unsigned int pseudo_random(unsigned int *seed)
+{
+	*seed = ((*seed) * 873511) % 22348977 + 7;
+	return ((*seed) >> 8);
+}
+
+/** Call transaction callback.
+ * Calling this callback informs the backend that transaction was processed.
+ */
+static void process_transaction_with_outcome(transaction_t * transaction,
+    usb_transaction_outcome_t outcome)
+{
+	dprintf(3, "processing transaction " TRANSACTION_FORMAT ", outcome: %s",
+	    TRANSACTION_PRINTF(*transaction),
+	    usb_str_transaction_outcome(outcome));
+	
+	transaction->callback(transaction->buffer, transaction->len, outcome,
+	    transaction->callback_arg);
+}
+
+/** Host controller manager main function.
+ */
+void hc_manager(void)
+{
+	list_initialize(&transaction_list);
+	
+	static unsigned int seed = 4573;
+	
+	printf("%s: transaction processor ready.\n", NAME);
+	
+	while (true) {
+		async_usleep(USLEEP_BASE + (pseudo_random(&seed) % USLEEP_VAR));
+		
+		if (list_empty(&transaction_list)) {
+			continue;
+		}
+		
+		char ports[HUB_PORT_COUNT + 2];
+		hub_get_port_statuses(ports, HUB_PORT_COUNT + 1);
+		dprintf(3, "virtual hub: addr=%d ports=%s",
+		    virthub_dev.address, ports);
+		
+		link_t *first_transaction_link = transaction_list.next;
+		transaction_t *transaction
+		    = transaction_get_instance(first_transaction_link);
+		list_remove(first_transaction_link);
+		
+		dprintf(3, "processing transaction " TRANSACTION_FORMAT "",
+		    TRANSACTION_PRINTF(*transaction));
+		
+		usb_transaction_outcome_t outcome;
+		outcome = virtdev_send_to_all(transaction);
+		
+		process_transaction_with_outcome(transaction, outcome);
+
+		free(transaction);
+	}
+}
+
+/** Create new transaction
+ */
+static transaction_t *transaction_create(usbvirt_transaction_type_t type,
+    usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg)
+{
+	transaction_t * transaction = malloc(sizeof(transaction_t));
+	
+	list_initialize(&transaction->link);
+	transaction->type = type;
+	transaction->target = target;
+	transaction->buffer = buffer;
+	transaction->len = len;
+	transaction->callback = callback;
+	transaction->callback_arg = arg;
+	
+	dprintf(1, "creating transaction " TRANSACTION_FORMAT,
+	    TRANSACTION_PRINTF(*transaction));
+	
+	return transaction;
+}
+
+/** Add transaction directioned towards the device.
+ */
+void hc_add_transaction_to_device(bool setup, usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg)
+{
+	transaction_t *transaction = transaction_create(
+	    setup ? USBVIRT_TRANSACTION_SETUP : USBVIRT_TRANSACTION_OUT, target,
+	    buffer, len, callback, arg);
+	list_append(&transaction->link, &transaction_list);
+}
+
+/** Add transaction directioned from the device.
+ */
+void hc_add_transaction_from_device(usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg)
+{
+	transaction_t *transaction = transaction_create(USBVIRT_TRANSACTION_IN,
+	    target, buffer, len, callback, arg);
+	list_append(&transaction->link, &transaction_list);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/vhc/hc.h
===================================================================
--- uspace/drv/vhc/hc.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/hc.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,85 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual HC.
+ */
+#ifndef VHCD_HC_H_
+#define VHCD_HC_H_
+
+#include <usb/usb.h>
+#include <usbvirt/hub.h>
+
+/** Callback after transaction is sent to USB.
+ *
+ * @param buffer Transaction data buffer.
+ * @param size Transaction data size.
+ * @param outcome Transaction outcome.
+ * @param arg Custom argument.
+ */
+typedef void (*hc_transaction_done_callback_t)(void *buffer, size_t size,
+    usb_transaction_outcome_t outcome, void *arg);
+
+/** Pending transaction details. */
+typedef struct {
+	/** Linked-list link. */
+	link_t link;
+	/** Transaction type. */
+	usbvirt_transaction_type_t type;
+	/** Device address. */
+	usb_target_t target;
+	/** Direction of the transaction. */
+	usb_direction_t direction;
+	/** Transaction data buffer. */
+	void * buffer;
+	/** Transaction data length. */
+	size_t len;
+	/** Callback after transaction is done. */
+	hc_transaction_done_callback_t callback;
+	/** Argument to the callback. */
+	void * callback_arg;
+} transaction_t;
+
+void hc_manager(void);
+
+void hc_add_transaction_to_device(bool setup, usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg);
+
+void hc_add_transaction_from_device(usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg);
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/vhc/hcd.c
===================================================================
--- uspace/drv/vhc/hcd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/hcd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,122 @@
+/*
+ * 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 usb
+ * @{
+ */ 
+/** @file
+ * @brief Virtual host controller driver.
+ */
+
+#include <devmap.h>
+#include <ipc/ipc.h>
+#include <async.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sysinfo.h>
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+#include <driver.h>
+
+#include <usb/usb.h>
+#include "vhcd.h"
+#include "hc.h"
+#include "devices.h"
+#include "hub.h"
+#include "conn.h"
+
+
+static int vhc_count = 0;
+static int vhc_add_device(usb_hc_device_t *dev)
+{
+	/*
+	 * Currently, we know how to simulate only single HC.
+	 */
+	if (vhc_count > 0) {
+		return ELIMIT;
+	}
+
+	vhc_count++;
+
+	dev->transfer_ops = &vhc_transfer_ops;
+	dev->generic->ops->default_handler = default_connection_handler;
+
+	/*
+	 * Initialize our hub and announce its presence.
+	 */
+	hub_init();
+	usb_hcd_add_root_hub(dev);
+
+	printf("%s: virtual USB host controller ready.\n", NAME);
+
+	return EOK;
+}
+
+static usb_hc_driver_t vhc_driver = {
+	.name = NAME,
+	.add_hc = &vhc_add_device
+};
+
+/** Fibril wrapper for HC transaction manager.
+ *
+ * @param arg Not used.
+ * @return Nothing, return argument is unreachable.
+ */
+static int hc_manager_fibril(void *arg)
+{
+	hc_manager();
+	return EOK;
+}
+
+int main(int argc, char * argv[])
+{	
+	printf("%s: virtual USB host controller driver.\n", NAME);
+
+	debug_level = 10;
+
+	fid_t fid = fibril_create(hc_manager_fibril, NULL);
+	if (fid == 0) {
+		printf("%s: failed to start HC manager fibril\n", NAME);
+		return ENOMEM;
+	}
+	fibril_add_ready(fid);
+
+	/*
+	 * Temporary workaround. Wait a little bit to be the last driver
+	 * in devman output.
+	 */
+	sleep(4);
+
+	return usb_hcd_main(&vhc_driver);
+}
+
+
+/**
+ * @}
+ */
Index: uspace/drv/vhc/hub.c
===================================================================
--- uspace/drv/vhc/hub.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/hub.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,256 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual USB hub.
+ */
+#include <usb/classes/classes.h>
+#include <usbvirt/hub.h>
+#include <usbvirt/device.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "vhcd.h"
+#include "hub.h"
+#include "hubintern.h"
+
+
+/** Standard device descriptor. */
+usb_standard_device_descriptor_t std_device_descriptor = {
+	.length = sizeof(usb_standard_device_descriptor_t),
+	.descriptor_type = USB_DESCTYPE_DEVICE,
+	.usb_spec_version = 0x110,
+	.device_class = USB_CLASS_HUB,
+	.device_subclass = 0,
+	.device_protocol = 0,
+	.max_packet_size = 64,
+	.configuration_count = 1
+};
+
+/** Standard interface descriptor. */
+usb_standard_interface_descriptor_t std_interface_descriptor = {
+	.length = sizeof(usb_standard_interface_descriptor_t),
+	.descriptor_type = USB_DESCTYPE_INTERFACE,
+	.interface_number = 0,
+	.alternate_setting = 0,
+	.endpoint_count = 1,
+	.interface_class = USB_CLASS_HUB,
+	.interface_subclass = 0,
+	.interface_protocol = 0,
+	.str_interface = 0
+};
+
+hub_descriptor_t hub_descriptor = {
+	.length = sizeof(hub_descriptor_t),
+	.type = USB_DESCTYPE_HUB,
+	.port_count = HUB_PORT_COUNT,
+	.characteristics = 0, 
+	.power_on_warm_up = 50, /* Huh? */
+	.max_current = 100, /* Huh again. */
+	.removable_device = { 0 },
+	.port_power = { 0xFF }
+};
+
+/** Endpoint descriptor. */
+usb_standard_endpoint_descriptor_t endpoint_descriptor = {
+	.length = sizeof(usb_standard_endpoint_descriptor_t),
+	.descriptor_type = USB_DESCTYPE_ENDPOINT,
+	.endpoint_address = HUB_STATUS_CHANGE_PIPE | 128,
+	.attributes = USB_TRANSFER_INTERRUPT,
+	.max_packet_size = 8,
+	.poll_interval = 0xFF
+};
+
+/** Standard configuration descriptor. */
+usb_standard_configuration_descriptor_t std_configuration_descriptor = {
+	.length = sizeof(usb_standard_configuration_descriptor_t),
+	.descriptor_type = USB_DESCTYPE_CONFIGURATION,
+	.total_length = 
+		sizeof(usb_standard_configuration_descriptor_t)
+		+ sizeof(std_interface_descriptor)
+		+ sizeof(hub_descriptor)
+		+ sizeof(endpoint_descriptor)
+		,
+	.interface_count = 1,
+	.configuration_number = HUB_CONFIGURATION_ID,
+	.str_configuration = 0,
+	.attributes = 128, /* denotes bus-powered device */
+	.max_power = 50
+};
+
+/** All hub configuration descriptors. */
+static usbvirt_device_configuration_extras_t extra_descriptors[] = {
+	{
+		.data = (uint8_t *) &std_interface_descriptor,
+		.length = sizeof(std_interface_descriptor)
+	},
+	{
+		.data = (uint8_t *) &hub_descriptor,
+		.length = sizeof(hub_descriptor)
+	},
+	{
+		.data = (uint8_t *) &endpoint_descriptor,
+		.length = sizeof(endpoint_descriptor)
+	}
+};
+
+/** Hub configuration. */
+usbvirt_device_configuration_t configuration = {
+	.descriptor = &std_configuration_descriptor,
+	.extra = extra_descriptors,
+	.extra_count = sizeof(extra_descriptors)/sizeof(extra_descriptors[0])
+};
+
+/** Hub standard descriptors. */
+usbvirt_descriptors_t descriptors = {
+	.device = &std_device_descriptor,
+	.configuration = &configuration,
+	.configuration_count = 1,
+};
+
+/** Hub as a virtual device. */
+usbvirt_device_t virthub_dev = {
+	.ops = &hub_ops,
+	.descriptors = &descriptors,
+	.lib_debug_level = 4,
+	.lib_debug_enabled_tags = USBVIRT_DEBUGTAG_ALL
+};
+
+/** Hub device. */
+hub_device_t hub_dev;
+
+/** Initialize virtual hub. */
+void hub_init(void)
+{
+	size_t i;
+	for (i = 0; i < HUB_PORT_COUNT; i++) {
+		hub_port_t *port = &hub_dev.ports[i];
+		
+		port->device = NULL;
+		port->state = HUB_PORT_STATE_NOT_CONFIGURED;
+		port->status_change = 0;
+	}
+	
+	usbvirt_connect_local(&virthub_dev);
+	
+	dprintf(1, "virtual hub (%d ports) created", HUB_PORT_COUNT);
+}
+
+/** Connect device to the hub.
+ *
+ * @param device Device to be connected.
+ * @return Port where the device was connected to.
+ */
+size_t hub_add_device(virtdev_connection_t *device)
+{
+	size_t i;
+	for (i = 0; i < HUB_PORT_COUNT; i++) {
+		hub_port_t *port = &hub_dev.ports[i];
+		
+		if (port->device != NULL) {
+			continue;
+		}
+		
+		port->device = device;
+		
+		/*
+		 * TODO:
+		 * If the hub was configured, we can normally
+		 * announce the plug-in.
+		 * Otherwise, we will wait until hub is configured
+		 * and announce changes in single burst.
+		 */
+		//if (port->state == HUB_PORT_STATE_DISCONNECTED) {
+			port->state = HUB_PORT_STATE_DISABLED;
+			set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
+		//}
+		
+		return i;
+	}
+	
+	return (size_t)-1;
+}
+
+/** Disconnect device from the hub. */
+void hub_remove_device(virtdev_connection_t *device)
+{
+	size_t i;
+	for (i = 0; i < HUB_PORT_COUNT; i++) {
+		hub_port_t *port = &hub_dev.ports[i];
+		
+		if (port->device != device) {
+			continue;
+		}
+		
+		port->device = NULL;
+		port->state = HUB_PORT_STATE_DISCONNECTED;
+		
+		set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
+	}
+}
+
+/** Tell whether device port is open.
+ *
+ * @return Whether communication to and from the device can go through the hub.
+ */
+bool hub_can_device_signal(virtdev_connection_t * device)
+{
+	size_t i;
+	for (i = 0; i < HUB_PORT_COUNT; i++) {
+		if (hub_dev.ports[i].device == device) {
+			return hub_dev.ports[i].state == HUB_PORT_STATE_ENABLED;
+		}
+	}
+	
+	return false;
+}
+
+/** Format hub port status.
+ *
+ * @param result Buffer where to store status string.
+ * @param len Number of characters that is possible to store in @p result
+ * 	(excluding trailing zero).
+ */
+void hub_get_port_statuses(char *result, size_t len)
+{
+	if (len > HUB_PORT_COUNT) {
+		len = HUB_PORT_COUNT;
+	}
+	size_t i;
+	for (i = 0; i < len; i++) {
+		result[i] = hub_port_state_as_char(hub_dev.ports[i].state);
+	}
+	result[len] = 0;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/vhc/hub.h
===================================================================
--- uspace/drv/vhc/hub.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/hub.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,58 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual USB hub.
+ */
+#ifndef VHCD_HUB_H_
+#define VHCD_HUB_H_
+
+#include <usbvirt/device.h>
+
+#include "devices.h"
+
+#define HUB_PORT_COUNT 6
+
+#define BITS2BYTES(bits) \
+    (bits ? ((((bits)-1)>>3)+1) : 0)
+
+extern usbvirt_device_t virthub_dev;
+
+void hub_init(void);
+size_t hub_add_device(virtdev_connection_t *);
+void hub_remove_device(virtdev_connection_t *);
+bool hub_can_device_signal(virtdev_connection_t *);
+void hub_get_port_statuses(char *result, size_t len);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/vhc/hubintern.h
===================================================================
--- uspace/drv/vhc/hubintern.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/hubintern.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,145 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief
+ */
+#ifndef VHCD_HUBINTERN_H_
+#define VHCD_HUBINTERN_H_
+
+#include "hub.h"
+
+/** Endpoint number for status change pipe. */
+#define HUB_STATUS_CHANGE_PIPE 1
+/** Configuration value for hub configuration. */
+#define HUB_CONFIGURATION_ID 1
+
+/** Hub descriptor.
+ */
+typedef struct {
+	/** Size of this descriptor in bytes. */
+	uint8_t length;
+	/** Descriptor type (USB_DESCTYPE_HUB). */
+	uint8_t type;
+	/** Number of downstream ports. */
+	uint8_t port_count;
+	/** Hub characteristics. */
+	uint16_t characteristics;
+	/** Time from power-on to stabilized current.
+	 * Expressed in 2ms unit.
+	 */
+	uint8_t power_on_warm_up;
+	/** Maximum current (in mA). */
+	uint8_t max_current;
+	/** Whether device at given port is removable. */
+	uint8_t removable_device[BITS2BYTES(HUB_PORT_COUNT+1)];
+	/** Port power control.
+	 * This is USB1.0 compatibility field, all bits must be 1.
+	 */
+	uint8_t port_power[BITS2BYTES(HUB_PORT_COUNT+1)];
+} __attribute__ ((packed)) hub_descriptor_t;
+
+/** Hub port internal state.
+ * Some states (e.g. port over current) are not covered as they are not
+ * simulated at all.
+ */
+typedef enum {
+	HUB_PORT_STATE_NOT_CONFIGURED,
+	HUB_PORT_STATE_POWERED_OFF,
+	HUB_PORT_STATE_DISCONNECTED,
+	HUB_PORT_STATE_DISABLED,
+	HUB_PORT_STATE_RESETTING,
+	HUB_PORT_STATE_ENABLED,
+	HUB_PORT_STATE_SUSPENDED,
+	HUB_PORT_STATE_RESUMING,
+	/* HUB_PORT_STATE_, */
+} hub_port_state_t;
+
+/** Convert hub port state to a char. */
+static inline char hub_port_state_as_char(hub_port_state_t state) {
+	switch (state) {
+		case HUB_PORT_STATE_NOT_CONFIGURED:
+			return '-';
+		case HUB_PORT_STATE_POWERED_OFF:
+			return 'O';
+		case HUB_PORT_STATE_DISCONNECTED:
+			return 'X';
+		case HUB_PORT_STATE_DISABLED:
+			return 'D';
+		case HUB_PORT_STATE_RESETTING:
+			return 'R';
+		case HUB_PORT_STATE_ENABLED:
+			return 'E';
+		case HUB_PORT_STATE_SUSPENDED:
+			return 'S';
+		case HUB_PORT_STATE_RESUMING:
+			return 'F';
+		default:
+			return '?';
+	}
+}
+
+/** Hub status change mask bits. */
+typedef enum {
+	HUB_STATUS_C_PORT_CONNECTION = (1 << 0),
+	HUB_STATUS_C_PORT_ENABLE = (1 << 1),
+	HUB_STATUS_C_PORT_SUSPEND = (1 << 2),
+	HUB_STATUS_C_PORT_OVER_CURRENT = (1 << 3),
+	HUB_STATUS_C_PORT_RESET = (1 << 4),
+	/* HUB_STATUS_C_ = (1 << ), */
+} hub_status_change_t;
+
+/** Hub port information. */
+typedef struct {
+	virtdev_connection_t *device;
+	hub_port_state_t state;
+	uint16_t status_change;
+} hub_port_t;
+
+/** Hub device type. */
+typedef struct {
+	hub_port_t ports[HUB_PORT_COUNT];
+} hub_device_t;
+
+extern hub_device_t hub_dev;
+
+extern hub_descriptor_t hub_descriptor;
+
+extern usbvirt_device_ops_t hub_ops;
+
+void clear_port_status_change(hub_port_t *, uint16_t);
+void set_port_status_change(hub_port_t *, uint16_t);
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/vhc/hubops.c
===================================================================
--- uspace/drv/vhc/hubops.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/hubops.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,384 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual USB hub operations.
+ */
+#include <usb/classes/classes.h>
+#include <usb/classes/hub.h>
+#include <usbvirt/hub.h>
+#include <usbvirt/device.h>
+#include <errno.h>
+
+#include "vhcd.h"
+#include "hub.h"
+#include "hubintern.h"
+
+/** Produce a byte from bit values.
+ */
+#define MAKE_BYTE(b0, b1, b2, b3, b4, b5, b6, b7) \
+	(( \
+		((b0) << 0) \
+		| ((b1) << 1) \
+		| ((b2) << 2) \
+		| ((b3) << 3) \
+		| ((b4) << 4) \
+		| ((b5) << 5) \
+		| ((b6) << 6) \
+		| ((b7) << 7) \
+	))
+
+static int on_get_descriptor(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data);
+static int on_class_request(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data);
+static int on_data_request(struct usbvirt_device *dev,
+    usb_endpoint_t endpoint,
+    void *buffer, size_t size, size_t *actual_size);
+
+/** Standard USB requests. */
+static usbvirt_standard_device_request_ops_t standard_request_ops = {
+	.on_get_status = NULL,
+	.on_clear_feature = NULL,
+	.on_set_feature = NULL,
+	.on_set_address = NULL,
+	.on_get_descriptor = on_get_descriptor,
+	.on_set_descriptor = NULL,
+	.on_get_configuration = NULL,
+	.on_set_configuration = NULL,
+	.on_get_interface = NULL,
+	.on_set_interface = NULL,
+	.on_synch_frame = NULL
+};
+
+/** Hub operations. */
+usbvirt_device_ops_t hub_ops = {
+	.standard_request_ops = &standard_request_ops,
+	.on_class_device_request = on_class_request,
+	.on_data = NULL,
+	.on_data_request = on_data_request
+};
+
+/** Callback for GET_DESCRIPTOR request. */
+static int on_get_descriptor(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data)
+{
+	if (request->value_high == USB_DESCTYPE_HUB) {
+		int rc = dev->control_transfer_reply(dev, 0,
+		    &hub_descriptor, hub_descriptor.length);
+		
+		return rc;
+	}
+	/* Let the framework handle all the rest. */
+	return EFORWARD;
+}
+
+/** Change port status and updates status change status fields.
+ */
+static void set_port_state(hub_port_t *port, hub_port_state_t state)
+{
+	port->state = state;
+	if (state == HUB_PORT_STATE_POWERED_OFF) {
+		clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
+		clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE);
+		clear_port_status_change(port, HUB_STATUS_C_PORT_RESET);
+	}
+	if (state == HUB_PORT_STATE_RESUMING) {
+		async_usleep(10*1000);
+		if (port->state == state) {
+			set_port_state(port, HUB_PORT_STATE_ENABLED);
+		}
+	}
+	if (state == HUB_PORT_STATE_RESETTING) {
+		async_usleep(10*1000);
+		if (port->state == state) {
+			set_port_status_change(port, HUB_STATUS_C_PORT_RESET);
+			set_port_state(port, HUB_PORT_STATE_ENABLED);
+		}
+	}
+}
+
+/** Get access to a port or return with EINVAL. */
+#define _GET_PORT(portvar, index) \
+	do { \
+		if (virthub_dev.state != USBVIRT_STATE_CONFIGURED) { \
+			return EINVAL; \
+		} \
+		if (((index) == 0) || ((index) > HUB_PORT_COUNT)) { \
+			return EINVAL; \
+		} \
+	} while (false); \
+	hub_port_t *portvar = &hub_dev.ports[index]
+
+
+static int clear_hub_feature(uint16_t feature)
+{
+	return ENOTSUP;
+}
+
+static int clear_port_feature(uint16_t feature, uint16_t portindex)
+{	
+	_GET_PORT(port, portindex);
+	
+	switch (feature) {
+		case USB_HUB_FEATURE_PORT_ENABLE:
+			if ((port->state != HUB_PORT_STATE_NOT_CONFIGURED)
+			    && (port->state != HUB_PORT_STATE_POWERED_OFF)) {
+				set_port_state(port, HUB_PORT_STATE_DISABLED);
+			}
+			return EOK;
+		
+		case USB_HUB_FEATURE_PORT_SUSPEND:
+			if (port->state != HUB_PORT_STATE_SUSPENDED) {
+				return EOK;
+			}
+			set_port_state(port, HUB_PORT_STATE_RESUMING);
+			return EOK;
+			
+		case USB_HUB_FEATURE_PORT_POWER:
+			if (port->state != HUB_PORT_STATE_NOT_CONFIGURED) {
+				set_port_state(port, HUB_PORT_STATE_POWERED_OFF);
+			}
+			return EOK;
+		
+		case USB_HUB_FEATURE_C_PORT_CONNECTION:
+			clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
+			return EOK;
+		
+		case USB_HUB_FEATURE_C_PORT_ENABLE:
+			clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE);
+			return EOK;
+		
+		case USB_HUB_FEATURE_C_PORT_SUSPEND:
+			clear_port_status_change(port, HUB_STATUS_C_PORT_SUSPEND);
+			return EOK;
+			
+		case USB_HUB_FEATURE_C_PORT_OVER_CURRENT:
+			clear_port_status_change(port, HUB_STATUS_C_PORT_OVER_CURRENT);
+			return EOK;
+	}
+	
+	return ENOTSUP;
+}
+
+static int get_bus_state(uint16_t portindex)
+{
+	return ENOTSUP;
+}
+
+static int get_hub_descriptor(uint8_t descriptor_type,
+    uint8_t descriptor_index, uint16_t length)
+{
+	return ENOTSUP;
+}
+
+static int get_hub_status(void)
+{
+	uint32_t hub_status = 0;
+	
+	return virthub_dev.control_transfer_reply(&virthub_dev, 0,
+	    &hub_status, 4);
+}
+
+static int get_port_status(uint16_t portindex)
+{
+	_GET_PORT(port, portindex);
+	
+	uint32_t status;
+	status = MAKE_BYTE(
+	    /* Current connect status. */
+	    port->device == NULL ? 0 : 1,
+	    /* Port enabled/disabled. */
+	    port->state == HUB_PORT_STATE_ENABLED ? 1 : 0,
+	    /* Suspend. */
+	    (port->state == HUB_PORT_STATE_SUSPENDED)
+	        || (port->state == HUB_PORT_STATE_RESUMING) ? 1 : 0,
+	    /* Over-current. */
+	    0,
+	    /* Reset. */
+	    port->state == HUB_PORT_STATE_RESETTING ? 1 : 0,
+	    /* Reserved. */
+	    0, 0, 0)
+	    
+	    | (MAKE_BYTE(
+	    /* Port power. */
+	    port->state == HUB_PORT_STATE_POWERED_OFF ? 0 : 1,
+	    /* Full-speed device. */
+	    0,
+	    /* Reserved. */
+	    0, 0, 0, 0, 0, 0
+	    )) << 8;
+	    
+	status |= (port->status_change << 16);
+	
+	return virthub_dev.control_transfer_reply(&virthub_dev, 0, &status, 4);
+}
+
+
+static int set_hub_feature(uint16_t feature)
+{
+	return ENOTSUP;
+}
+
+static int set_port_feature(uint16_t feature, uint16_t portindex)
+{
+	_GET_PORT(port, portindex);
+	
+	switch (feature) {
+		case USB_HUB_FEATURE_PORT_RESET:
+			if (port->state != HUB_PORT_STATE_POWERED_OFF) {
+				set_port_state(port, HUB_PORT_STATE_RESETTING);
+			}
+			return EOK;
+		
+		case USB_HUB_FEATURE_PORT_SUSPEND:
+			if (port->state == HUB_PORT_STATE_ENABLED) {
+				set_port_state(port, HUB_PORT_STATE_SUSPENDED);
+			}
+			return EOK;
+		
+		case USB_HUB_FEATURE_PORT_POWER:
+			if (port->state == HUB_PORT_STATE_POWERED_OFF) {
+				set_port_state(port, HUB_PORT_STATE_DISCONNECTED);
+			}
+			return EOK;
+	}
+	return ENOTSUP;
+}
+
+#undef _GET_PORT
+
+
+/** Callback for class request. */
+static int on_class_request(struct usbvirt_device *dev,
+    usb_device_request_setup_packet_t *request, uint8_t *data)
+{	
+	dprintf(2, "hub class request (%d)\n", (int) request->request);
+	
+	uint8_t recipient = request->request_type & 31;
+	uint8_t direction = request->request_type >> 7;
+	
+#define _VERIFY(cond) \
+	do { \
+		if (!(cond)) { \
+			dprintf(0, "WARN: invalid class request (%s not met).\n", \
+			    NAME, #cond); \
+			return EINVAL; \
+		} \
+	} while (0)
+	
+	switch (request->request) {
+		case USB_HUB_REQUEST_CLEAR_FEATURE:
+			_VERIFY(direction == 0);
+			_VERIFY(request->length == 0);
+			if (recipient == 0) {
+				_VERIFY(request->index == 0);
+				return clear_hub_feature(request->value);
+			} else {
+				_VERIFY(recipient == 3);
+				return clear_port_feature(request->value,
+				    request->index);
+			}
+			
+		case USB_HUB_REQUEST_GET_STATE:
+			return get_bus_state(request->index);
+			
+		case USB_HUB_REQUEST_GET_DESCRIPTOR:
+			return get_hub_descriptor(request->value_low,
+			    request->value_high, request->length);
+			
+		case USB_HUB_REQUEST_GET_STATUS:
+			if (recipient == 0) {
+				return get_hub_status();
+			} else {
+				return get_port_status(request->index);
+			}
+			
+		case USB_HUB_REQUEST_SET_FEATURE:
+			if (recipient == 0) {
+				return set_hub_feature(request->value);
+			} else {
+				return set_port_feature(request->value, request->index);
+			}
+			
+		default:
+			break;
+	}
+	
+#undef _VERIFY	
+
+
+	return EOK;
+}
+
+void clear_port_status_change(hub_port_t *port, uint16_t change)
+{
+	port->status_change &= (~change);
+}
+
+void set_port_status_change(hub_port_t *port, uint16_t change)
+{
+	port->status_change |= change;
+}
+
+/** Callback for data request. */
+static int on_data_request(struct usbvirt_device *dev,
+    usb_endpoint_t endpoint,
+    void *buffer, size_t size, size_t *actual_size)
+{
+	if (endpoint != HUB_STATUS_CHANGE_PIPE) {
+		return EINVAL;
+	}
+	
+	uint8_t change_map = 0;
+	
+	size_t i;
+	for (i = 0; i < HUB_PORT_COUNT; i++) {
+		hub_port_t *port = &hub_dev.ports[i];
+		
+		if (port->status_change != 0) {
+			change_map |= (1 << (i + 1));
+		}
+	}
+	
+	uint8_t *b = (uint8_t *) buffer;
+	if (size > 0) {
+		*b = change_map;
+		*actual_size = 1;
+	}
+	
+	return EOK;
+}
+
+
+/**
+ * @}
+ */
Index: uspace/drv/vhc/vhc.ma
===================================================================
--- uspace/drv/vhc/vhc.ma	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/vhc.ma	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,2 @@
+10 usb&hc=vhc
+10 usb&hc=vhc&hub
Index: uspace/drv/vhc/vhcd.h
===================================================================
--- uspace/drv/vhc/vhcd.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/drv/vhc/vhcd.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,52 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual USB host controller common definitions.
+ */
+#ifndef VHCD_VHCD_H_
+#define VHCD_VHCD_H_
+
+#define NAME "vhc"
+#define NAME_DEV "hcd-virt-dev"
+#define NAMESPACE "usb"
+
+#define DEVMAP_PATH_HC NAMESPACE "/" NAME
+#define DEVMAP_PATH_DEV NAMESPACE "/" NAME_DEV
+
+extern int debug_level;
+void dprintf(int, const char *, ...);
+void dprintf_inval_call(int, ipc_call_t, ipcarg_t);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/block/libblock.c
===================================================================
--- uspace/lib/block/libblock.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/block/libblock.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -816,6 +816,6 @@
 	    UPPER32(ba), cnt);
 	if (rc != EOK) {
-		printf("Error %d reading %d blocks starting at block %" PRIuOFF64
-		    " from device handle %d\n", rc, cnt, ba,
+		printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
+		    " from device handle %" PRIun "\n", rc, cnt, ba,
 		    devcon->devmap_handle);
 #ifndef NDEBUG
@@ -843,6 +843,6 @@
 	    UPPER32(ba), cnt);
 	if (rc != EOK) {
-		printf("Error %d writing %d blocks starting at block %" PRIuOFF64
-		    " to device handle %d\n", rc, cnt, ba, devcon->devmap_handle);
+		printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
+		    " to device handle %" PRIun "\n", rc, cnt, ba, devcon->devmap_handle);
 #ifndef NDEBUG
 		stacktrace_print();
Index: uspace/lib/c/arch/abs32le/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/inttypes.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/arch/abs32le/include/inttypes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -34,33 +34,8 @@
 #define LIBC_abs32le_INTTYPES_H_
 
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-#define PRId64 "lld"
-#define PRIdPTR "d"
-
-#define PRIo8 "o"
-#define PRIo16 "o"
-#define PRIo32 "o"
-#define PRIo64 "llo"
-#define PRIoPTR "o"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "llu"
-#define PRIuPTR "u"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-#define PRIx64 "llx"
-#define PRIxPTR "x"
-
-#define PRIX8 "X"
-#define PRIX16 "X"
-#define PRIX32 "X"
-#define PRIX64 "llX"
-#define PRIXPTR "X"
+#define PRIdn  PRId32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIun  PRIu32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: uspace/lib/c/arch/amd64/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/amd64/include/inttypes.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/arch/amd64/include/inttypes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,44 +30,12 @@
  * @{
  */
-/** @file Macros for format specifiers.
- *
- * Macros for formatting stdint types as specified in section
- * 7.8.1 Macros for format specifiers of the C99 draft specification
- * (ISO/IEC 9899:201x). Only some macros from the specification are
- * implemented.
- */
 
 #ifndef LIBC_amd64_INTTYPES_H_
 #define LIBC_amd64_INTTYPES_H_
 
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-#define PRId64 "lld"
-#define PRIdPTR "lld"
-
-#define PRIo8 "o"
-#define PRIo16 "o"
-#define PRIo32 "o"
-#define PRIo64 "llo"
-#define PRIoPTR "llo"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "llu"
-#define PRIuPTR "llu"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-#define PRIx64 "llx"
-#define PRIxPTR "llx"
-
-#define PRIX8 "X"
-#define PRIX16 "X"
-#define PRIX32 "X"
-#define PRIX64 "llX"
-#define PRIXPTR "llX"
+#define PRIdn  PRId64  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIun  PRIu64  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
 
 #endif
Index: uspace/lib/c/arch/arm32/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/arm32/include/inttypes.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/arch/arm32/include/inttypes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,44 +30,12 @@
  * @{
  */
-/** @file Macros for format specifiers.
- *
- * Macros for formatting stdint types as specified in section
- * 7.8.1 Macros for format specifiers of the C99 draft specification
- * (ISO/IEC 9899:201x). Only some macros from the specification are
- * implemented.
- */
 
 #ifndef LIBC_arm32_INTTYPES_H_
 #define LIBC_arm32_INTTYPES_H_
 
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-#define PRId64 "lld"
-#define PRIdPTR "d"
-
-#define PRIo8 "o"
-#define PRIo16 "o"
-#define PRIo32 "o"
-#define PRIo64 "llo"
-#define PRIoPTR "o"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "llu"
-#define PRIuPTR "u"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-#define PRIx64 "llx"
-#define PRIxPTR "x"
-
-#define PRIX8 "X"
-#define PRIX16 "X"
-#define PRIX32 "X"
-#define PRIX64 "llX"
-#define PRIXPTR "X"
+#define PRIdn  PRId32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIun  PRIu32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: uspace/lib/c/arch/ia32/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/ia32/include/inttypes.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/arch/ia32/include/inttypes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,44 +30,12 @@
  * @{
  */
-/** @file Macros for format specifiers.
- *
- * Macros for formatting stdint types as specified in section
- * 7.8.1 Macros for format specifiers of the C99 draft specification
- * (ISO/IEC 9899:201x). Only some macros from the specification are
- * implemented.
- */
 
 #ifndef LIBC_ia32_INTTYPES_H_
 #define LIBC_ia32_INTTYPES_H_
 
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-#define PRId64 "lld"
-#define PRIdPTR "d"
-
-#define PRIo8 "o"
-#define PRIo16 "o"
-#define PRIo32 "o"
-#define PRIo64 "llo"
-#define PRIoPTR "o"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "llu"
-#define PRIuPTR "u"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-#define PRIx64 "llx"
-#define PRIxPTR "x"
-
-#define PRIX8 "X"
-#define PRIX16 "X"
-#define PRIX32 "X"
-#define PRIX64 "llX"
-#define PRIXPTR "X"
+#define PRIdn  PRId32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIun  PRIu32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: uspace/lib/c/arch/ia64/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/ia64/include/inttypes.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/arch/ia64/include/inttypes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,44 +30,12 @@
  * @{
  */
-/** @file Macros for format specifiers.
- *
- * Macros for formatting stdint types as specified in section
- * 7.8.1 Macros for format specifiers of the C99 draft specification
- * (ISO/IEC 9899:201x). Only some macros from the specification are
- * implemented.
- */
 
 #ifndef LIBC_ia64_INTTYPES_H_
 #define LIBC_ia64_INTTYPES_H_
 
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-#define PRId64 "ld"
-#define PRIdPTR "ld"
-
-#define PRIo8 "o"
-#define PRIo16 "o"
-#define PRIo32 "o"
-#define PRIo64 "lo"
-#define PRIoPTR "lo"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "lu"
-#define PRIuPTR "lu"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-#define PRIx64 "lx"
-#define PRIxPTR "lx"
-
-#define PRIX8 "X"
-#define PRIX16 "X"
-#define PRIX32 "X"
-#define PRIX64 "lX"
-#define PRIXPTR "lX"
+#define PRIdn  PRId64  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIun  PRIu64  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
 
 #endif
Index: uspace/lib/c/arch/mips32/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/mips32/include/inttypes.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/arch/mips32/include/inttypes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,44 +30,12 @@
  * @{
  */
-/** @file Macros for format specifiers.
- *
- * Macros for formatting stdint types as specified in section
- * 7.8.1 Macros for format specifiers of the C99 draft specification
- * (ISO/IEC 9899:201x). Only some macros from the specification are
- * implemented.
- */
 
 #ifndef LIBC_mips32_INTTYPES_H_
 #define LIBC_mips32_INTTYPES_H_
 
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-#define PRId64 "lld"
-#define PRIdPTR "d"
-
-#define PRIo8 "o"
-#define PRIo16 "o"
-#define PRIo32 "o"
-#define PRIo64 "llo"
-#define PRIoPTR "o"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "llu"
-#define PRIuPTR "u"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-#define PRIx64 "llx"
-#define PRIxPTR "x"
-
-#define PRIX8 "X"
-#define PRIX16 "X"
-#define PRIX32 "X"
-#define PRIX64 "llX"
-#define PRIXPTR "x"
+#define PRIdn  PRId32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIun  PRIu32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: uspace/lib/c/arch/ppc32/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/inttypes.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/arch/ppc32/include/inttypes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,44 +30,12 @@
  * @{
  */
-/** @file Macros for format specifiers.
- *
- * Macros for formatting stdint types as specified in section
- * 7.8.1 Macros for format specifiers of the C99 draft specification
- * (ISO/IEC 9899:201x). Only some macros from the specification are
- * implemented.
- */
 
 #ifndef LIBC_ppc32_INTTYPES_H_
 #define LIBC_ppc32_INTTYPES_H_
 
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-#define PRId64 "lld"
-#define PRIdPTR "d"
-
-#define PRIo8 "o"
-#define PRIo16 "o"
-#define PRIo32 "o"
-#define PRIo64 "llo"
-#define PRIoPTR "o"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "llu"
-#define PRIuPTR "u"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-#define PRIx64 "llx"
-#define PRIxPTR "x"
-
-#define PRIX8 "X"
-#define PRIX16 "X"
-#define PRIX32 "X"
-#define PRIX64 "llX"
-#define PRIXPTR "X"
+#define PRIdn  PRId32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIun  PRIu32  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
 
 #endif
Index: uspace/lib/c/arch/sparc64/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/inttypes.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/arch/sparc64/include/inttypes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -30,44 +30,12 @@
  * @{
  */
-/** @file Macros for format specifiers.
- *
- * Macros for formatting stdint types as specified in section
- * 7.8.1 Macros for format specifiers of the C99 draft specification
- * (ISO/IEC 9899:201x). Only some macros from the specification are
- * implemented.
- */
 
 #ifndef LIBC_sparc64_INTTYPES_H_
 #define LIBC_sparc64_INTTYPES_H_
 
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-#define PRId64 "lld"
-#define PRIdPTR "lld"
-
-#define PRIo8 "o"
-#define PRIo16 "o"
-#define PRIo32 "o"
-#define PRIo64 "llo"
-#define PRIoPTR "llo"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "llu"
-#define PRIuPTR "llu"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-#define PRIx64 "llx"
-#define PRIxPTR "llx"
-
-#define PRIX8 "X"
-#define PRIX16 "X"
-#define PRIX32 "X"
-#define PRIX64 "llX"
-#define PRIXPTR "llX"
+#define PRIdn  PRId64  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIun  PRIu64  /**< Format for sysarg_t, ipcarg_t, etc. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
 
 #endif
Index: uspace/lib/c/generic/device/char.c
===================================================================
--- uspace/lib/c/generic/device/char.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/generic/device/char.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -26,5 +26,5 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
  /** @addtogroup libc
  * @{
@@ -40,44 +40,48 @@
 #include <stdio.h>
 
-/** Read to or write from the device using its character interface.
- * 
- * Helper function.
- * 
- * @param dev_phone phone to the device.
- * @param buf the buffer for the data read from or written to the device.
- * @param len the maximum length of the data to be read or written.
- * @param read read from the device if true, write to it otherwise.
- * 
- * @return non-negative number of bytes actually read from or written to the device on success,
- * negative error number otherwise.
- * 
+/** Read to or write from device.
+ *
+ * Helper function to read to or write from a device
+ * using its character interface.
+ *
+ * @param dev_phone Phone to the device.
+ * @param buf       Buffer for the data read
+ *                  from or written to the device.
+ * @param len       Maximum length of the data to be
+ *                  read or written.
+ * @param read      Read from the device if true,
+ *                  write to it otherwise.
+ *
+ * @return Non-negative number of bytes actually read
+ *         from or written to the device on success,
+ *         negative error number otherwise.
+ *
  */
-static int rw_dev(int dev_phone, void *buf, size_t len, bool read) 
+static ssize_t rw_dev(int dev_phone, void *buf, size_t len, bool read)
 {
-	ipc_call_t answer;
-	
 	async_serialize_start();
 	
+	ipc_call_t answer;
 	aid_t req;
 	int ret;
 	
 	if (read) {
-		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_READ_DEV, &answer);
-		ret = async_data_read_start(dev_phone, buf, len);		
+		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		    CHAR_READ_DEV, &answer);
+		ret = async_data_read_start(dev_phone, buf, len);
 	} else {
-		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_WRITE_DEV, &answer);
+		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		    CHAR_WRITE_DEV, &answer);
 		ret = async_data_write_start(dev_phone, buf, len);
 	}
 	
 	ipcarg_t rc;
-	if (ret != EOK) {		
+	if (ret != EOK) {
 		async_wait_for(req, &rc);
 		async_serialize_end();
-		if (rc == EOK) {
-			return ret;
-		}
-		else {
-			return (int) rc;
-		}
+		if (rc == EOK)
+			return (ssize_t) ret;
+			
+		return (ssize_t) rc;
 	}
 	
@@ -85,39 +89,45 @@
 	async_serialize_end();
 	
-	ret = (int)rc;
-	if (EOK != ret) {
-		return ret;
-	}
+	ret = (int) rc;
+	if (ret != EOK)
+		return (ssize_t) ret;
 	
-	return IPC_GET_ARG1(answer);	
+	return (ssize_t) IPC_GET_ARG1(answer);
 }
 
-/** Read from the device using its character interface.
- * 
- * @param dev_phone phone to the device.
- * @param buf the output buffer for the data read from the device.
- * @param len the maximum length of the data to be read.
- * 
- * @return non-negative number of bytes actually read from the device on success, negative error number otherwise.
+/** Read from device using its character interface.
+ *
+ * @param dev_phone Phone to the device.
+ * @param buf       Output buffer for the data
+ *                  read from the device.
+ * @param len       Maximum length of the data to be read.
+ *
+ * @return Non-negative number of bytes actually read
+ *         from the device on success, negative error
+ *         number otherwise.
+ *
  */
-int read_dev(int dev_phone, void *buf, size_t len)
-{	
+ssize_t read_dev(int dev_phone, void *buf, size_t len)
+{
 	return rw_dev(dev_phone, buf, len, true);
 }
 
-/** Write to the device using its character interface.
- * 
- * @param dev_phone phone to the device.
- * @param buf the input buffer containg the data to be written to the device.
- * @param len the maximum length of the data to be written.
- * 
- * @return non-negative number of bytes actually written to the device on success, negative error number otherwise.
+/** Write to device using its character interface.
+ *
+ * @param dev_phone Phone to the device.
+ * @param buf       Input buffer containg the data
+ *                  to be written to the device.
+ * @param len       Maximum length of the data to be written.
+ *
+ * @return Non-negative number of bytes actually written
+ *         to the device on success, negative error number
+ *         otherwise.
+ *
  */
-int write_dev(int dev_phone, void *buf, size_t len)
+ssize_t write_dev(int dev_phone, void *buf, size_t len)
 {
 	return rw_dev(dev_phone, buf, len, false);
 }
 
-  
- /** @}
+/** @}
  */
Index: uspace/lib/c/generic/io/printf_core.c
===================================================================
--- uspace/lib/c/generic/io/printf_core.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/generic/io/printf_core.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -82,5 +82,6 @@
 	PrintfQualifierLong,
 	PrintfQualifierLongLong,
-	PrintfQualifierPointer
+	PrintfQualifierPointer,
+	PrintfQualifierSize
 } qualifier_t;
 
@@ -552,7 +553,8 @@
  *  - ""   Signed or unsigned int (default value).@n
  *  - "l"  Signed or unsigned long int.@n
- *         If conversion is "c", the character is wchar_t (wide character).@n
+ *         If conversion is "c", the character is wint_t (wide character).@n
  *         If conversion is "s", the string is wchar_t * (wide string).@n
  *  - "ll" Signed or unsigned long long int.@n
+ *  - "z"  Signed or unsigned ssize_t or site_t.@n
  *
  * CONVERSION:@n
@@ -736,4 +738,9 @@
 				}
 				break;
+			case 'z':
+				qualifier = PrintfQualifierSize;
+				i = nxt;
+				uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+				break;
 			default:
 				/* Default type */
@@ -763,5 +770,5 @@
 			case 'c':
 				if (qualifier == PrintfQualifierLong)
-					retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps);
+					retval = print_wchar(va_arg(ap, wint_t), width, flags, ps);
 				else
 					retval = print_char(va_arg(ap, unsigned int), width, flags, ps);
@@ -849,4 +856,8 @@
 				precision = size << 1;
 				number = (uint64_t) (uintptr_t) va_arg(ap, void *);
+				break;
+			case PrintfQualifierSize:
+				size = sizeof(size_t);
+				number = (uint64_t) va_arg(ap, size_t);
 				break;
 			default:
Index: uspace/lib/c/generic/stacktrace.c
===================================================================
--- uspace/lib/c/generic/stacktrace.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/generic/stacktrace.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -50,5 +50,5 @@
 
 	while (stacktrace_fp_valid(&st, fp)) {
-		printf("%p: %p()\n", fp, pc);
+		printf("%p: %p()\n", (void *) fp, (void *) pc);
 		(void) stacktrace_ra_get(&st, fp, &pc);
 		(void) stacktrace_fp_prev(&st, fp, &nfp);
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/generic/str.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -1005,4 +1005,210 @@
 	*end = '\0';
 	return start;
+}
+
+/** Convert string to uint64_t (internal variant).
+ *
+ * @param nptr   Pointer to string.
+ * @param endptr Pointer to the first invalid character is stored here.
+ * @param base   Zero or number between 2 and 36 inclusive.
+ * @param neg    Indication of unary minus is stored here.
+ * @apram result Result of the conversion.
+ *
+ * @return EOK if conversion was successful.
+ *
+ */
+static int str_uint(const char *nptr, char **endptr, unsigned int base,
+    bool *neg, uint64_t *result)
+{
+	assert(endptr != NULL);
+	assert(neg != NULL);
+	assert(result != NULL);
+	
+	*neg = false;
+	const char *str = nptr;
+	
+	/* Ignore leading whitespace */
+	while (isspace(*str))
+		str++;
+	
+	if (*str == '-') {
+		*neg = true;
+		str++;
+	} else if (*str == '+')
+		str++;
+	
+	if (base == 0) {
+		/* Decode base if not specified */
+		base = 10;
+		
+		if (*str == '0') {
+			base = 8;
+			str++;
+			
+			switch (*str) {
+			case 'b':
+			case 'B':
+				base = 2;
+				str++;
+				break;
+			case 'o':
+			case 'O':
+				base = 8;
+				str++;
+				break;
+			case 'd':
+			case 'D':
+			case 't':
+			case 'T':
+				base = 10;
+				str++;
+				break;
+			case 'x':
+			case 'X':
+				base = 16;
+				str++;
+				break;
+			default:
+				str--;
+			}
+		}
+	} else {
+		/* Check base range */
+		if ((base < 2) || (base > 36)) {
+			*endptr = (char *) str;
+			return EINVAL;
+		}
+	}
+	
+	*result = 0;
+	const char *startstr = str;
+	
+	while (*str != 0) {
+		unsigned int digit;
+		
+		if ((*str >= 'a') && (*str <= 'z'))
+			digit = *str - 'a' + 10;
+		else if ((*str >= 'A') && (*str <= 'Z'))
+			digit = *str - 'A' + 10;
+		else if ((*str >= '0') && (*str <= '9'))
+			digit = *str - '0';
+		else
+			break;
+		
+		if (digit >= base)
+			break;
+		
+		uint64_t prev = *result;
+		*result = (*result) * base + digit;
+		
+		if (*result < prev) {
+			/* Overflow */
+			*endptr = (char *) str;
+			return EOVERFLOW;
+		}
+		
+		str++;
+	}
+	
+	if (str == startstr) {
+		/*
+		 * No digits were decoded => first invalid character is
+		 * the first character of the string.
+		 */
+		str = nptr;
+	}
+	
+	*endptr = (char *) str;
+	
+	if (str == nptr)
+		return EINVAL;
+	
+	return EOK;
+}
+
+/** Convert string to uint64_t.
+ *
+ * @param nptr   Pointer to string.
+ * @param endptr If not NULL, pointer to the first invalid character
+ *               is stored here.
+ * @param base   Zero or number between 2 and 36 inclusive.
+ * @param strict Do not allow any trailing characters.
+ * @param result Result of the conversion.
+ *
+ * @return EOK if conversion was successful.
+ *
+ */
+int str_uint64(const char *nptr, char **endptr, unsigned int base,
+    bool strict, uint64_t *result)
+{
+	assert(result != NULL);
+	
+	bool neg;
+	char *lendptr;
+	int ret = str_uint(nptr, &lendptr, base, &neg, result);
+	
+	if (endptr != NULL)
+		*endptr = (char *) lendptr;
+	
+	if (ret != EOK)
+		return ret;
+	
+	/* Do not allow negative values */
+	if (neg)
+		return EINVAL;
+	
+	/* Check whether we are at the end of
+	   the string in strict mode */
+	if ((strict) && (*lendptr != 0))
+		return EINVAL;
+	
+	return EOK;
+}
+
+/** Convert string to size_t.
+ *
+ * @param nptr   Pointer to string.
+ * @param endptr If not NULL, pointer to the first invalid character
+ *               is stored here.
+ * @param base   Zero or number between 2 and 36 inclusive.
+ * @param strict Do not allow any trailing characters.
+ * @param result Result of the conversion.
+ *
+ * @return EOK if conversion was successful.
+ *
+ */
+int str_size_t(const char *nptr, char **endptr, unsigned int base,
+    bool strict, size_t *result)
+{
+	assert(result != NULL);
+	
+	bool neg;
+	char *lendptr;
+	uint64_t res;
+	int ret = str_uint(nptr, &lendptr, base, &neg, &res);
+	
+	if (endptr != NULL)
+		*endptr = (char *) lendptr;
+	
+	if (ret != EOK)
+		return ret;
+	
+	/* Do not allow negative values */
+	if (neg)
+		return EINVAL;
+	
+	/* Check whether we are at the end of
+	   the string in strict mode */
+	if ((strict) && (*lendptr != 0))
+		return EINVAL;
+	
+	/* Check for overflow */
+	size_t _res = (size_t) res;
+	if (_res != res)
+		return EOVERFLOW;
+	
+	*result = _res;
+	
+	return EOK;
 }
 
Index: uspace/lib/c/include/assert.h
===================================================================
--- uspace/lib/c/include/assert.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/assert.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -51,15 +51,19 @@
 
 #ifndef NDEBUG
-#	define assert(expr) \
-		do { \
-			if (!(expr)) { \
-				printf("Assertion failed (%s) at file '%s', " \
-				    "line %d.\n", #expr, __FILE__, __LINE__); \
-				abort(); \
-			} \
-		} while (0)
-#else
-#	define assert(expr)
-#endif
+
+#define assert(expr) \
+	do { \
+		if (!(expr)) { \
+			printf("Assertion failed (%s) at file '%s', " \
+			    "line %d.\n", #expr, __FILE__, __LINE__); \
+			abort(); \
+		} \
+	} while (0)
+
+#else /* NDEBUG */
+
+#define assert(expr)
+
+#endif /* NDEBUG */
 
 #endif
Index: uspace/lib/c/include/device/char.h
===================================================================
--- uspace/lib/c/include/device/char.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/device/char.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -26,5 +26,5 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
  /** @addtogroup libc
  * @{
@@ -32,5 +32,5 @@
 /** @file
  */
- 
+
 #ifndef LIBC_DEVICE_HW_RES_H_
 #define LIBC_DEVICE_HW_RES_H_
@@ -38,9 +38,9 @@
 typedef enum {
 	CHAR_READ_DEV = 0,
-	CHAR_WRITE_DEV	
+	CHAR_WRITE_DEV
 } hw_res_funcs_t;
 
-int read_dev(int dev_phone, void *buf, size_t len);
-int write_dev(int dev_phone, void *buf, size_t len);
+ssize_t read_dev(int dev_phone, void *buf, size_t len);
+ssize_t write_dev(int dev_phone, void *buf, size_t len);
 
 #endif
Index: uspace/lib/c/include/err.h
===================================================================
--- uspace/lib/c/include/err.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/err.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -38,8 +38,9 @@
 #include <stdio.h>
 
-#define errx(status, fmt, ...) { \
-	printf((fmt), ##__VA_ARGS__); \
-	_exit(status); \
-}
+#define errx(status, fmt, ...) \
+	{ \
+		printf((fmt), ##__VA_ARGS__); \
+		_exit(status); \
+	}
 
 #endif
@@ -47,3 +48,2 @@
 /** @}
  */
-
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -38,4 +38,8 @@
 	HW_RES_DEV_IFACE = 0,	
 	CHAR_DEV_IFACE,
+
+	/** Interface provided by USB host controller. */
+	USBHC_DEV_IFACE,
+
 	// TODO add more interfaces
 	DEV_IFACE_MAX
Index: uspace/lib/c/include/malloc.h
===================================================================
--- uspace/lib/c/include/malloc.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/malloc.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -41,7 +41,10 @@
 extern uintptr_t get_max_heap_addr(void);
 
-extern void *malloc(const size_t size);
-extern void *calloc(const size_t nmemb, const size_t size);
-extern void *memalign(const size_t align, const size_t size);
+extern void *malloc(const size_t size)
+    __attribute__((malloc));
+extern void *calloc(const size_t nmemb, const size_t size)
+    __attribute__((malloc));
+extern void *memalign(const size_t align, const size_t size)
+    __attribute__((malloc));
 extern void *realloc(const void *addr, const size_t size);
 extern void free(const void *addr);
Index: uspace/lib/c/include/stdint.h
===================================================================
--- uspace/lib/c/include/stdint.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/stdint.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -36,27 +36,27 @@
 #define LIBC_STDINT_H_
 
-#define INT8_MIN  (0x80)
-#define INT8_MAX  (0x7F)
+#define INT8_MIN  INT8_C(0x80)
+#define INT8_MAX  INT8_C(0x7F)
 
-#define UINT8_MIN  (0u)
-#define UINT8_MAX  (0xFFu)
+#define UINT8_MIN  UINT8_C(0)
+#define UINT8_MAX  UINT8_C(0xFF)
 
-#define INT16_MIN  (0x8000)
-#define INT16_MAX  (0x7FFF)
+#define INT16_MIN  INT16_C(0x8000)
+#define INT16_MAX  INT16_C(0x7FFF)
 
-#define UINT16_MIN  (0u)
-#define UINT16_MAX  (0xFFFFu)
+#define UINT16_MIN  UINT16_C(0)
+#define UINT16_MAX  UINT16_C(0xFFFF)
 
-#define INT32_MIN  (0x80000000l)
-#define INT32_MAX  (0x7FFFFFFFl)
+#define INT32_MIN  INT32_C(0x80000000)
+#define INT32_MAX  INT32_C(0x7FFFFFFF)
 
-#define UINT32_MIN  (0ul)
-#define UINT32_MAX  (0xFFFFFFFFul)
+#define UINT32_MIN  UINT32_C(0)
+#define UINT32_MAX  UINT32_C(0xFFFFFFFF)
 
-#define INT64_MIN  (0x8000000000000000ll)
-#define INT64_MAX  (0x7FFFFFFFFFFFFFFFll)
+#define INT64_MIN  INT64_C(0x8000000000000000)
+#define INT64_MAX  INT64_C(0x7FFFFFFFFFFFFFFF)
 
-#define UINT64_MIN  (0ull)
-#define UINT64_MAX  (0xFFFFFFFFFFFFFFFFull)
+#define UINT64_MIN  UINT64_C(0)
+#define UINT64_MAX  UINT64_C(0xFFFFFFFFFFFFFFFF)
 
 #include <libarch/types.h>
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/stdio.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -41,4 +41,15 @@
 #include <adt/list.h>
 
+#ifndef NVERIFY_PRINTF
+
+#define PRINTF_ATTRIBUTE(start, end) \
+	__attribute__((format(gnu_printf, start, end)))
+
+#else /* NVERIFY_PRINTF */
+
+#define PRINTF_ATTRIBUTE(start, end)
+
+#endif /* NVERIFY_PRINTF */
+
 #define EOF  (-1)
 
@@ -149,12 +160,16 @@
 
 /* Formatted string output functions */
-extern int fprintf(FILE *, const char*, ...);
+extern int fprintf(FILE *, const char*, ...)
+    PRINTF_ATTRIBUTE(2, 3);
 extern int vfprintf(FILE *, const char *, va_list);
 
-extern int printf(const char *, ...);
+extern int printf(const char *, ...)
+    PRINTF_ATTRIBUTE(1, 2);
 extern int vprintf(const char *, va_list);
 
-extern int snprintf(char *, size_t , const char *, ...);
-extern int asprintf(char **, const char *, ...);
+extern int snprintf(char *, size_t , const char *, ...)
+    PRINTF_ATTRIBUTE(3, 4);
+extern int asprintf(char **, const char *, ...)
+    PRINTF_ATTRIBUTE(2, 3);
 extern int vsnprintf(char *, size_t, const char *, va_list);
 
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/str.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -86,4 +86,7 @@
 extern char *str_ndup(const char *, size_t max_size);
 
+extern int str_uint64(const char *, char **, unsigned int, bool, uint64_t *);
+extern int str_size_t(const char *, char **, unsigned int, bool, size_t *);
+
 extern void order_suffix(const uint64_t val, uint64_t *rv, char *suffix);
 
Index: uspace/lib/c/include/sys/typefmt.h
===================================================================
--- uspace/lib/c/include/sys/typefmt.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/sys/typefmt.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -39,5 +39,5 @@
 #include <inttypes.h>
 
-/* off64_t */
+/* off64_t, aoff64_t */
 #define PRIdOFF64 PRId64
 #define PRIuOFF64 PRIu64
@@ -45,28 +45,4 @@
 #define PRIXOFF64 PRIX64
 
-/* (s)size_t */
-#define PRIdSIZE PRIdPTR
-#define PRIuSIZE PRIuPTR
-#define PRIxSIZE PRIxPTR
-#define PRIXSIZE PRIXPTR
-
-/* sysarg_t */
-#define PRIdSYSARG PRIdPTR
-#define PRIuSYSARG PRIuPTR
-#define PRIxSYSARG PRIxPTR
-#define PRIXSYSARG PRIxPTR
-
-/* ipcarg_t */
-#define PRIdIPCARG PRIdPTR
-#define PRIuIPCARG PRIuPTR
-#define PRIxIPCARG PRIxPTR
-#define PRIXIPCARG PRIXPTR
-
-/* taskid_t */
-#define PRIdTASKID PRId64
-#define PRIuTASKID PRIu64
-#define PRIxTASKID PRIx64
-#define PRIXTASKID PRIx64
-
 #endif
 
Index: uspace/lib/c/include/sys/types.h
===================================================================
--- uspace/lib/c/include/sys/types.h	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/c/include/sys/types.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -46,7 +46,4 @@
 typedef uint64_t aoff64_t;
 
-/** Unicode code point */
-typedef int32_t wchar_t;
-
 typedef volatile uint8_t ioport8_t;
 typedef volatile uint16_t ioport16_t;
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/drv/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -29,5 +29,5 @@
 
 USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude
+EXTRA_CFLAGS = -Iinclude -I$(LIBUSB_PREFIX)/include
 LIBRARY = libdrv
 
@@ -36,4 +36,5 @@
 	generic/dev_iface.c \
 	generic/remote_res.c \
+	generic/remote_usbhc.c \
 	generic/remote_char.c
 
Index: uspace/lib/drv/generic/dev_iface.c
===================================================================
--- uspace/lib/drv/generic/dev_iface.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/drv/generic/dev_iface.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -39,9 +39,11 @@
 #include "remote_res.h"
 #include "remote_char.h"
+#include "remote_usbhc.h"
 
 static iface_dipatch_table_t remote_ifaces = {
 	.ifaces = {
 		&remote_res_iface,
-		&remote_char_iface
+		&remote_char_iface,
+		&remote_usbhc_iface
 	}
 };
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/lib/drv/generic/driver.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -48,4 +48,5 @@
 #include <ctype.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include <ipc/driver.h>
@@ -177,8 +178,8 @@
 	res = driver->driver_ops->add_device(dev);
 	if (0 == res) {
-		printf("%s: new device with handle = %x was added.\n",
+		printf("%s: new device with handle=%" PRIun " was added.\n",
 		    driver->name, dev_handle);
 	} else {
-		printf("%s: failed to add a new device with handle = %d.\n",
+		printf("%s: failed to add a new device with handle = %" PRIun ".\n",
 		    driver->name, dev_handle);
 		remove_from_devices_list(dev);
@@ -207,6 +208,5 @@
 			break;
 		default:
-			if (!(callid & IPC_CALLID_NOTIFICATION))
-				ipc_answer_0(callid, ENOENT);
+			ipc_answer_0(callid, ENOENT);
 		}
 	}
@@ -230,5 +230,5 @@
 	if (dev == NULL) {
 		printf("%s: driver_connection_gen error - no device with handle"
-		    " %x was found.\n", driver->name, handle);
+		    " %" PRIun " was found.\n", driver->name, handle);
 		ipc_answer_0(iid, ENOENT);
 		return;
@@ -294,5 +294,5 @@
 				printf("%s: driver_connection_gen error - ",
 				    driver->name);
-				printf("device with handle %d has no interface "
+				printf("device with handle %" PRIun " has no interface "
 				    "with id %d.\n", handle, iface_idx);
 				ipc_answer_0(callid, ENOTSUP);
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,204 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <errno.h>
+
+#include "usbhc_iface.h"
+#include "driver.h"
+
+#define USB_MAX_PAYLOAD_SIZE 1020
+
+static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
+//static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *);
+
+/** Remote USB interface operations. */
+static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
+	&remote_usbhc_get_buffer,
+	&remote_usbhc_interrupt_out,
+	&remote_usbhc_interrupt_in
+};
+
+/** Remote USB interface structure.
+ */
+remote_iface_t remote_usbhc_iface = {
+	.method_count = sizeof(remote_usbhc_iface_ops) /
+	    sizeof(remote_usbhc_iface_ops[0]),
+	.methods = remote_usbhc_iface_ops
+};
+
+typedef struct {
+	ipc_callid_t caller;
+	void *buffer;
+	size_t size;
+} async_transaction_t;
+
+
+void remote_usbhc_get_buffer(device_t *device, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	ipcarg_t buffer_hash = IPC_GET_ARG1(*call);
+	async_transaction_t * trans = (async_transaction_t *)buffer_hash;
+	if (trans == NULL) {
+		ipc_answer_0(callid, ENOENT);
+		return;
+	}
+	if (trans->buffer == NULL) {
+		ipc_answer_0(callid, EINVAL);
+		free(trans);
+		return;
+	}
+
+	ipc_callid_t cid;
+	size_t accepted_size;
+	if (!async_data_read_receive(&cid, &accepted_size)) {
+		ipc_answer_0(callid, EINVAL);
+		return;
+	}
+
+	if (accepted_size > trans->size) {
+		accepted_size = trans->size;
+	}
+	async_data_read_finalize(callid, trans->buffer, accepted_size);
+
+	ipc_answer_1(callid, EOK, accepted_size);
+
+	free(trans->buffer);
+	free(trans);
+}
+
+
+static void callback_out(device_t *device,
+    usb_transaction_outcome_t outcome, void *arg)
+{
+	async_transaction_t *trans = (async_transaction_t *)arg;
+
+	// FIXME - answer according to outcome
+	ipc_answer_0(trans->caller, EOK);
+
+	free(trans);
+}
+
+static void callback_in(device_t *device,
+    usb_transaction_outcome_t outcome, size_t actual_size, void *arg)
+{
+	async_transaction_t *trans = (async_transaction_t *)arg;
+
+	// FIXME - answer according to outcome
+	ipc_answer_1(trans->caller, EOK, (ipcarg_t)trans);
+
+	trans->size = actual_size;
+}
+
+void remote_usbhc_interrupt_out(device_t *device, void *iface,
+	    ipc_callid_t callid, ipc_call_t *call)
+{
+	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
+
+	size_t expected_len = IPC_GET_ARG3(*call);
+	usb_target_t target = {
+		.address = IPC_GET_ARG1(*call),
+		.endpoint = IPC_GET_ARG2(*call)
+	};
+
+	size_t len = 0;
+	void *buffer = NULL;
+	if (expected_len > 0) {
+		int rc = async_data_write_accept(&buffer, false,
+		    1, USB_MAX_PAYLOAD_SIZE,
+		    0, &len);
+
+		if (rc != EOK) {
+			ipc_answer_0(callid, rc);
+			return;
+		}
+	}
+
+	if (!usb_iface->interrupt_out) {
+		ipc_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
+	trans->caller = callid;
+	trans->buffer = NULL;
+	trans->size = 0;
+
+	int rc = usb_iface->interrupt_out(device, target, buffer, len,
+	    callback_out, trans);
+
+	if (rc != EOK) {
+		ipc_answer_0(callid, rc);
+		free(trans);
+	}
+}
+
+void remote_usbhc_interrupt_in(device_t *device, void *iface,
+	    ipc_callid_t callid, ipc_call_t *call)
+{
+	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
+
+	size_t len = IPC_GET_ARG3(*call);
+	usb_target_t target = {
+		.address = IPC_GET_ARG1(*call),
+		.endpoint = IPC_GET_ARG2(*call)
+	};
+
+	if (!usb_iface->interrupt_in) {
+		ipc_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
+	trans->caller = callid;
+	trans->buffer = malloc(len);
+	trans->size = len;
+
+	int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,
+	    callback_in, trans);
+
+	if (rc != EOK) {
+		ipc_answer_0(callid, rc);
+		free(trans->buffer);
+		free(trans);
+	}
+}
+
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/remote_usbhc.h
===================================================================
--- uspace/lib/drv/include/remote_usbhc.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/drv/include/remote_usbhc.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,44 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USBHC_H_
+#define LIBDRV_REMOTE_USBHC_H_
+
+remote_iface_t remote_usbhc_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,171 @@
+/*
+ * 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 libdrv usb
+ * @{
+ */
+/** @file
+ * @brief USB interface definition.
+ */
+
+#ifndef LIBDRV_USBHC_IFACE_H_
+#define LIBDRV_USBHC_IFACE_H_
+
+#include "driver.h"
+#include <usb/usb.h>
+
+
+/** IPC methods for communication with HC through DDF interface.
+ *
+ * Notes for async methods:
+ *
+ * Methods for sending data to device (OUT transactions)
+ * - e.g. IPC_M_USBHC_INTERRUPT_OUT -
+ * always use the same semantics:
+ * - first, IPC call with given method is made
+ *   - argument #1 is target address
+ *   - argument #2 is target endpoint
+ *   - argument #3 is buffer size
+ * - this call is immediately followed by IPC data write (from caller)
+ * - the initial call (and the whole transaction) is answer after the
+ *   transaction is scheduled by the HC and acknowledged by the device
+ *   or immediately after error is detected
+ * - the answer carries only the error code
+ *
+ * Methods for retrieving data from device (IN transactions)
+ * - e.g. IPC_M_USBHC_INTERRUPT_IN -
+ * also use the same semantics:
+ * - first, IPC call with given method is made
+ *   - argument #1 is target address
+ *   - argument #2 is target endpoint
+ *   - argument #3 is buffer size
+ * - the call is not answered until the device returns some data (or until
+ *   error occurs)
+ * - if the call is answered with EOK, first argument of the answer is buffer
+ *   hash that could be used to retrieve the actual data
+ *
+ * Some special methods (NO-DATA transactions) do not send any data. These
+ * might behave as both OUT or IN transactions because communication parts
+ * where actual buffers are exchanged are omitted.
+ *
+ * The mentioned data retrieval can be done any time after receiving EOK
+ * answer to IN method.
+ * This retrieval is done using the IPC_M_USBHC_GET_BUFFER where
+ * the first argument is buffer hash from call answer.
+ * This call must be immediately followed by data read-in and after the
+ * data are transferred, the initial call (IPC_M_USBHC_GET_BUFFER)
+ * is answered. Each buffer can be retrieved only once.
+ *
+ * For all these methods, wrap functions exists. Important rule: functions
+ * for IN transactions have (as parameters) buffers where retrieved data
+ * will be stored. These buffers must be already allocated and shall not be
+ * touch until the transaction is completed
+ * (e.g. not before calling usb_wait_for() with appropriate handle).
+ * OUT transactions buffers can be freed immediately after call is dispatched
+ * (i.e. after return from wrapping function).
+ *
+ */
+typedef enum {
+	/** Asks for data buffer.
+	 * See explanation at usb_iface_funcs_t.
+	 * This function does not have counter part in functional interface
+	 * as it is handled by the remote part itself.
+	 */
+	IPC_M_USBHC_GET_BUFFER,
+
+
+	/** Send interrupt data to device.
+	 * See explanation at usb_iface_funcs_t (OUT transaction).
+	 */
+	IPC_M_USBHC_INTERRUPT_OUT,
+
+	/** Get interrupt data from device.
+	 * See explanation at usb_iface_funcs_t (IN transaction).
+	 */
+	IPC_M_USBHC_INTERRUPT_IN,
+
+
+	/** Start WRITE control transfer.
+	 * See explanation at usb_iface_funcs_t (OUT transaction).
+	 */
+	IPC_M_USBHC_CONTROL_WRITE_SETUP,
+
+	/** Send control-transfer data to device.
+	 * See explanation at usb_iface_funcs_t (OUT transaction).
+	 */
+	IPC_M_USBHC_CONTROL_WRITE_DATA,
+
+	/** Terminate WRITE control transfer.
+	 * See explanation at usb_iface_funcs_t (NO-DATA transaction).
+	 */
+	IPC_M_USBHC_CONTROL_WRITE_STATUS,
+
+
+
+	/** Start READ control transfer.
+	 * See explanation at usb_iface_funcs_t (OUT transaction).
+	 */
+	IPC_M_USBHC_CONTROL_READ_SETUP,
+
+	/** Get control-transfer data from device.
+	 * See explanation at usb_iface_funcs_t (IN transaction).
+	 */
+	IPC_M_USBHC_CONTROL_READ_DATA,
+
+	/** Terminate READ control transfer.
+	 * See explanation at usb_iface_funcs_t (NO-DATA transaction).
+	 */
+	IPC_M_USBHC_CONTROL_READ_STATUS,
+
+
+	/* IPC_M_USB_ */
+} usbhc_iface_funcs_t;
+
+/** Callback for outgoing transfer. */
+typedef void (*usbhc_iface_transfer_out_callback_t)(device_t *,
+    usb_transaction_outcome_t, void *);
+
+/** Callback for incoming transfer. */
+typedef void (*usbhc_iface_transfer_in_callback_t)(device_t *,
+    usb_transaction_outcome_t, size_t, void *);
+
+/** USB devices communication interface. */
+typedef struct {
+	int (*interrupt_out)(device_t *, usb_target_t,
+	    void *, size_t,
+	    usbhc_iface_transfer_out_callback_t, void *);
+	int (*interrupt_in)(device_t *, usb_target_t,
+	    void *, size_t,
+	    usbhc_iface_transfer_in_callback_t, void *);
+} usbhc_iface_t;
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/Makefile
===================================================================
--- uspace/lib/usb/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBRARY = libusb
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -Iinclude
+
+SOURCES = \
+	src/hcdhubd.c \
+	src/localdrv.c \
+	src/usb.c \
+	src/usbdrv.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/usb/include/usb/classes/classes.h
===================================================================
--- uspace/lib/usb/include/usb/classes/classes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/classes/classes.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,66 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB device classes and subclasses.
+ */
+#ifndef LIBUSB_CLASSES_H_
+#define LIBUSB_CLASSES_H_
+
+/** USB device class. */
+typedef enum {
+	USB_CLASS_USE_INTERFACE = 0x00,
+	USB_CLASS_AUDIO = 0x01,
+	USB_CLASS_COMMUNICATIONS_CDC_CONTROL = 0x02,
+	USB_CLASS_HID = 0x03,
+	USB_CLASS_PHYSICAL = 0x05,
+	USB_CLASS_IMAGE = 0x06,
+	USB_CLASS_PRINTER = 0x07,
+	USB_CLASS_MASS_STORAGE = 0x08,
+	USB_CLASS_HUB = 0x09,
+	USB_CLASS_CDC_DATA = 0x0A,
+	USB_CLASS_SMART_CARD = 0x0B,
+	USB_CLASS_CONTENT_SECURITY = 0x0D,
+	USB_CLASS_VIDEO = 0x0E,
+	USB_CLASS_PERSONAL_HEALTHCARE = 0x0F,
+	USB_CLASS_DIAGNOSTIC = 0xDC,
+	USB_CLASS_WIRELESS_CONTROLLER = 0xE0,
+	USB_CLASS_MISCELLANEOUS = 0xEF,
+	USB_CLASS_APPLICATION_SPECIFIC = 0xFE,
+	USB_CLASS_VENDOR_SPECIFIC = 0xFF,
+	/* USB_CLASS_ = 0x, */
+} usb_class_t;
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/include/usb/classes/hid.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/classes/hid.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,59 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB HID device related types.
+ */
+#ifndef LIBUSB_HID_H_
+#define LIBUSB_HID_H_
+
+/** USB/HID device requests. */
+typedef enum {
+	USB_HIDREQ_GET_REPORT = 1,
+	USB_HIDREQ_GET_IDLE = 2,
+	USB_HIDREQ_GET_PROTOCOL = 3,
+	/* Values 4 to 8 are reserved. */
+	USB_HIDREQ_SET_REPORT = 9,
+	USB_HIDREQ_SET_IDLE = 10,
+	USB_HIDREQ_SET_PROTOCOL = 11
+} usb_hid_request_t;
+
+/** USB/HID interface protocols. */
+typedef enum {
+	USB_HID_PROTOCOL_NONE = 0,
+	USB_HID_PROTOCOL_KEYBOARD = 1,
+	USB_HID_PROTOCOL_MOUSE = 2
+} usb_hid_protocol_t;
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/include/usb/classes/hidut.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidut.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/classes/hidut.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,68 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB HID Usage Tables.
+ */
+#ifndef LIBUSB_HIDUT_H_
+#define LIBUSB_HIDUT_H_
+
+/** USB/HID Usage Pages. */
+typedef enum {
+	USB_HIDUT_PAGE_GENERIC_DESKTOP = 1,
+	USB_HIDUT_PAGE_SIMULATION = 2,
+	USB_HIDUT_PAGE_VR = 3,
+	USB_HIDUT_PAGE_SPORT = 4,
+	USB_HIDUT_PAGE_GAME = 5,
+	USB_HIDUT_PAGE_GENERIC_DEVICE = 6,
+	USB_HIDUT_PAGE_KEYBOARD = 7,
+	USB_HIDUT_PAGE_LED = 8,
+	USB_HIDUT_PAGE_BUTTON = 9
+	/* USB_HIDUT_PAGE_ = , */
+} usb_hidut_usage_page_t;
+
+/** Usages for Generic Desktop Page. */
+typedef enum {
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_POINTER = 1,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE = 2,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_JOYSTICK = 4,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_GAMEPAD = 5,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD = 6,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYPAD = 7
+	/* USB_HIDUT_USAGE_GENERIC_DESKTOP_ = , */
+	
+} usb_hidut_usage_generic_desktop_t;
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/include/usb/classes/hidutkbd.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidutkbd.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/classes/hidutkbd.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,175 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB HID key codes.
+ * @details
+ * This is not a typical header as by default it is equal to empty file.
+ * However, by cleverly defining the USB_HIDUT_KBD_KEY you can use it
+ * to generate conversion tables etc.
+ *
+ * For example, this creates enum for known keys:
+ * @code
+#define USB_HIDUT_KBD_KEY(name, usage_id, l, lc, l1, l2) \
+	USB_KBD_KEY_##name = usage_id,
+typedef enum {
+	#include <usb/hidutkbd.h>
+} usb_key_code_t;
+ @endcode
+ *
+ * Maybe, it might be better that you would place such enums into separate
+ * files and create them as separate step before compiling to allow tools
+ * such as Doxygen get the definitions right.
+ *
+ * @warning This file does not include guard to prevent multiple inclusions
+ * into a single file.
+ */
+
+
+#ifndef USB_HIDUT_KBD_KEY
+/** Declare keyboard key.
+ * @param name Key name (identifier).
+ * @param usage_id Key code (see Keyboard/Keypad Page (0x07) in HUT1.12.
+ * @param letter Corresponding character (0 if not applicable).
+ * @param letter_caps Corresponding character with Caps on.
+ * @param letter_mod1 Corresponding character with modifier #1 on.
+ * @param letter_mod2 Corresponding character with modifier #2 on.
+ */
+#define USB_HIDUT_KBD_KEY(name, usage_id, letter, letter_caps, letter_mod1, letter_mod2)
+
+#endif
+
+#define __NONPRINT(name, usage_id) \
+	USB_HIDUT_KBD_KEY(name, usage_id, 0, 0, 0, 0)
+
+/* US alphabet letters */
+USB_HIDUT_KBD_KEY(A, 0x04, 'a', 'A', 0, 0)
+USB_HIDUT_KBD_KEY(B, 0x05, 'b', 'B', 0, 0)
+USB_HIDUT_KBD_KEY(C, 0x06, 'c', 'C', 0, 0)
+USB_HIDUT_KBD_KEY(D, 0x07, 'd', 'D', 0, 0)
+USB_HIDUT_KBD_KEY(E, 0x08, 'e', 'E', 0, 0)
+USB_HIDUT_KBD_KEY(F, 0x09, 'f', 'F', 0, 0)
+USB_HIDUT_KBD_KEY(G, 0x0A, 'g', 'G', 0, 0)
+USB_HIDUT_KBD_KEY(H, 0x0B, 'h', 'H', 0, 0)
+USB_HIDUT_KBD_KEY(I, 0x0C, 'i', 'I', 0, 0)
+USB_HIDUT_KBD_KEY(J, 0x0D, 'j', 'J', 0, 0)
+USB_HIDUT_KBD_KEY(K, 0x0E, 'k', 'K', 0, 0)
+USB_HIDUT_KBD_KEY(L, 0x0F, 'l', 'L', 0, 0)
+USB_HIDUT_KBD_KEY(M, 0x10, 'm', 'M', 0, 0)
+USB_HIDUT_KBD_KEY(N, 0x11, 'n', 'N', 0, 0)
+USB_HIDUT_KBD_KEY(O, 0x12, 'o', 'O', 0, 0)
+USB_HIDUT_KBD_KEY(P, 0x13, 'p', 'P', 0, 0)
+USB_HIDUT_KBD_KEY(Q, 0x14, 'q', 'Q', 0, 0)
+USB_HIDUT_KBD_KEY(R, 0x15, 'r', 'R', 0, 0)
+USB_HIDUT_KBD_KEY(S, 0x16, 's', 'S', 0, 0)
+USB_HIDUT_KBD_KEY(T, 0x17, 't', 'T', 0, 0)
+USB_HIDUT_KBD_KEY(U, 0x18, 'u', 'U', 0, 0)
+USB_HIDUT_KBD_KEY(V, 0x19, 'v', 'V', 0, 0)
+USB_HIDUT_KBD_KEY(W, 0x1A, 'w', 'W', 0, 0)
+USB_HIDUT_KBD_KEY(X, 0x1B, 'x', 'X', 0, 0)
+USB_HIDUT_KBD_KEY(Y, 0x1C, 'y', 'Y', 0, 0)
+USB_HIDUT_KBD_KEY(Z, 0x1D, 'z', 'Z', 0, 0)
+
+/* Keyboard digits */
+USB_HIDUT_KBD_KEY(1, 0x1E, '1', '!', 0, 0)
+USB_HIDUT_KBD_KEY(2, 0x1F, '2', '@', 0, 0)
+USB_HIDUT_KBD_KEY(3, 0x20, '3', '#', 0, 0)
+USB_HIDUT_KBD_KEY(4, 0x21, '4', '$', 0, 0)
+USB_HIDUT_KBD_KEY(5, 0x22, '5', '%', 0, 0)
+USB_HIDUT_KBD_KEY(6, 0x23, '6', '^', 0, 0)
+USB_HIDUT_KBD_KEY(7, 0x24, '7', '&', 0, 0)
+USB_HIDUT_KBD_KEY(8, 0x25, '8', '*', 0, 0)
+USB_HIDUT_KBD_KEY(9, 0x26, '9', '(', 0, 0)
+USB_HIDUT_KBD_KEY(0, 0x27, '0', ')', 0, 0)
+
+/* More-or-less typewriter command keys */
+USB_HIDUT_KBD_KEY(ENTER, 0x28, '\n', 0, 0, 0)
+USB_HIDUT_KBD_KEY(ESCAPE, 0x29, 0, 0, 0, 0)
+USB_HIDUT_KBD_KEY(BACKSPACE, 0x2A, '\b', 0, 0, 0)
+USB_HIDUT_KBD_KEY(TAB, 0x2B, '\t', 0, 0, 0)
+USB_HIDUT_KBD_KEY(SPACE, 0x2C, ' ', 0, 0, 0)
+
+/* Special (printable) characters */
+USB_HIDUT_KBD_KEY(DASH, 0x2D, '-', '_', 0, 0)
+USB_HIDUT_KBD_KEY(EQUALS, 0x2E, '=', '+', 0, 0)
+USB_HIDUT_KBD_KEY(LEFT_BRACKET, 0x2F, '[', '{', 0, 0)
+USB_HIDUT_KBD_KEY(RIGHT_BRACKET, 0x30, ']', '}', 0, 0)
+USB_HIDUT_KBD_KEY(BACKSLASH, 0x31, '\\', '|', 0, 0)
+USB_HIDUT_KBD_KEY(HASH, 0x32, '#', '~', 0, 0)
+USB_HIDUT_KBD_KEY(SEMICOLON, 0x33, ';', ':', 0, 0)
+USB_HIDUT_KBD_KEY(APOSTROPHE, 0x34, '\'', '"', 0, 0)
+USB_HIDUT_KBD_KEY(GRAVE_ACCENT, 0x35, '`', '~', 0, 0)
+USB_HIDUT_KBD_KEY(COMMA, 0x36, ',', '<', 0, 0)
+USB_HIDUT_KBD_KEY(PERIOD, 0x37, '.', '>', 0, 0)
+USB_HIDUT_KBD_KEY(SLASH, 0x38, '/', '?', 0, 0)
+
+USB_HIDUT_KBD_KEY(CAPS_LOCK, 0x39, 0, 0, 0, 0)
+
+/* Function keys */
+__NONPRINT( F1, 0x3A)
+__NONPRINT( F2, 0x3B)
+__NONPRINT( F3, 0x3C)
+__NONPRINT( F4, 0x3D)
+__NONPRINT( F5, 0x3E)
+__NONPRINT( F6, 0x3F)
+__NONPRINT( F7, 0x40)
+__NONPRINT( F8, 0x41)
+__NONPRINT( F9, 0x42)
+__NONPRINT(F10, 0x43)
+__NONPRINT(F11, 0x44)
+__NONPRINT(F12, 0x45)
+
+/* Cursor movement keys & co. */
+__NONPRINT(PRINT_SCREEN, 0x46)
+__NONPRINT(SCROLL_LOCK, 0x47)
+__NONPRINT(PAUSE, 0x48)
+__NONPRINT(INSERT, 0x49)
+__NONPRINT(HOME, 0x4A)
+__NONPRINT(PAGE_UP, 0x4B)
+__NONPRINT(DELETE, 0x4C)
+__NONPRINT(END, 0x4D)
+__NONPRINT(PAGE_DOWN, 0x4E)
+__NONPRINT(RIGHT_ARROW, 0x4F)
+__NONPRINT(LEFT_ARROW, 0x50)
+__NONPRINT(DOWN_ARROW, 0x51)
+__NONPRINT(UP_ARROW, 0x52)
+
+
+
+
+/* USB_HIDUT_KBD_KEY(, 0x, '', '', 0, 0) */
+
+#undef __NONPRINT
+
+/**
+ * @}
+ */
+
Index: uspace/lib/usb/include/usb/classes/hub.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hub.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/classes/hub.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,224 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB hub related structures.
+ */
+#ifndef LIBUSB_HUB_H_
+#define LIBUSB_HUB_H_
+
+#include <sys/types.h>
+
+
+/** Hub class feature selector.
+ * @warning The constants are not unique (feature selectors are used
+ * for hub and port).
+ */
+typedef enum {
+	USB_HUB_FEATURE_C_HUB_LOCAL_POWER = 0,
+	USB_HUB_FEATURE_C_HUB_OVER_CURRENT = 1,
+	USB_HUB_FEATURE_PORT_CONNECTION = 0,
+	USB_HUB_FEATURE_PORT_ENABLE = 1,
+	USB_HUB_FEATURE_PORT_SUSPEND = 2,
+	USB_HUB_FEATURE_PORT_OVER_CURRENT = 3,
+	USB_HUB_FEATURE_PORT_RESET = 4,
+	USB_HUB_FEATURE_PORT_POWER = 8,
+	USB_HUB_FEATURE_PORT_LOW_SPEED = 9,
+	USB_HUB_FEATURE_C_PORT_CONNECTION = 16,
+	USB_HUB_FEATURE_C_PORT_ENABLE = 17,
+	USB_HUB_FEATURE_C_PORT_SUSPEND = 18,
+	USB_HUB_FEATURE_C_PORT_OVER_CURRENT = 19,
+	USB_HUB_FEATURE_C_PORT_RESET = 20,
+	/* USB_HUB_FEATURE_ = , */
+} usb_hub_class_feature_t;
+
+
+/**
+ *	@brief usb hub descriptor
+ *
+ *	For more information see Universal Serial Bus Specification Revision 1.1 chapter 11.16.2
+ */
+typedef struct hub_descriptor_type{
+    /** Number of bytes in this descriptor, including this byte */
+    //uint8_t bDescLength;
+
+    /** Descriptor Type, value: 29H for hub descriptor */
+    //uint8_t bDescriptorType;
+
+    /** Number of downstream ports that this hub supports */
+    uint8_t ports_count;
+
+    /**
+            D1...D0: Logical Power Switching Mode
+            00: Ganged power switching (all ports’ power at
+            once)
+            01: Individual port power switching
+            1X: Reserved. Used only on 1.0 compliant hubs
+            that implement no power switching.
+            D2: Identifies a Compound Device
+            0: Hub is not part of a compound device
+            1: Hub is part of a compound device
+            D4...D3: Over-current Protection Mode
+            00: Global Over-current Protection. The hub
+            reports over-current as a summation of all
+            ports’ current draw, without a breakdown of
+            individual port over-current status.
+            01: Individual Port Over-current Protection. The
+            hub reports over-current on a per-port basis.
+            Each port has an over-current indicator.
+            1X: No Over-current Protection. This option is
+            allowed only for bus-powered hubs that do not
+            implement over-current protection.
+            D15...D5:
+            Reserved
+     */
+    uint16_t hub_characteristics;
+
+    /**
+            Time (in 2ms intervals) from the time the power-on
+            sequence begins on a port until power is good on that
+            port. The USB System Software uses this value to
+            determine how long to wait before accessing a
+            powered-on port.
+     */
+    uint8_t pwr_on_2_good_time;
+
+    /**
+            Maximum current requirements of the Hub Controller
+            electronics in mA.
+     */
+    uint8_t current_requirement;
+
+    /**
+            Indicates if a port has a removable device attached.
+            This field is reported on byte-granularity. Within a
+            byte, if no port exists for a given location, the field
+            representing the port characteristics returns 0.
+            Bit value definition:
+            0B - Device is removable
+            1B - Device is non-removable
+            This is a bitmap corresponding to the individual ports
+            on the hub:
+            Bit 0: Reserved for future use
+            Bit 1: Port 1
+            Bit 2: Port 2
+            ....
+            Bit n: Port n (implementation-dependent, up to a
+            maximum of 255 ports).
+     */
+    uint8_t * devices_removable;
+
+    /**
+            This field exists for reasons of compatibility with
+            software written for 1.0 compliant devices. All bits in
+            this field should be set to 1B. This field has one bit for
+            each port on the hub with additional pad bits, if
+            necessary, to make the number of bits in the field an
+            integer multiple of 8.
+     */
+    //uint8_t * port_pwr_ctrl_mask;
+} usb_hub_descriptor_t;
+
+/**
+ *	Maximum size of usb hub descriptor in bytes
+ */
+extern size_t USB_HUB_MAX_DESCRIPTOR_SIZE;
+
+/**
+ *	hub descriptor type
+ */
+extern uint8_t USB_HUB_DESCRIPTOR_TYPE;
+
+/**
+ * @brief create uint8_t array with serialized descriptor
+ *
+ * @param descriptor
+ */
+void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor);
+
+/**
+ * @brief create deserialized desriptor structure out of serialized descriptor
+ *
+ * The serialized descriptor must be proper usb hub descriptor, otherwise an eerror might occur.
+ *
+ * @param sdescriptor serialized descriptor
+ */
+usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * sdescriptor);
+
+/**	@brief usb hub specific request types.
+ *
+ *	For more information see Universal Serial Bus Specification Revision 1.1 chapter 11.16.2
+ */
+typedef enum {
+    /**	This request resets a value reported in the hub status.	*/
+    USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE = 0x20,
+    /** This request resets a value reported in the port status. */
+    USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE = 0x23,
+    /** This is an optional per-port diagnostic request that returns the bus state value, as sampled at the last EOF2 point. */
+    USB_HUB_REQ_TYPE_GET_STATE = 0xA3,
+    /** This request returns the hub descriptor. */
+    USB_HUB_REQ_TYPE_GET_DESCRIPTOR = 0xA0,
+    /** This request returns the current hub status and the states that have changed since the previous acknowledgment. */
+    USB_HUB_REQ_TYPE_GET_HUB_STATUS = 0xA0,
+    /** This request returns the current port status and the current value of the port status change bits. */
+    USB_HUB_REQ_TYPE_GET_PORT_STATUS = 0xA3,
+    /** This request overwrites the hub descriptor. */
+    USB_HUB_REQ_TYPE_SET_DESCRIPTOR = 0x20,
+    /** This request sets a value reported in the hub status. */
+    USB_HUB_REQ_TYPE_SET_HUB_FEATURE = 0x20,
+    /** This request sets a value reported in the port status. */
+    USB_HUB_REQ_TYPE_SET_PORT_FEATURE = 0x23
+} usb_hub_bm_request_type_t;
+
+/** @brief hub class request codes*/
+typedef enum {
+    /**  */
+    USB_HUB_REQUEST_GET_STATUS = 0,
+    /** */
+    USB_HUB_REQUEST_CLEAR_FEATURE = 1,
+    /** */
+    USB_HUB_REQUEST_GET_STATE = 2,
+    /** */
+    USB_HUB_REQUEST_SET_FEATURE = 3,
+    /** */
+    USB_HUB_REQUEST_GET_DESCRIPTOR = 6,
+    /** */
+    USB_HUB_REQUEST_SET_DESCRIPTOR = 7
+} usb_hub_request_t;
+
+
+
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/include/usb/descriptor.h
===================================================================
--- uspace/lib/usb/include/usb/descriptor.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/descriptor.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,176 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Standard USB descriptors.
+ */
+#ifndef LIBUSB_DESCRIPTOR_H_
+#define LIBUSB_DESCRIPTOR_H_
+
+#include <ipc/ipc.h>
+#include <async.h>
+
+/** Descriptor type. */
+typedef enum {
+	USB_DESCTYPE_DEVICE = 1,
+	USB_DESCTYPE_CONFIGURATION = 2,
+	USB_DESCTYPE_STRING = 3,
+	USB_DESCTYPE_INTERFACE = 4,
+	USB_DESCTYPE_ENDPOINT = 5,
+	USB_DESCTYPE_HID = 0x21,
+	USB_DESCTYPE_HID_REPORT = 0x22,
+	USB_DESCTYPE_HID_PHYSICAL = 0x23,
+	USB_DESCTYPE_HUB = 0x29,
+	/* USB_DESCTYPE_ = */
+} usb_descriptor_type_t;
+
+/** Standard USB device descriptor.
+ */
+typedef struct {
+	/** Size of this descriptor in bytes. */
+	uint8_t length;
+	/** Descriptor type (USB_DESCTYPE_DEVICE). */
+	uint8_t descriptor_type;
+	/** USB specification release number.
+	 * The number shall be coded as binary-coded decimal (BCD).
+	 */
+	uint16_t usb_spec_version;
+	/** Device class. */
+	uint8_t device_class;
+	/** Device sub-class. */
+	uint8_t device_subclass;
+	/** Device protocol. */
+	uint8_t device_protocol;
+	/** Maximum packet size for endpoint zero.
+	 * Valid values are only 8, 16, 32, 64).
+	 */
+	uint8_t max_packet_size;
+	/** Vendor ID. */
+	uint16_t vendor_id;
+	/** Product ID. */
+	uint16_t product_id;
+	/** Device release number (in BCD). */
+	uint16_t device_version;
+	/** Manufacturer descriptor index. */
+	uint8_t str_manufacturer;
+	/** Product descriptor index. */
+	uint8_t str_product;
+	/** Device serial number desriptor index. */
+	uint8_t str_serial_number;
+	/** Number of possible configurations. */
+	uint8_t configuration_count;
+} __attribute__ ((packed)) usb_standard_device_descriptor_t;
+
+/** Standard USB configuration descriptor.
+ */
+typedef struct {
+	/** Size of this descriptor in bytes. */
+	uint8_t length;
+	/** Descriptor type (USB_DESCTYPE_CONFIGURATION). */
+	uint8_t descriptor_type;
+	/** Total length of all data of this configuration.
+	 * This includes the combined length of all descriptors
+	 * (configuration, interface, endpoint, class-specific and
+	 * vendor-specific) valid for this configuration.
+	 */
+	uint16_t total_length;
+	/** Number of possible interfaces under this configuration. */
+	uint8_t interface_count;
+	/** Configuration value used when setting this configuration. */
+	uint8_t configuration_number;
+	/** String descriptor describing this configuration. */
+	uint8_t str_configuration;
+	/** Attribute bitmap. */
+	uint8_t attributes;
+	/** Maximum power consumption from the USB under this configuration.
+	 * Expressed in 2mA unit (e.g. 50 ~ 100mA).
+	 */
+	uint8_t max_power;
+} __attribute__ ((packed)) usb_standard_configuration_descriptor_t;
+
+/** Standard USB interface descriptor.
+ */
+typedef struct {
+	/** Size of this descriptor in bytes. */
+	uint8_t length;
+	/** Descriptor type (USB_DESCTYPE_INTERFACE). */
+	uint8_t descriptor_type;
+	/** Number of interface.
+	 * Zero-based index into array of interfaces for current configuration.
+	 */
+	uint8_t interface_number;
+	/** Alternate setting for value in interface_number. */
+	uint8_t alternate_setting;
+	/** Number of endpoints used by this interface.
+	 * This number must exclude usage of endpoint zero
+	 * (default control pipe).
+	 */
+	uint8_t endpoint_count;
+	/** Class code. */
+	uint8_t interface_class;
+	/** Subclass code. */
+	uint8_t interface_subclass;
+	/** Protocol code. */
+	uint8_t interface_protocol;
+	/** String descriptor describing this interface. */
+	uint8_t str_interface;
+} __attribute__ ((packed)) usb_standard_interface_descriptor_t;
+
+/** Standard USB endpoint descriptor.
+ */
+typedef struct {
+	/** Size of this descriptor in bytes. */
+	uint8_t length;
+	/** Descriptor type (USB_DESCTYPE_ENDPOINT). */
+	uint8_t descriptor_type;
+	/** Endpoint address together with data flow direction. */
+	uint8_t endpoint_address;
+	/** Endpoint attributes.
+	 * Includes transfer type (usb_transfer_type_t).
+	 */
+	uint8_t attributes;
+	/** Maximum packet size. */
+	uint16_t max_packet_size;
+	/** Polling interval in milliseconds.
+	 * Ignored for bulk and control endpoints.
+	 * Isochronous endpoints must use value 1.
+	 * Interrupt endpoints any value from 1 to 255.
+	 */
+	uint8_t poll_interval;
+} __attribute__ ((packed)) usb_standard_endpoint_descriptor_t;
+
+
+/* TODO: string descriptors. */
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/include/usb/devreq.h
===================================================================
--- uspace/lib/usb/include/usb/devreq.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/devreq.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,88 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Standard USB device requests.
+ */
+#ifndef LIBUSB_DEVREQ_H_
+#define LIBUSB_DEVREQ_H_
+
+#include <ipc/ipc.h>
+#include <async.h>
+
+/** Standard device request. */
+typedef enum {
+	USB_DEVREQ_GET_STATUS = 0,
+	USB_DEVREQ_CLEAR_FEATURE = 1,
+	USB_DEVREQ_SET_FEATURE = 3,
+	USB_DEVREQ_SET_ADDRESS = 5,
+	USB_DEVREQ_GET_DESCRIPTOR = 6,
+	USB_DEVREQ_SET_DESCRIPTOR = 7,
+	USB_DEVREQ_GET_CONFIGURATION = 8,
+	USB_DEVREQ_SET_CONFIGURATION = 9,
+	USB_DEVREQ_GET_INTERFACE = 10,
+	USB_DEVREQ_SET_INTERFACE = 11,
+	USB_DEVREQ_SYNCH_FRAME = 12,
+	USB_DEVREQ_LAST_STD
+} usb_stddevreq_t;
+
+/** Device request setup packet.
+ * The setup packet describes the request.
+ */
+typedef struct {
+	/** Request type.
+	 * The type combines transfer direction, request type and
+	 * intended recipient.
+	 */
+	uint8_t request_type;
+	/** Request identification. */
+	uint8_t request;
+	/** Main parameter to the request. */
+	union {
+		/* FIXME: add #ifdefs according to host endianess */
+		struct {
+			uint8_t value_low;
+			uint8_t value_high;
+		};
+		uint16_t value;
+	};
+	/** Auxiliary parameter to the request.
+	 * Typically, it is offset to something.
+	 */
+	uint16_t index;
+	/** Length of extra data. */
+	uint16_t length;
+} __attribute__ ((packed)) usb_device_request_setup_packet_t;
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/include/usb/hcdhubd.h
===================================================================
--- uspace/lib/usb/include/usb/hcdhubd.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/hcdhubd.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,178 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief HC driver and hub driver.
+ */
+#ifndef LIBUSB_HCDHUBD_H_
+#define LIBUSB_HCDHUBD_H_
+
+#include <adt/list.h>
+#include <driver.h>
+#include <usb/usb.h>
+
+/** Endpoint properties. */
+typedef struct {
+	/** Endpoint number. */
+	usb_endpoint_t endpoint;
+	/** Transfer type. */
+	usb_transfer_type_t transfer_type;
+	/** Endpoint direction. */
+	usb_direction_t direction;
+	/** Data toggle bit. */
+	int data_toggle;
+} usb_hc_endpoint_info_t;
+
+/** Information about attached USB device. */
+typedef struct {
+	/** Assigned address. */
+	usb_address_t address;
+	/** Number of endpoints. */
+	size_t endpoint_count;
+	/** Endpoint properties. */
+	usb_hc_endpoint_info_t *endpoints;
+	/** Link to other attached devices of the same HC. */
+	link_t link;
+} usb_hcd_attached_device_info_t;
+
+/** Information about attached hub. */
+typedef struct {
+	/** Number of ports. */
+	size_t port_count;
+	/** General device info. */
+	usb_hcd_attached_device_info_t *device;
+	/** Link to other hubs. */
+	link_t link;
+} usb_hcd_hub_info_t;
+
+/** Host controller device. */
+typedef struct usb_hc_device usb_hc_device_t;
+
+/** Callback for OUT transfers. */
+typedef void (*usb_hcd_transfer_callback_out_t)
+    (usb_hc_device_t *, usb_transaction_outcome_t, void *);
+
+/** Callback for IN transfers. */
+typedef void (*usb_hcd_transfer_callback_in_t)
+    (usb_hc_device_t *, size_t, usb_transaction_outcome_t, void *);
+
+
+/** Transfer functions provided by each USB host controller driver. */
+typedef struct {
+	/** OUT transfer.
+	 * @param hc Host controller that shall enqueue the transfer.
+	 * @param dev Target device.
+	 * @param ep Target endpoint.
+	 * @param buffer Buffer to be sent.
+	 * @param size Buffer size.
+	 * @param callback Callback after transfer was processed by hardware.
+	 * @param arg Callback argument.
+	 */
+	int (*transfer_out)(usb_hc_device_t *hc,
+	    usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *ep,
+	    void *buffer, size_t size,
+	    usb_hcd_transfer_callback_out_t callback, void *arg);
+
+	/** SETUP transfer. */
+	int (*transfer_setup)(usb_hc_device_t *,
+	    usb_hcd_attached_device_info_t *, usb_hc_endpoint_info_t *,
+	    void *, size_t,
+	    usb_hcd_transfer_callback_out_t, void *);
+
+	/** IN transfer. */
+	int (*transfer_in)(usb_hc_device_t *,
+	    usb_hcd_attached_device_info_t *, usb_hc_endpoint_info_t *,
+	    void *, size_t,
+	    usb_hcd_transfer_callback_in_t, void *);
+} usb_hcd_transfer_ops_t;
+
+struct usb_hc_device {
+	/** Transfer operations. */
+	usb_hcd_transfer_ops_t *transfer_ops;
+
+	/** Custom HC data. */
+	void *data;
+
+	/** Generic device entry (read-only). */
+	device_t *generic;
+
+	/** List of attached devices. */
+	link_t attached_devices;
+
+	/** List of hubs operating from this HC. */
+	link_t hubs;
+
+	/** Link to other driven HCs. */
+	link_t link;
+};
+
+/** Host controller driver. */
+typedef struct {
+	/** Driver name. */
+	const char *name;
+	/** Callback when device (host controller) is added. */
+	int (*add_hc)(usb_hc_device_t *device);
+} usb_hc_driver_t;
+
+
+int usb_hcd_main(usb_hc_driver_t *);
+int usb_hcd_add_root_hub(usb_hc_device_t *dev);
+
+
+/*
+ * Functions to be used by drivers within same task as the HC driver.
+ * This will probably include only hub drivers.
+ */
+
+
+int usb_hc_async_interrupt_out(usb_hc_device_t *, usb_target_t,
+    void *, size_t, usb_handle_t *);
+int usb_hc_async_interrupt_in(usb_hc_device_t *, usb_target_t,
+    void *, size_t, size_t *, usb_handle_t *);
+
+int usb_hc_async_control_write_setup(usb_hc_device_t *, usb_target_t,
+    void *, size_t, usb_handle_t *);
+int usb_hc_async_control_write_data(usb_hc_device_t *, usb_target_t,
+    void *, size_t, usb_handle_t *);
+int usb_hc_async_control_write_status(usb_hc_device_t *, usb_target_t,
+    usb_handle_t *);
+
+int usb_hc_async_control_read_setup(usb_hc_device_t *, usb_target_t,
+    void *, size_t, usb_handle_t *);
+int usb_hc_async_control_read_data(usb_hc_device_t *, usb_target_t,
+    void *, size_t, size_t *, usb_handle_t *);
+int usb_hc_async_control_read_status(usb_hc_device_t *, usb_target_t,
+    usb_handle_t *);
+
+int usb_hc_async_wait_for(usb_handle_t);
+
+
+#endif
Index: uspace/lib/usb/include/usb/usb.h
===================================================================
--- uspace/lib/usb/include/usb/usb.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/usb.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,130 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Base USB types.
+ */
+#ifndef LIBUSB_USB_H_
+#define LIBUSB_USB_H_
+
+#include <sys/types.h>
+#include <ipc/ipc.h>
+
+/** USB transfer type. */
+typedef enum {
+	USB_TRANSFER_CONTROL = 0,
+	USB_TRANSFER_ISOCHRONOUS = 1,
+	USB_TRANSFER_BULK = 2,
+	USB_TRANSFER_INTERRUPT = 3
+} usb_transfer_type_t;
+
+const char * usb_str_transfer_type(usb_transfer_type_t t);
+
+/** USB data transfer direction. */
+typedef enum {
+	USB_DIRECTION_IN,
+	USB_DIRECTION_OUT
+} usb_direction_t;
+
+/** USB transaction outcome. */
+typedef enum {
+	USB_OUTCOME_OK,
+	USB_OUTCOME_CRCERROR,
+	USB_OUTCOME_BABBLE
+} usb_transaction_outcome_t;
+
+const char * usb_str_transaction_outcome(usb_transaction_outcome_t o);
+
+/** USB address type.
+ * Negative values could be used to indicate error.
+ */
+typedef int usb_address_t;
+
+/** USB endpoint number type.
+ * Negative values could be used to indicate error.
+ */
+typedef int usb_endpoint_t;
+
+/** Maximum endpoint number in USB 1.1.
+ */
+#define USB11_ENDPOINT_MAX 16
+
+
+/** USB complete address type. 
+ * Pair address + endpoint is identification of transaction recipient.
+ */
+typedef struct {
+	usb_address_t address;
+	usb_endpoint_t endpoint;
+} usb_target_t;
+
+static inline int usb_target_same(usb_target_t a, usb_target_t b)
+{
+	return (a.address == b.address)
+	    && (a.endpoint == b.endpoint);
+}
+
+/** General handle type.
+ * Used by various USB functions as opaque handle.
+ */
+typedef ipcarg_t usb_handle_t;
+
+/** USB packet identifier. */
+typedef enum {
+#define _MAKE_PID_NIBBLE(tag, type) \
+	((uint8_t)(((tag) << 2) | (type)))
+#define _MAKE_PID(tag, type) \
+	( \
+	    _MAKE_PID_NIBBLE(tag, type) \
+	    | ((~_MAKE_PID_NIBBLE(tag, type)) << 4) \
+	)
+	USB_PID_OUT = _MAKE_PID(0, 1),
+	USB_PID_IN = _MAKE_PID(2, 1),
+	USB_PID_SOF = _MAKE_PID(1, 1),
+	USB_PID_SETUP = _MAKE_PID(3, 1),
+
+	USB_PID_DATA0 = _MAKE_PID(0 ,3),
+	USB_PID_DATA1 = _MAKE_PID(2 ,3),
+
+	USB_PID_ACK = _MAKE_PID(0 ,2),
+	USB_PID_NAK = _MAKE_PID(2 ,2),
+	USB_PID_STALL = _MAKE_PID(3 ,2),
+
+	USB_PID_PRE = _MAKE_PID(3 ,0),
+	/* USB_PID_ = _MAKE_PID( ,), */
+#undef _MAKE_PID
+#undef _MAKE_PID_NIBBLE
+} usb_packet_id;
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/include/usb/usbdrv.h
===================================================================
--- uspace/lib/usb/include/usb/usbdrv.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/include/usb/usbdrv.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,55 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB driver.
+ */
+#ifndef LIBUSB_USBDRV_H_
+#define LIBUSB_USBDRV_H_
+
+#include "usb.h"
+#include <driver.h>
+
+int usb_drv_hc_connect(device_t *, unsigned int);
+
+usb_address_t usb_drv_get_my_address(int, device_t *);
+
+int usb_drv_async_interrupt_out(int, usb_target_t,
+    void *, size_t, usb_handle_t *);
+int usb_drv_async_interrupt_in(int, usb_target_t,
+    void *, size_t, size_t *, usb_handle_t *);
+
+int usb_drv_async_wait_for(usb_handle_t);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/src/hcdhubd.c
===================================================================
--- uspace/lib/usb/src/hcdhubd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/src/hcdhubd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,395 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief HC driver and hub driver (implementation).
+ */
+#include <usb/hcdhubd.h>
+#include <usb/devreq.h>
+#include <usbhc_iface.h>
+#include <driver.h>
+#include <bool.h>
+#include <errno.h>
+#include <usb/classes/hub.h>
+
+#define USB_HUB_DEVICE_NAME "usbhub"
+
+/** List of handled host controllers. */
+static LIST_INITIALIZE(hc_list);
+
+/** Our HC driver. */
+static usb_hc_driver_t *hc_driver = NULL;
+
+static usbhc_iface_t usb_interface = {
+	.interrupt_out = NULL,
+	.interrupt_in = NULL
+};
+
+static device_ops_t usb_device_ops = {
+	.interfaces[USBHC_DEV_IFACE] = &usb_interface
+};
+
+size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71;
+
+uint8_t USB_HUB_DESCRIPTOR_TYPE = 0x29;
+
+//*********************************************
+//
+//  various utils
+//
+//*********************************************
+
+
+void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor){
+	//base size
+	size_t size = 7;
+	//variable size according to port count
+	size_t var_size = descriptor->ports_count / 8 + ((descriptor->ports_count % 8>0)?1:0);
+	size += 2 * var_size;
+	uint8_t * result = (uint8_t*) malloc(size);
+	//size
+	result[0]=size;
+	//descriptor type
+	result[1]=USB_HUB_DESCRIPTOR_TYPE;
+	result[2]=descriptor->ports_count;
+	/// @fixme handling of endianness??
+	result[3]=descriptor->hub_characteristics / 256;
+	result[4]=descriptor->hub_characteristics % 256;
+	result[5]=descriptor->pwr_on_2_good_time;
+	result[6]=descriptor->current_requirement;
+
+        size_t i;
+	for(i=0;i<var_size;++i){
+		result[7+i]=descriptor->devices_removable[i];
+	}
+	for(i=0;i<var_size;++i){
+		result[7+var_size+i]=255;
+	}
+	return result;
+}
+
+usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor){
+        uint8_t * sdescriptor = (uint8_t*)serialized_descriptor;
+	if(sdescriptor[1]!=USB_HUB_DESCRIPTOR_TYPE) return NULL;
+	usb_hub_descriptor_t * result = (usb_hub_descriptor_t*) malloc(sizeof(usb_hub_descriptor_t));
+	//uint8_t size = sdescriptor[0];
+	result->ports_count = sdescriptor[2];
+	/// @fixme handling of endianness??
+	result->hub_characteristics = sdescriptor[4] + 256 * sdescriptor[3];
+	result->pwr_on_2_good_time=sdescriptor[5];
+	result->current_requirement=sdescriptor[6];
+	size_t var_size = result->ports_count / 8 + ((result->ports_count % 8>0)?1:0);
+	result->devices_removable = (uint8_t*)malloc(var_size);
+
+        size_t i;
+	for(i=0;i<var_size;++i){
+		result->devices_removable[i] = sdescriptor[7+i];
+	}
+	return result;
+}
+
+
+//*********************************************
+//
+//  hub driver code
+//
+//*********************************************
+
+
+
+static void set_hub_address(usb_hc_device_t *hc, usb_address_t address);
+
+/** Callback when new device is detected and must be handled by this driver.
+ *
+ * @param dev New device.
+ * @return Error code.hub added, hurrah!\n"
+ */
+static int add_device(device_t *dev)
+{
+	/*
+	 * FIXME: use some magic to determine whether hub or another HC
+	 * was connected.
+	 */
+	bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0;
+	printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name);
+
+	if (is_hc) {
+		/*
+		 * We are the HC itself.
+		 */
+		usb_hc_device_t *hc_dev = malloc(sizeof(usb_hc_device_t));
+		list_initialize(&hc_dev->link);
+		hc_dev->transfer_ops = NULL;
+
+		hc_dev->generic = dev;
+		dev->ops = &usb_device_ops;
+		hc_dev->generic->driver_data = hc_dev;
+
+		int rc = hc_driver->add_hc(hc_dev);
+		if (rc != EOK) {
+			free(hc_dev);
+			return rc;
+		}
+
+		/*
+		 * FIXME: The following line causes devman to hang.
+		 * Will investigate later why.
+		 */
+		// add_device_to_class(dev, "usbhc");
+
+		list_append(&hc_dev->link, &hc_list);
+
+		return EOK;
+	} else {
+		usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
+		set_hub_address(hc, 5);
+
+		/*
+		 * We are some (probably deeply nested) hub.
+		 * Thus, assign our own operations and explore already
+		 * connected devices.
+		 */
+                //insert hub into list
+                //find owner hcd
+                device_t * my_hcd = dev;
+                while(my_hcd->parent)
+                    my_hcd = my_hcd->parent;
+                //dev->
+                printf("%s: owner hcd found: %s\n",hc_driver->name, my_hcd->name);
+
+
+		return ENOTSUP;
+	}
+}
+
+/** Sample usage of usb_hc_async functions.
+ * This function sets hub address using standard SET_ADDRESS request.
+ *
+ * @warning This function shall be removed once you are familiar with
+ * the usb_hc_ API.
+ *
+ * @param hc Host controller the hub belongs to.
+ * @param address New hub address.
+ */
+static void set_hub_address(usb_hc_device_t *hc, usb_address_t address)
+{
+	printf("%s: setting hub address to %d\n", hc->generic->name, address);
+	usb_target_t target = {0, 0};
+	usb_handle_t handle;
+	int rc;
+
+	usb_device_request_setup_packet_t setup_packet = {
+		.request_type = 0,
+		.request = USB_DEVREQ_SET_ADDRESS,
+		.index = 0,
+		.length = 0,
+	};
+	setup_packet.value = address;
+
+	rc = usb_hc_async_control_write_setup(hc, target,
+	    &setup_packet, sizeof(setup_packet), &handle);
+	if (rc != EOK) {
+		return;
+	}
+
+	rc = usb_hc_async_wait_for(handle);
+	if (rc != EOK) {
+		return;
+	}
+
+	rc = usb_hc_async_control_write_status(hc, target, &handle);
+	if (rc != EOK) {
+		return;
+	}
+
+	rc = usb_hc_async_wait_for(handle);
+	if (rc != EOK) {
+		return;
+	}
+
+	printf("%s: hub address changed\n", hc->generic->name);
+}
+
+/** Check changes on all known hubs.
+ */
+static void check_hub_changes(void)
+{
+	/*
+	 * Iterate through all HCs.
+	 */
+	link_t *link_hc;
+	for (link_hc = hc_list.next;
+	    link_hc != &hc_list;
+	    link_hc = link_hc->next) {
+		usb_hc_device_t *hc = list_get_instance(link_hc,
+		    usb_hc_device_t, link);
+		/*
+		 * Iterate through all their hubs.
+		 */
+		link_t *link_hub;
+		for (link_hub = hc->hubs.next;
+		    link_hub != &hc->hubs;
+		    link_hub = link_hub->next) {
+			usb_hcd_hub_info_t *hub = list_get_instance(link_hub,
+			    usb_hcd_hub_info_t, link);
+
+			/*
+			 * Check status change pipe of this hub.
+			 */
+			usb_target_t target = {
+				.address = hub->device->address,
+				.endpoint = 1
+			};
+
+			// FIXME: count properly
+			size_t byte_length = (hub->port_count / 8) + 1;
+
+			void *change_bitmap = malloc(byte_length);
+			size_t actual_size;
+			usb_handle_t handle;
+
+			/*
+			 * Send the request.
+			 * FIXME: check returned value for possible errors
+			 */
+			usb_hc_async_interrupt_in(hc, target,
+			    change_bitmap, byte_length, &actual_size,
+			    &handle);
+
+			usb_hc_async_wait_for(handle);
+
+			/*
+			 * TODO: handle the changes.
+			 */
+		}
+	}
+}
+
+/** Operations for combined HC and HUB driver. */
+static driver_ops_t hc_driver_generic_ops = {
+	.add_device = add_device
+};
+
+/** Combined HC and HUB driver. */
+static driver_t hc_driver_generic = {
+	.driver_ops = &hc_driver_generic_ops
+};
+
+/** Main USB host controller driver routine.
+ *
+ * @see driver_main
+ *
+ * @param hc Host controller driver.
+ * @return Error code.
+ */
+int usb_hcd_main(usb_hc_driver_t *hc)
+{
+	hc_driver = hc;
+	hc_driver_generic.name = hc->name;
+
+	/*
+	 * Launch here fibril that will periodically check all
+	 * attached hubs for status change.
+	 * WARN: This call will effectively do nothing.
+	 */
+	check_hub_changes();
+
+	/*
+	 * Run the device driver framework.
+	 */
+	return driver_main(&hc_driver_generic);
+}
+
+/** Add a root hub for given host controller.
+ * This function shall be called only once for each host controller driven
+ * by this driver.
+ * It takes care of creating child device - hub - that will be driven by
+ * this task.
+ *
+ * @param dev Host controller device.
+ * @return Error code.
+ */
+int usb_hcd_add_root_hub(usb_hc_device_t *dev)
+{
+	int rc;
+
+	/*
+	 * Announce presence of child device.
+	 */
+	device_t *hub = NULL;
+	match_id_t *match_id = NULL;
+
+	hub = create_device();
+	if (hub == NULL) {
+		rc = ENOMEM;
+		goto failure;
+	}
+	hub->name = USB_HUB_DEVICE_NAME;
+
+	match_id = create_match_id();
+	if (match_id == NULL) {
+		rc = ENOMEM;
+		goto failure;
+	}
+
+	char *id;
+	rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name);
+	if (rc <= 0) {
+		rc = ENOMEM;
+		goto failure;
+	}
+
+	match_id->id = id;
+	match_id->score = 30;
+
+	add_match_id(&hub->match_ids, match_id);
+
+	rc = child_device_register(hub, dev->generic);
+	if (rc != EOK) {
+		goto failure;
+	}
+
+	printf("%s: registered root hub\n", dev->generic->name);
+	return EOK;
+
+failure:
+	if (hub != NULL) {
+		hub->name = NULL;
+		delete_device(hub);
+	}
+	delete_match_id(match_id);
+
+	return rc;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usb/src/localdrv.c
===================================================================
--- uspace/lib/usb/src/localdrv.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/src/localdrv.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,389 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Driver communication for local drivers (hubs).
+ */
+#include <usb/hcdhubd.h>
+#include <usbhc_iface.h>
+#include <driver.h>
+#include <bool.h>
+#include <errno.h>
+
+/** Information about pending transaction on HC. */
+typedef struct {
+	/** Storage for actual number of bytes transferred. */
+	size_t *size_transferred;
+
+	/** Target device. */
+	usb_hcd_attached_device_info_t *device;
+	/** Target endpoint. */
+	usb_hc_endpoint_info_t *endpoint;
+
+	/** Guard for the condition variable. */
+	fibril_mutex_t condvar_guard;
+	/** Condition variable for waiting for done. */
+	fibril_condvar_t condvar;
+
+	/** Flag whether the transfer is done. */
+	bool done;
+} transfer_info_t;
+
+/** Create new transfer info.
+ *
+ * @param device Attached device.
+ * @param endpoint Endpoint.
+ * @return Transfer info with pre-filled values.
+ */
+static transfer_info_t *transfer_info_create(
+    usb_hcd_attached_device_info_t *device, usb_hc_endpoint_info_t *endpoint)
+{
+	transfer_info_t *transfer = malloc(sizeof(transfer_info_t));
+
+	transfer->size_transferred = NULL;
+	fibril_condvar_initialize(&transfer->condvar);
+	fibril_mutex_initialize(&transfer->condvar_guard);
+	transfer->done = false;
+
+	transfer->device = device;
+	transfer->endpoint = endpoint;
+
+	return transfer;
+}
+
+/** Destroy transfer info.
+ *
+ * @param transfer Transfer to be destroyed.
+ */
+static void transfer_info_destroy(transfer_info_t *transfer)
+{
+	free(transfer->device);
+	free(transfer->endpoint);
+	free(transfer);
+}
+
+/** Create info about attached device.
+ *
+ * @param address Device address.
+ * @return Device info structure.
+ */
+static usb_hcd_attached_device_info_t *create_attached_device_info(
+    usb_address_t address)
+{
+	usb_hcd_attached_device_info_t *dev
+	    = malloc(sizeof(usb_hcd_attached_device_info_t));
+
+	dev->address = address;
+	dev->endpoint_count = 0;
+	dev->endpoints = NULL;
+	list_initialize(&dev->link);
+
+	return dev;
+}
+
+/** Create info about device endpoint.
+ *
+ * @param endpoint Endpoint number.
+ * @param direction Endpoint data direction.
+ * @param transfer_type Transfer type of the endpoint.
+ * @return Endpoint info structure.
+ */
+static usb_hc_endpoint_info_t *create_endpoint_info(usb_endpoint_t endpoint,
+    usb_direction_t direction, usb_transfer_type_t transfer_type)
+{
+	usb_hc_endpoint_info_t *ep = malloc(sizeof(usb_hc_endpoint_info_t));
+	ep->data_toggle = 0;
+	ep->direction = direction;
+	ep->transfer_type = transfer_type;
+	ep->endpoint = endpoint;
+
+	return ep;
+}
+
+/** Marks given transfer as done.
+ *
+ * @param transfer Transfer to be completed.
+ */
+static void transfer_mark_complete(transfer_info_t *transfer)
+{
+	fibril_mutex_lock(&transfer->condvar_guard);
+	transfer->done = true;
+	fibril_condvar_signal(&transfer->condvar);
+	fibril_mutex_unlock(&transfer->condvar_guard);
+}
+
+/** Callback for OUT transfers.
+ *
+ * @param hc Host controller that processed the transfer.
+ * @param outcome Transfer outcome.
+ * @param arg Custom argument.
+ */
+static void callback_out(usb_hc_device_t *hc,
+    usb_transaction_outcome_t outcome, void *arg)
+{
+	transfer_info_t *transfer = (transfer_info_t *) arg;
+
+	/*
+	 * For out transfers, marking them complete is enough.
+	 * No other processing is necessary.
+	 */
+	transfer_mark_complete(transfer);
+}
+
+/** Callback for IN transfers.
+ *
+ * @param hc Host controller that processed the transfer.
+ * @param actual_size Number of actually transferred bytes.
+ * @param outcome Transfer outcome.
+ * @param arg Custom argument.
+ */
+static void callback_in(usb_hc_device_t *hc,
+    size_t actual_size, usb_transaction_outcome_t outcome, void *arg)
+{
+	transfer_info_t *transfer = (transfer_info_t *) arg;
+
+	/*
+	 * Set the number of actually transferred bytes and
+	 * mark the transfer as complete.
+	 */
+	if (transfer->size_transferred != NULL) {
+		*transfer->size_transferred = actual_size;
+	}
+
+	transfer_mark_complete(transfer);
+}
+
+static int async_transfer_out(usb_hc_device_t *hc,
+    usb_target_t target, usb_transfer_type_t transfer_type,
+    void *data, size_t size,
+    usb_handle_t *handle)
+{
+	if ((hc->transfer_ops == NULL)
+	    || (hc->transfer_ops->transfer_out == NULL)) {
+		return ENOTSUP;
+	}
+
+	/* This creation of the device on the fly is just a workaround. */
+
+	transfer_info_t *transfer = transfer_info_create(
+	    create_attached_device_info(target.address),
+	    create_endpoint_info(target.endpoint,
+		USB_DIRECTION_OUT, transfer_type));
+
+	int rc = hc->transfer_ops->transfer_out(hc,
+	    transfer->device, transfer->endpoint,
+	    data, size,
+	    callback_out, transfer);
+
+	if (rc != EOK) {
+		transfer_info_destroy(transfer);
+		return rc;
+	}
+
+	*handle = (usb_handle_t)transfer;
+
+	return EOK;
+}
+
+static int async_transfer_setup(usb_hc_device_t *hc,
+    usb_target_t target, usb_transfer_type_t transfer_type,
+    void *data, size_t size,
+    usb_handle_t *handle)
+{
+	if ((hc->transfer_ops == NULL)
+	    || (hc->transfer_ops->transfer_setup == NULL)) {
+		return ENOTSUP;
+	}
+
+	/* This creation of the device on the fly is just a workaround. */
+
+	transfer_info_t *transfer = transfer_info_create(
+	    create_attached_device_info(target.address),
+	    create_endpoint_info(target.endpoint,
+		USB_DIRECTION_OUT, transfer_type));
+
+	int rc = hc->transfer_ops->transfer_setup(hc,
+	    transfer->device, transfer->endpoint,
+	    data, size,
+	    callback_out, transfer);
+
+	if (rc != EOK) {
+		transfer_info_destroy(transfer);
+		return rc;
+	}
+
+	*handle = (usb_handle_t)transfer;
+
+	return EOK;
+}
+
+static int async_transfer_in(usb_hc_device_t *hc, usb_target_t target,
+    usb_transfer_type_t transfer_type,
+    void *buffer, size_t size, size_t *actual_size,
+    usb_handle_t *handle)
+{
+	if ((hc->transfer_ops == NULL)
+	    || (hc->transfer_ops->transfer_in == NULL)) {
+		return ENOTSUP;
+	}
+
+	/* This creation of the device on the fly is just a workaround. */
+
+	transfer_info_t *transfer = transfer_info_create(
+	    create_attached_device_info(target.address),
+	    create_endpoint_info(target.endpoint,
+		USB_DIRECTION_IN, transfer_type));
+	transfer->size_transferred = actual_size;
+
+	int rc = hc->transfer_ops->transfer_in(hc,
+	    transfer->device, transfer->endpoint,
+	    buffer, size,
+	    callback_in, transfer);
+
+	if (rc != EOK) {
+		transfer_info_destroy(transfer);
+		return rc;
+	}
+
+	*handle = (usb_handle_t)transfer;
+
+	return EOK;
+}
+
+
+/** Issue interrupt OUT transfer to HC driven by current task.
+ *
+ * @param hc Host controller to handle the transfer.
+ * @param target Target device address.
+ * @param buffer Data buffer.
+ * @param size Buffer size.
+ * @param handle Transfer handle.
+ * @return Error code.
+ */
+int usb_hc_async_interrupt_out(usb_hc_device_t *hc, usb_target_t target,
+    void *buffer, size_t size,
+    usb_handle_t *handle)
+{
+	return async_transfer_out(hc, target,
+	    USB_TRANSFER_INTERRUPT, buffer, size, handle);
+}
+
+
+/** Issue interrupt IN transfer to HC driven by current task.
+ *
+ * @warning The @p buffer and @p actual_size parameters shall not be
+ * touched until this transfer is waited for by usb_hc_async_wait_for().
+ *
+ * @param hc Host controller to handle the transfer.
+ * @param target Target device address.
+ * @param buffer Data buffer.
+ * @param size Buffer size.
+ * @param actual_size Size of actually transferred data.
+ * @param handle Transfer handle.
+ * @return Error code.
+ */
+int usb_hc_async_interrupt_in(usb_hc_device_t *hc, usb_target_t target,
+    void *buffer, size_t size, size_t *actual_size,
+    usb_handle_t *handle)
+{
+	return async_transfer_in(hc, target,
+	    USB_TRANSFER_INTERRUPT, buffer, size, actual_size, handle);
+}
+
+int usb_hc_async_control_write_setup(usb_hc_device_t *hc, usb_target_t target,
+    void *data, size_t size, usb_handle_t *handle)
+{
+	return async_transfer_setup(hc, target,
+	    USB_TRANSFER_CONTROL, data, size, handle);
+}
+
+int usb_hc_async_control_write_data(usb_hc_device_t *hc, usb_target_t target,
+    void *data, size_t size, usb_handle_t *handle)
+{
+	return async_transfer_out(hc, target,
+	    USB_TRANSFER_CONTROL, data, size, handle);
+}
+
+int usb_hc_async_control_write_status(usb_hc_device_t *hc, usb_target_t target,
+    usb_handle_t *handle)
+{
+	return async_transfer_in(hc, target,
+	    USB_TRANSFER_CONTROL, NULL, 0, NULL, handle);
+}
+
+int usb_hc_async_control_read_setup(usb_hc_device_t *hc, usb_target_t target,
+    void *data, size_t size, usb_handle_t *handle)
+{
+	return async_transfer_setup(hc, target,
+	    USB_TRANSFER_CONTROL, data, size, handle);
+}
+
+int usb_hc_async_control_read_data(usb_hc_device_t *hc, usb_target_t target,
+    void *buffer, size_t size, size_t *actual_size,
+    usb_handle_t *handle)
+{
+	return async_transfer_in(hc, target,
+	    USB_TRANSFER_CONTROL, buffer, size, actual_size, handle);
+}
+
+int usb_hc_async_control_read_status(usb_hc_device_t *hc, usb_target_t target,
+    usb_handle_t *handle)
+{
+	return async_transfer_out(hc, target,
+	    USB_TRANSFER_CONTROL, NULL, 0, handle);
+}
+
+/** Wait for transfer to complete.
+ *
+ * @param handle Transfer handle.
+ * @return Error code.
+ */
+int usb_hc_async_wait_for(usb_handle_t handle)
+{
+	transfer_info_t *transfer = (transfer_info_t *) handle;
+	if (transfer == NULL) {
+		return ENOENT;
+	}
+
+	fibril_mutex_lock(&transfer->condvar_guard);
+	while (!transfer->done) {
+		fibril_condvar_wait(&transfer->condvar, &transfer->condvar_guard);
+	}
+	fibril_mutex_unlock(&transfer->condvar_guard);
+
+	transfer_info_destroy(transfer);
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usb/src/usb.c
===================================================================
--- uspace/lib/usb/src/usb.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/src/usb.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,74 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Base USB types.
+ */
+#include <usb/usb.h>
+#include <errno.h>
+
+
+/** String representation for USB transfer type. */
+const char * usb_str_transfer_type(usb_transfer_type_t t)
+{
+	switch (t) {
+		case USB_TRANSFER_ISOCHRONOUS:
+			return "isochronous";
+		case USB_TRANSFER_INTERRUPT:
+			return "interrupt";
+		case USB_TRANSFER_CONTROL:
+			return "control";
+		case USB_TRANSFER_BULK:
+			return "bulk";
+		default:
+			return "unknown";
+	}
+}
+
+/** String representation of USB transaction outcome. */
+const char * usb_str_transaction_outcome(usb_transaction_outcome_t o)
+{
+	switch (o) {
+		case USB_OUTCOME_OK:
+			return "ok";
+		case USB_OUTCOME_CRCERROR:
+			return "CRC error";
+		case USB_OUTCOME_BABBLE:
+			return "babble";
+		default:
+			return "unknown";
+	}
+}
+
+
+/**
+ * @}
+ */
Index: uspace/lib/usb/src/usbdrv.c
===================================================================
--- uspace/lib/usb/src/usbdrv.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usb/src/usbdrv.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,327 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief USB driver (implementation).
+ */
+#include <usb/usbdrv.h>
+#include <usbhc_iface.h>
+#include <errno.h>
+
+/** Information about pending transaction on HC. */
+typedef struct {
+	/** Phone to host controller driver. */
+	int phone;
+	/** Data buffer. */
+	void *buffer;
+	/** Buffer size. */
+	size_t size;
+	/** Storage for actual number of bytes transferred. */
+	size_t *size_transferred;
+	/** Initial call replay data. */
+	ipc_call_t reply;
+	/** Initial call identifier. */
+	aid_t request;
+} transfer_info_t;
+
+/** Connect to host controller the device is physically attached to.
+ *
+ * @param handle Device handle.
+ * @param flags Connection flags (blocking connection).
+ * @return Phone to corresponding HC or error code.
+ */
+int usb_drv_hc_connect(device_t *dev, unsigned int flags)
+{
+	/*
+	 * Call parent hub to obtain device handle of respective HC.
+	 */
+	return ENOTSUP;
+}
+
+/** Tell USB address assigned to given device.
+ *
+ * @param phone Phone to my HC.
+ * @param dev Device in question.
+ * @return USB address or error code.
+ */
+usb_address_t usb_drv_get_my_address(int phone, device_t *dev)
+{
+	return ENOTSUP;
+}
+
+/** Send data to HCD.
+ *
+ * @param phone Phone to HC.
+ * @param method Method used for calling.
+ * @param target Targeted device.
+ * @param buffer Data buffer (NULL to skip data transfer phase).
+ * @param size Buffer size (must be zero when @p buffer is NULL).
+ * @param handle Storage for transaction handle (cannot be NULL).
+ * @return Error status.
+ * @retval EINVAL Invalid parameter.
+ * @retval ENOMEM Not enough memory to complete the operation.
+ */
+static int async_send_buffer(int phone, int method,
+    usb_target_t target,
+    void *buffer, size_t size,
+    usb_handle_t *handle)
+{
+	if (phone < 0) {
+		return EINVAL;
+	}
+
+	if ((buffer == NULL) && (size > 0)) {
+		return EINVAL;
+	}
+
+	if (handle == NULL) {
+		return EINVAL;
+	}
+
+	transfer_info_t *transfer
+	    = (transfer_info_t *) malloc(sizeof(transfer_info_t));
+	if (transfer == NULL) {
+		return ENOMEM;
+	}
+
+	transfer->size_transferred = NULL;
+	transfer->buffer = NULL;
+	transfer->size = 0;
+	transfer->phone = phone;
+
+	int rc;
+
+	transfer->request = async_send_4(phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    method,
+	    target.address, target.endpoint,
+	    size,
+	    &transfer->reply);
+
+	if (size > 0) {
+		rc = async_data_write_start(phone, buffer, size);
+		if (rc != EOK) {
+			async_wait_for(transfer->request, NULL);
+			return rc;
+		}
+	}
+
+	*handle = (usb_handle_t) transfer;
+
+	return EOK;
+}
+
+/** Prepare data retrieval.
+ *
+ * @param phone Opened phone to HCD.
+ * @param method Method used for calling.
+ * @param target Targeted device.
+ * @param buffer Buffer where to store retrieved data
+ * 	(NULL to skip data transfer phase).
+ * @param size Buffer size (must be zero when @p buffer is NULL).
+ * @param actual_size Storage where actual number of bytes transferred will
+ * 	be stored.
+ * @param handle Storage for transaction handle (cannot be NULL).
+ * @return Error status.
+ * @retval EINVAL Invalid parameter.
+ * @retval ENOMEM Not enough memory to complete the operation.
+ */
+static int async_recv_buffer(int phone, int method,
+    usb_target_t target,
+    void *buffer, size_t size, size_t *actual_size,
+    usb_handle_t *handle)
+{
+	if (phone < 0) {
+		return EINVAL;
+	}
+
+	if ((buffer == NULL) && (size > 0)) {
+		return EINVAL;
+	}
+
+	if (handle == NULL) {
+		return EINVAL;
+	}
+
+	transfer_info_t *transfer
+	    = (transfer_info_t *) malloc(sizeof(transfer_info_t));
+	if (transfer == NULL) {
+		return ENOMEM;
+	}
+
+	transfer->size_transferred = actual_size;
+	transfer->buffer = buffer;
+	transfer->size = size;
+	transfer->phone = phone;
+
+	transfer->request = async_send_4(phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    method,
+	    target.address, target.endpoint,
+	    size,
+	    &transfer->reply);
+
+	*handle = (usb_handle_t) transfer;
+
+	return EOK;
+}
+
+/** Read buffer from HCD.
+ *
+ * @param phone Opened phone to HCD.
+ * @param hash Buffer hash (obtained after completing IN transaction).
+ * @param buffer Buffer where to store data data.
+ * @param size Buffer size.
+ * @param actual_size Storage where actual number of bytes transferred will
+ * 	be stored.
+ * @return Error status.
+ */
+static int read_buffer_in(int phone, ipcarg_t hash,
+    void *buffer, size_t size, size_t *actual_size)
+{
+	ipc_call_t answer_data;
+	ipcarg_t answer_rc;
+	aid_t req;
+	int rc;
+
+	req = async_send_2(phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_GET_BUFFER,
+	    hash,
+	    &answer_data);
+
+	rc = async_data_read_start(phone, buffer, size);
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return EINVAL;
+	}
+
+	async_wait_for(req, &answer_rc);
+	rc = (int)answer_rc;
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	*actual_size = IPC_GET_ARG1(answer_data);
+
+	return EOK;
+}
+
+/** Blocks caller until given USB transaction is finished.
+ * After the transaction is finished, the user can access all output data
+ * given to initial call function.
+ *
+ * @param handle Transaction handle.
+ * @return Error status.
+ * @retval EOK No error.
+ * @retval EBADMEM Invalid handle.
+ * @retval ENOENT Data buffer associated with transaction does not exist.
+ */
+int usb_drv_async_wait_for(usb_handle_t handle)
+{
+	if (handle == 0) {
+		return EBADMEM;
+	}
+
+	int rc = EOK;
+
+	transfer_info_t *transfer = (transfer_info_t *) handle;
+
+	ipcarg_t answer_rc;
+	async_wait_for(transfer->request, &answer_rc);
+
+	if (answer_rc != EOK) {
+		rc = (int) answer_rc;
+		goto leave;
+	}
+
+	/*
+	 * If the buffer is not NULL, we must accept some data.
+	 */
+	if ((transfer->buffer != NULL) && (transfer->size > 0)) {
+		/*
+		 * The buffer hash identifies the data on the server
+		 * side.
+		 * We will use it when actually reading-in the data.
+		 */
+		ipcarg_t buffer_hash = IPC_GET_ARG1(transfer->reply);
+		if (buffer_hash == 0) {
+			rc = ENOENT;
+			goto leave;
+		}
+
+		size_t actual_size;
+		rc = read_buffer_in(transfer->phone, buffer_hash,
+		    transfer->buffer, transfer->size, &actual_size);
+
+		if (rc != EOK) {
+			goto leave;
+		}
+
+		if (transfer->size_transferred) {
+			*(transfer->size_transferred) = actual_size;
+		}
+	}
+
+leave:
+	free(transfer);
+
+	return rc;
+}
+
+/** Send interrupt data to device. */
+int usb_drv_async_interrupt_out(int phone, usb_target_t target,
+    void *buffer, size_t size,
+    usb_handle_t *handle)
+{
+	return async_send_buffer(phone,
+	    IPC_M_USBHC_INTERRUPT_OUT,
+	    target,
+	    buffer, size,
+	    handle);
+}
+
+/** Request interrupt data from device. */
+int usb_drv_async_interrupt_in(int phone, usb_target_t target,
+    void *buffer, size_t size, size_t *actual_size,
+    usb_handle_t *handle)
+{
+	return async_recv_buffer(phone,
+	    IPC_M_USBHC_INTERRUPT_IN,
+	    target,
+	    buffer, size, actual_size,
+	    handle);
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/Makefile
===================================================================
--- uspace/lib/usbvirt/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/Makefile	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBRARY = libusbvirt
+
+LIBS = $(LIBUSB_PREFIX)/libusb.a
+EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include
+
+SOURCES = \
+	callback.c \
+	ctrlpipe.c \
+	debug.c \
+	main.c \
+	stdreq.c \
+	transaction.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/usbvirt/callback.c
===================================================================
--- uspace/lib/usbvirt/callback.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/callback.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,236 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Callback connection handling.
+ */
+#include <devmap.h>
+#include <fcntl.h>
+#include <vfs/vfs.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mem.h>
+
+#include "hub.h"
+#include "device.h"
+#include "private.h"
+
+#define NAMESPACE "usb"
+#define USB_MAX_PAYLOAD_SIZE 1020
+
+/** Wrapper for SETUP transaction over telephone. */
+static void handle_setup_transaction(usbvirt_device_t *device,
+    ipc_callid_t iid, ipc_call_t icall)
+{
+	usb_address_t address = IPC_GET_ARG1(icall);
+	usb_endpoint_t endpoint = IPC_GET_ARG2(icall);
+	size_t expected_len = IPC_GET_ARG3(icall);
+	
+	if (address != device->address) {
+		ipc_answer_0(iid, EADDRNOTAVAIL);
+		return;
+	}
+	
+	if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) {
+		ipc_answer_0(iid, EINVAL);
+		return;
+	}
+	
+	if (expected_len == 0) {
+		ipc_answer_0(iid, EINVAL);
+		return;
+	}
+	
+	size_t len = 0;
+	void * buffer = NULL;
+	int rc = async_data_write_accept(&buffer, false,
+	    1, USB_MAX_PAYLOAD_SIZE, 0, &len);
+		
+	if (rc != EOK) {
+		ipc_answer_0(iid, rc);
+		return;
+	}
+	
+	rc = device->transaction_setup(device, endpoint, buffer, len);
+	
+	ipc_answer_0(iid, rc);
+}
+
+/** Wrapper for OUT transaction over telephone. */
+static void handle_out_transaction(usbvirt_device_t *device,
+    ipc_callid_t iid, ipc_call_t icall)
+{
+	usb_address_t address = IPC_GET_ARG1(icall);
+	usb_endpoint_t endpoint = IPC_GET_ARG2(icall);
+	size_t expected_len = IPC_GET_ARG3(icall);
+	
+	if (address != device->address) {
+		ipc_answer_0(iid, EADDRNOTAVAIL);
+		return;
+	}
+	
+	if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) {
+		ipc_answer_0(iid, EINVAL);
+		return;
+	}
+	
+	int rc = EOK;
+	
+	size_t len = 0;
+	void *buffer = NULL;
+	
+	if (expected_len > 0) {
+		rc = async_data_write_accept(&buffer, false,
+		    1, USB_MAX_PAYLOAD_SIZE, 0, &len);
+			
+		if (rc != EOK) {
+			ipc_answer_0(iid, rc);
+			return;
+		}
+	}
+	
+	rc = device->transaction_out(device, endpoint, buffer, len);
+	
+	if (buffer != NULL) {
+		free(buffer);
+	}
+	
+	ipc_answer_0(iid, rc);
+}
+
+
+/** Wrapper for IN transaction over telephone. */
+static void handle_in_transaction(usbvirt_device_t *device,
+    ipc_callid_t iid, ipc_call_t icall)
+{
+	usb_address_t address = IPC_GET_ARG1(icall);
+	usb_endpoint_t endpoint = IPC_GET_ARG2(icall);
+	size_t expected_len = IPC_GET_ARG3(icall);
+	
+	if (address != device->address) {
+		ipc_answer_0(iid, EADDRNOTAVAIL);
+		return;
+	}
+	
+	if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) {
+		ipc_answer_0(iid, EINVAL);
+		return;
+	}
+	
+	int rc = EOK;
+	
+	void *buffer = expected_len > 0 ? malloc(expected_len) : NULL;
+	size_t len;
+	
+	rc = device->transaction_in(device, endpoint, buffer, expected_len, &len);
+	/*
+	 * If the request was processed, we will send data back.
+	 */
+	if (rc == EOK) {
+		size_t receive_len;
+		ipc_callid_t callid;
+		if (!async_data_read_receive(&callid, &receive_len)) {
+			ipc_answer_0(iid, EINVAL);
+			return;
+		}
+		async_data_read_finalize(callid, buffer, receive_len);
+	}
+	
+	ipc_answer_0(iid, rc);
+}
+
+/** Wrapper for getting device name. */
+static void handle_get_name(usbvirt_device_t *device,
+    ipc_callid_t iid, ipc_call_t icall)
+{
+	if (device->name == NULL) {
+		ipc_answer_0(iid, ENOENT);
+	}
+	
+	size_t size = str_size(device->name);
+	
+	ipc_callid_t callid;
+	size_t accepted_size;
+	if (!async_data_read_receive(&callid, &accepted_size)) {
+		ipc_answer_0(iid, EINVAL);
+		return;
+	}
+	
+	if (accepted_size > size) {
+		accepted_size = size;
+	}
+	async_data_read_finalize(callid, device->name, accepted_size);
+	
+	ipc_answer_1(iid, EOK, accepted_size);
+}
+
+/** Callback connection for a given device. */
+void device_callback_connection(usbvirt_device_t *device, ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_answer_0(iid, EOK);
+	
+	while (true) {
+		ipc_callid_t callid; 
+		ipc_call_t call; 
+		
+		callid = async_get_call(&call);
+		switch (IPC_GET_METHOD(call)) {
+			case IPC_M_PHONE_HUNGUP:
+				ipc_answer_0(callid, EOK);
+				return;
+			
+			case IPC_M_USBVIRT_GET_NAME:
+				handle_get_name(device, callid, call);
+				break;
+			
+			case IPC_M_USBVIRT_TRANSACTION_SETUP:
+				handle_setup_transaction(device, callid, call);
+				break;
+			
+			case IPC_M_USBVIRT_TRANSACTION_OUT:
+				handle_out_transaction(device, callid, call);
+				break;
+				
+			case IPC_M_USBVIRT_TRANSACTION_IN:
+				handle_in_transaction(device, callid, call);
+				break;
+			
+			default:
+				ipc_answer_0(callid, EINVAL);
+				break;
+		}
+	}
+}
+
+
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/ctrlpipe.c
===================================================================
--- uspace/lib/usbvirt/ctrlpipe.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/ctrlpipe.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,127 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Device control pipe.
+ */
+#include <errno.h>
+
+#include "private.h"
+
+#define REQUEST_TYPE_STANDARD 0 
+#define REQUEST_TYPE_CLASS 1
+
+#define GET_MIDBITS_MASK(size, shift) \
+	(((1 << size) - 1) << shift)
+#define GET_MIDBITS(value, size, shift) \
+	((value & GET_MIDBITS_MASK(size, shift)) >> shift)
+
+
+static const char *str_request_type(int type)
+{
+	switch (type) {
+		case REQUEST_TYPE_STANDARD:
+			return "standard";
+		case REQUEST_TYPE_CLASS:
+			return "class";
+		default:
+			return "unknown";
+	}
+}
+
+/** Tell request type.
+ * By type is meant either standard, class, vendor or other.
+ */
+static int request_get_type(uint8_t request_type)
+{
+	return GET_MIDBITS(request_type, 2, 5);
+}
+
+/** Handle communication over control pipe zero.
+ */
+int control_pipe(usbvirt_device_t *device, usbvirt_control_transfer_t *transfer)
+{
+	device->lib_debug(device, 1, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO,
+	    "op on control pipe zero (request_size=%u)", transfer->request_size);
+	
+	if (transfer->request_size < sizeof(usb_device_request_setup_packet_t)) {
+		return ENOMEM;
+	}
+	
+	usb_device_request_setup_packet_t *request = (usb_device_request_setup_packet_t *) transfer->request;
+	uint8_t *remaining_data = transfer->data;
+	
+	int type = request_get_type(request->request_type);
+	
+	int rc = EOK;
+	
+	device->lib_debug(device, 2, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO,
+	    "request type: %s", str_request_type(type));
+	
+	switch (type) {
+		case REQUEST_TYPE_STANDARD:
+			rc = handle_std_request(device, request, remaining_data);
+			break;
+		case REQUEST_TYPE_CLASS:
+			if (DEVICE_HAS_OP(device, on_class_device_request)) {
+				rc = device->ops->on_class_device_request(device,
+				    request, remaining_data);
+			}
+			break;
+		default:
+			break;
+	}
+	
+	if (device->new_address != -1) {
+		/*
+		 * TODO: handle when this request is invalid (e.g.
+		 * setting address when in configured state).
+		 */
+		if (device->new_address == 0) {
+			device->state = USBVIRT_STATE_DEFAULT;
+		} else {
+			device->state = USBVIRT_STATE_ADDRESS;
+		}
+		device->address = device->new_address;
+		
+		device->new_address = -1;
+		
+		device->lib_debug(device, 2, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO,
+		    "device address changed to %d (state %s)",
+		    device->address, str_device_state(device->state));
+	}
+	
+	return rc;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/debug.c
===================================================================
--- uspace/lib/usbvirt/debug.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/debug.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,104 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Debugging support.
+ */
+#include <stdio.h>
+#include <bool.h>
+
+#include "device.h"
+#include "private.h"
+
+
+static void debug_print(int level, uint8_t tag,
+    int current_level, uint8_t enabled_tags,
+    const char *format, va_list args)
+{
+	if (level > current_level) {
+		return;
+	}
+	
+	if ((tag & enabled_tags) == 0) {
+		return;
+	}
+	
+	bool print_prefix = true;
+	
+	if ((format[0] == '%') && (format[1] == 'M')) {
+		format += 2;
+		print_prefix = false;
+	}
+	
+	if (print_prefix) {
+		printf("[vusb]: ");
+		while (--level > 0) {
+			printf(" ");
+		}
+	}
+	
+	vprintf(format, args);
+	
+	if (print_prefix) {
+		printf("\n");
+	}
+}
+
+
+void user_debug(usbvirt_device_t *device, int level, uint8_t tag,
+    const char *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	
+	debug_print(level, tag,
+	    device->debug_level, device->debug_enabled_tags,
+	    format, args);
+	
+	va_end(args);
+}
+
+void lib_debug(usbvirt_device_t *device, int level, uint8_t tag,
+    const char *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	
+	debug_print(level, tag,
+	    device->lib_debug_level, device->lib_debug_enabled_tags,
+	    format, args);
+	
+	va_end(args);
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/device.h
===================================================================
--- uspace/lib/usbvirt/device.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/device.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,224 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Virtual USB device.
+ */
+#ifndef LIBUSBVIRT_DEVICE_H_
+#define LIBUSBVIRT_DEVICE_H_
+
+#include <usb/usb.h>
+#include <usb/descriptor.h>
+#include <usb/devreq.h>
+
+typedef struct usbvirt_device usbvirt_device_t;
+struct usbvirt_control_transfer;
+
+typedef int (*usbvirt_on_device_request_t)(usbvirt_device_t *dev,
+	usb_device_request_setup_packet_t *request,
+	uint8_t *data);
+
+/** Callbacks for standard device requests.
+ * When these functions are NULL or return EFORWARD, this
+ * framework will try to satisfy the request by itself.
+ */
+typedef struct {
+	usbvirt_on_device_request_t on_get_status;
+	usbvirt_on_device_request_t on_clear_feature;
+	usbvirt_on_device_request_t on_set_feature;
+	usbvirt_on_device_request_t on_set_address;
+	usbvirt_on_device_request_t on_get_descriptor;
+	usbvirt_on_device_request_t on_set_descriptor;
+	usbvirt_on_device_request_t on_get_configuration;
+	usbvirt_on_device_request_t on_set_configuration;
+	usbvirt_on_device_request_t on_get_interface;
+	usbvirt_on_device_request_t on_set_interface;
+	usbvirt_on_device_request_t on_synch_frame;
+} usbvirt_standard_device_request_ops_t;
+
+/** Device operations. */
+typedef struct {
+	/** Callbacks for standard deivce requests. */
+	usbvirt_standard_device_request_ops_t *standard_request_ops;
+	/** Callback for class-specific USB request. */
+	usbvirt_on_device_request_t on_class_device_request;
+	
+	int (*on_control_transfer)(usbvirt_device_t *dev,
+	    usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer);
+	
+	/** Callback for all other incoming data. */
+	int (*on_data)(usbvirt_device_t *dev,
+	    usb_endpoint_t endpoint, void *buffer, size_t size);
+	
+	/** Callback for host request for data. */
+	int (*on_data_request)(usbvirt_device_t *dev,
+	    usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size);
+	
+	/** Decides direction of control transfer. */
+	usb_direction_t (*decide_control_transfer_direction)(
+	    usb_endpoint_t endpoint, void *buffer, size_t size);
+} usbvirt_device_ops_t;
+
+/** Extra configuration data for GET_CONFIGURATION request. */
+typedef struct {
+	/** Actual data. */
+	uint8_t *data;
+	/** Data length. */
+	size_t length;
+} usbvirt_device_configuration_extras_t;
+
+/** Single device configuration. */
+typedef struct {
+	/** Standard configuration descriptor. */
+	usb_standard_configuration_descriptor_t *descriptor;
+	/** Array of extra data. */
+	usbvirt_device_configuration_extras_t *extra;
+	/** Length of @c extra array. */
+	size_t extra_count;
+} usbvirt_device_configuration_t;
+
+/** Standard USB descriptors. */
+typedef struct {
+	/** Standard device descriptor.
+	 * There is always only one such descriptor for the device.
+	 */
+	usb_standard_device_descriptor_t *device;
+	
+	/** Configurations. */
+	usbvirt_device_configuration_t *configuration;
+	/** Number of configurations. */
+	size_t configuration_count;
+	/** Index of currently selected configuration. */
+	uint8_t current_configuration;
+} usbvirt_descriptors_t;
+
+/** Possible states of virtual USB device.
+ * Notice that these are not 1:1 mappings to those in USB specification.
+ */
+typedef enum {
+	USBVIRT_STATE_DEFAULT,
+	USBVIRT_STATE_ADDRESS,
+	USBVIRT_STATE_CONFIGURED
+} usbvirt_device_state_t;
+
+/** Information about on-going control transfer.
+ */
+typedef struct usbvirt_control_transfer {
+	/** Transfer direction (read/write control transfer). */
+	usb_direction_t direction;
+	/** Request data. */
+	void *request;
+	/** Size of request data. */
+	size_t request_size;
+	/** Payload. */
+	void *data;
+	/** Size of payload. */
+	size_t data_size;
+} usbvirt_control_transfer_t;
+
+typedef enum {
+	USBVIRT_DEBUGTAG_BASE = 1,
+	USBVIRT_DEBUGTAG_TRANSACTION = 2,
+	USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO = 4,
+	USBVIRT_DEBUGTAG_ALL = 255
+} usbvirt_debug_tags_t;
+
+/** Virtual USB device. */
+struct usbvirt_device {
+	/** Callback device operations. */
+	usbvirt_device_ops_t *ops;
+	
+	/** Reply onto control transfer.
+	 */
+	int (*control_transfer_reply)(usbvirt_device_t *dev,
+	    usb_endpoint_t endpoint, void *buffer, size_t size);
+	
+	/** Device name.
+	 * Used in debug prints and sent to virtual host controller.
+	 */
+	const char *name;
+	
+	/** Standard descriptors. */
+	usbvirt_descriptors_t *descriptors;
+	
+	/** Current device state. */
+	usbvirt_device_state_t state;
+	
+	/** Device address. */
+	usb_address_t address;
+	/** New device address.
+	 * This field is used during SET_ADDRESS request.
+	 * On all other occasions, it holds invalid address (e.g. -1).
+	 */
+	usb_address_t new_address;
+	
+	/** Process OUT transaction. */
+	int (*transaction_out)(usbvirt_device_t *dev,
+	    usb_endpoint_t endpoint, void *buffer, size_t size);
+	/** Process SETUP transaction. */
+	int (*transaction_setup)(usbvirt_device_t *dev,
+	    usb_endpoint_t endpoint, void *buffer, size_t size);
+	/** Process IN transaction. */
+	int (*transaction_in)(usbvirt_device_t *dev,
+	    usb_endpoint_t endpoint, void *buffer, size_t size, size_t *data_size);
+	
+	/** State information on control-transfer endpoints. */
+	usbvirt_control_transfer_t current_control_transfers[USB11_ENDPOINT_MAX];
+	
+	/* User debugging. */
+	
+	/** Debug print. */
+	void (*debug)(usbvirt_device_t *dev, int level, uint8_t tag,
+	    const char *format, ...);
+	
+	/** Current debug level. */
+	int debug_level;
+	
+	/** Bitmap of currently enabled tags. */
+	uint8_t debug_enabled_tags;
+	
+	/* Library debugging. */
+	
+	/** Debug print. */
+	void (*lib_debug)(usbvirt_device_t *dev, int level, uint8_t tag,
+	    const char *format, ...);
+	
+	/** Current debug level. */
+	int lib_debug_level;
+	
+	/** Bitmap of currently enabled tags. */
+	uint8_t lib_debug_enabled_tags;
+};
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/hub.h
===================================================================
--- uspace/lib/usbvirt/hub.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/hub.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,68 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Virtual USB device.
+ */
+#ifndef LIBUSBVIRT_HUB_H_
+#define LIBUSBVIRT_HUB_H_
+
+#include "device.h"
+
+/** USB transaction type.
+ * This types does not correspond directly to types in USB specification,
+ * as actually DATA transactions are marked with these types to identify
+ * their direction (and tag).
+ */
+typedef enum {
+	USBVIRT_TRANSACTION_SETUP,
+	USBVIRT_TRANSACTION_IN,
+	USBVIRT_TRANSACTION_OUT
+} usbvirt_transaction_type_t;
+
+const char *usbvirt_str_transaction_type(usbvirt_transaction_type_t type);
+
+/** Telephony methods of virtual devices. */
+typedef enum {
+	IPC_M_USBVIRT_GET_NAME = IPC_FIRST_USER_METHOD,
+	IPC_M_USBVIRT_TRANSACTION_SETUP,
+	IPC_M_USBVIRT_TRANSACTION_OUT,
+	IPC_M_USBVIRT_TRANSACTION_IN,
+} usbvirt_device_method_t;
+
+int usbvirt_connect(usbvirt_device_t *);
+int usbvirt_connect_local(usbvirt_device_t *);
+int usbvirt_disconnect(usbvirt_device_t *dev);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/main.c
===================================================================
--- uspace/lib/usbvirt/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,291 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Device registration with virtual USB framework.
+ */
+#include <devman.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mem.h>
+#include <assert.h>
+
+#include "hub.h"
+#include "device.h"
+#include "private.h"
+
+#define NAMESPACE "usb"
+
+/** Virtual device wrapper. */
+typedef struct {
+	/** Actual device. */
+	usbvirt_device_t *device;
+	/** Phone to host controller. */
+	int vhcd_phone;
+	/** Device id. */
+	ipcarg_t id;
+	/** Linked-list member. */
+	link_t link;
+} virtual_device_t;
+
+/*** List of known device. */
+static LIST_INITIALIZE(device_list);
+
+/** Find virtual device wrapper based on the contents. */
+static virtual_device_t *find_device(usbvirt_device_t *device)
+{
+	if (list_empty(&device_list)) {
+		return NULL;
+	}
+	
+	link_t *pos;
+	for (pos = device_list.next; pos != &device_list; pos = pos->next) {
+		virtual_device_t *dev
+		    = list_get_instance(pos, virtual_device_t, link);
+		if (dev->device == device) {
+			return dev;
+		}
+	}
+	
+	return NULL;
+}
+
+/** Find virtual device wrapper by its id. */
+static virtual_device_t *find_device_by_id(ipcarg_t id)
+{
+	if (list_empty(&device_list)) {
+		return NULL;
+	}
+	
+	link_t *pos;
+	for (pos = device_list.next; pos != &device_list; pos = pos->next) {
+		virtual_device_t *dev
+		    = list_get_instance(pos, virtual_device_t, link);
+		if (dev->id == id) {
+			return dev;
+		}
+	}
+	
+	return NULL;
+}
+
+/** Reply to a control transfer. */
+static int control_transfer_reply(usbvirt_device_t *device,
+	    usb_endpoint_t endpoint, void *buffer, size_t size)
+{
+	usbvirt_control_transfer_t *transfer = &device->current_control_transfers[endpoint];
+	if (transfer->data != NULL) {
+		free(transfer->data);
+	}
+	transfer->data = malloc(size);
+	memcpy(transfer->data, buffer, size);
+	transfer->data_size = size;
+	
+	return EOK;
+}
+
+/** Initialize virtual device. */
+static void device_init(usbvirt_device_t *dev)
+{
+	dev->transaction_out = transaction_out;
+	dev->transaction_setup = transaction_setup;
+	dev->transaction_in = transaction_in;
+	
+	dev->control_transfer_reply = control_transfer_reply;
+	
+	dev->debug = user_debug;
+	dev->lib_debug = lib_debug;
+	
+	dev->state = USBVIRT_STATE_DEFAULT;
+	dev->address = 0;
+	dev->new_address = -1;
+	
+	size_t i;
+	for (i = 0; i < USB11_ENDPOINT_MAX; i++) {
+		usbvirt_control_transfer_t *transfer = &dev->current_control_transfers[i];
+		transfer->direction = 0;
+		transfer->request = NULL;
+		transfer->request_size = 0;
+		transfer->data = NULL;
+		transfer->data_size = 0;
+	}
+}
+
+/** Add a virtual device.
+ * The returned device (if not NULL) shall be destroy via destroy_device().
+ */
+static virtual_device_t *add_device(usbvirt_device_t *dev)
+{
+	assert(find_device(dev) == NULL);
+	virtual_device_t *new_device
+	    = (virtual_device_t *) malloc(sizeof(virtual_device_t));
+	
+	new_device->device = dev;
+	link_initialize(&new_device->link);
+	
+	list_append(&new_device->link, &device_list);
+	
+	return new_device;
+}
+
+/** Destroy virtual device. */
+static void destroy_device(virtual_device_t *dev)
+{
+	if (dev->vhcd_phone > 0) {
+		ipc_hangup(dev->vhcd_phone);
+	}
+	
+	list_remove(&dev->link);
+	
+	free(dev);
+}
+
+/** Callback connection handler. */
+static void callback_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	// FIXME - determine which device just called back
+	virtual_device_t *dev = find_device_by_id(0);
+	if (dev == NULL) {
+		ipc_answer_0(iid, EINVAL);
+		printf("Ooops\n");
+		return;
+	}
+
+	device_callback_connection(dev->device, iid, icall);
+}
+
+/** Create necessary phones for comunication with virtual HCD.
+ * This function wraps following calls:
+ * -# open <code>/dev/devices/\\vhc for reading
+ * -# access phone of file opened in previous step
+ * -# create callback through just opened phone
+ * -# create handler for calling on data from host to function
+ * -# return the (outgoing) phone
+ *
+ * @warning This function is wrapper for several actions and therefore
+ * it is not possible - in case of error - to determine at which point
+ * error occured.
+ *
+ * @param hcd_path HCD identification under devfs
+ *     (without <code>/dev/usb/</code>).
+ * @param dev Device to connect.
+ * @return EOK on success or error code from errno.h.
+ */
+int usbvirt_connect(usbvirt_device_t *dev)
+{
+	virtual_device_t *virtual_device = find_device(dev);
+	if (virtual_device != NULL) {
+		return EEXISTS;
+	}
+	
+	const char *vhc_path = "/vhc";
+	int rc;
+	devman_handle_t handle;
+
+	rc = devman_device_get_handle(vhc_path, &handle, 0);
+	if (rc != EOK) {
+		printf("devman_device_get_handle() failed\n");
+		return rc;
+	}
+	
+	int hcd_phone = devman_device_connect(handle, 0);
+	
+	if (hcd_phone < 0) {
+		printf("devman_device_connect() failed\n");
+		return hcd_phone;
+	}
+	
+	ipcarg_t phonehash;
+	rc = ipc_connect_to_me(hcd_phone, 0, 0, 0, &phonehash);
+	if (rc != EOK) {
+		printf("ipc_connect_to_me() failed\n");
+		return rc;
+	}
+	
+	device_init(dev);
+	
+	virtual_device = add_device(dev);
+	virtual_device->vhcd_phone = hcd_phone;
+	virtual_device->id = 0;
+	
+	async_new_connection(phonehash, 0, NULL, callback_connection);
+	
+	return EOK;
+}
+
+/** Prepares device as local.
+ * This is useful if you want to have a virtual device in the same task
+ * as HCD.
+ *
+ * @param dev Device to connect.
+ * @return Error code.
+ * @retval EOK Device connected.
+ * @retval EEXISTS This device is already connected.
+ */
+int usbvirt_connect_local(usbvirt_device_t *dev)
+{
+	virtual_device_t *virtual_device = find_device(dev);
+	if (virtual_device != NULL) {
+		return EEXISTS;
+	}
+	
+	device_init(dev);
+	
+	virtual_device = add_device(dev);
+	virtual_device->vhcd_phone = -1;
+	virtual_device->id = 0;
+	
+	return EOK;
+}
+
+/** Disconnects device from HCD.
+ *
+ * @param dev Device to be disconnected.
+ * @return Error code.
+ * @retval EOK Device connected.
+ * @retval ENOENT This device is not connected.
+ */
+int usbvirt_disconnect(usbvirt_device_t *dev)
+{
+	virtual_device_t *virtual_device = find_device(dev);
+	if (virtual_device == NULL) {
+		return ENOENT;
+	}
+	
+	destroy_device(virtual_device);
+	
+	return EOK;
+}
+
+
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/private.h
===================================================================
--- uspace/lib/usbvirt/private.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/private.h	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,91 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Virtual USB private header.
+ */
+#ifndef LIBUSBVIRT_PRIVATE_H_
+#define LIBUSBVIRT_PRIVATE_H_
+
+#include "device.h"
+#include "hub.h"
+
+
+#define DEVICE_HAS_OP(dev, op) \
+	( \
+		(  ((dev)->ops) != NULL  ) \
+		&& \
+		(  ((dev)->ops->op) != NULL  ) \
+	)
+
+int usbvirt_data_to_host(struct usbvirt_device *dev,
+    usb_endpoint_t endpoint, void *buffer, size_t size);
+
+int handle_incoming_data(struct usbvirt_device *dev,
+    usb_endpoint_t endpoint, void *buffer, size_t size);
+
+int control_pipe(usbvirt_device_t *device, usbvirt_control_transfer_t *transfer);
+
+int handle_std_request(usbvirt_device_t *device, usb_device_request_setup_packet_t *request, uint8_t *data);
+
+void device_callback_connection(usbvirt_device_t *device, ipc_callid_t iid, ipc_call_t *icall);
+
+int transaction_setup(usbvirt_device_t *device, usb_endpoint_t endpoint,
+    void *buffer, size_t size);
+int transaction_out(usbvirt_device_t *device, usb_endpoint_t endpoint,
+    void *buffer, size_t size);
+int transaction_in(usbvirt_device_t *device, usb_endpoint_t endpoint,
+    void *buffer, size_t size, size_t *data_size);
+
+
+void user_debug(usbvirt_device_t *device, int level, uint8_t tag,
+    const char *format, ...);
+void lib_debug(usbvirt_device_t *device, int level, uint8_t tag,
+    const char *format, ...);
+    
+static inline const char *str_device_state(usbvirt_device_state_t state)
+{
+	switch (state) {
+		case USBVIRT_STATE_DEFAULT:
+			return "default";
+		case USBVIRT_STATE_ADDRESS:
+			return "address";
+		case USBVIRT_STATE_CONFIGURED:
+			return "configured";
+		default:
+			return "unknown";
+	}
+}
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/stdreq.c
===================================================================
--- uspace/lib/usbvirt/stdreq.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/stdreq.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,212 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Preprocessing of standard device requests.
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <mem.h>
+#include <usb/devreq.h>
+
+#include "private.h"
+
+
+
+/*
+ * All sub handlers must return EFORWARD to inform the caller that
+ * they were not able to process the request (yes, it is abuse of
+ * this error code but such error code shall not collide with anything
+ * else in this context).
+ */
+ 
+/** GET_DESCRIPTOR handler. */
+static int handle_get_descriptor(usbvirt_device_t *device,
+    uint8_t type, uint8_t index, uint16_t language,
+    uint16_t length)
+{
+	/* 
+	 * Standard device descriptor.
+	 */
+	if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) {
+		if (device->descriptors && device->descriptors->device) {
+			return device->control_transfer_reply(device, 0,
+			    device->descriptors->device,
+			    device->descriptors->device->length);
+		} else {
+			return EFORWARD;
+		}
+	}
+	
+	/*
+	 * Configuration descriptor together with interface, endpoint and
+	 * class-specific descriptors.
+	 */
+	if (type == USB_DESCTYPE_CONFIGURATION) {
+		if (!device->descriptors) {
+			return EFORWARD;
+		}
+		if (index >= device->descriptors->configuration_count) {
+			return EFORWARD;
+		}
+		/* Copy the data. */
+		usbvirt_device_configuration_t *config = &device->descriptors
+		    ->configuration[index];
+		uint8_t *all_data = malloc(config->descriptor->total_length);
+		if (all_data == NULL) {
+			return ENOMEM;
+		}
+		
+		uint8_t *ptr = all_data;
+		memcpy(ptr, config->descriptor, config->descriptor->length);
+		ptr += config->descriptor->length;
+		size_t i;
+		for (i = 0; i < config->extra_count; i++) {
+			usbvirt_device_configuration_extras_t *extra
+			    = &config->extra[i];
+			memcpy(ptr, extra->data, extra->length);
+			ptr += extra->length;
+		}
+		
+		int rc = device->control_transfer_reply(device, 0,
+		    all_data, config->descriptor->total_length);
+		
+		free(all_data);
+		
+		return rc;
+	}
+	
+	return EFORWARD;
+}
+
+/** SET_ADDRESS handler. */
+static int handle_set_address(usbvirt_device_t *device,
+    uint16_t new_address,
+    uint16_t zero1, uint16_t zero2)
+{
+	if ((zero1 != 0) || (zero2 != 0)) {
+		return EINVAL;
+	}
+	
+	if (new_address > 127) {
+		return EINVAL;
+	}
+	
+	device->new_address = new_address;
+	
+	return EOK;
+}
+
+/** SET_CONFIGURATION handler. */
+static int handle_set_configuration(usbvirt_device_t *device,
+    uint16_t configuration_value,
+    uint16_t zero1, uint16_t zero2)
+{
+	if ((zero1 != 0) || (zero2 != 0)) {
+		return EINVAL;
+	}
+	
+	/*
+	 * Configuration value is 1 byte information.
+	 */
+	if (configuration_value > 255) {
+		return EINVAL;
+	}
+	
+	/*
+	 * Do nothing when in default state. According to specification,
+	 * this is not specified.
+	 */
+	if (device->state == USBVIRT_STATE_DEFAULT) {
+		return EOK;
+	}
+	
+	if (configuration_value == 0) {
+		device->state = USBVIRT_STATE_ADDRESS;
+	} else {
+		/*
+		* TODO: browse provided configurations and verify that
+		* user selected existing configuration.
+		*/
+		device->state = USBVIRT_STATE_CONFIGURED;
+		if (device->descriptors) {
+			device->descriptors->current_configuration
+			    = configuration_value;
+		}
+	}
+		
+	return EOK;
+}
+
+#define HANDLE_REQUEST(request, data, type, dev, user_callback, default_handler) \
+	do { \
+		if ((request)->request == (type)) { \
+			int _rc = EFORWARD; \
+			if (((dev)->ops) && ((dev)->ops->standard_request_ops) \
+			    && ((dev)->ops->standard_request_ops->user_callback)) { \
+				_rc = (dev)->ops->standard_request_ops->\
+				    user_callback(dev, request, data); \
+			} \
+			if (_rc == EFORWARD) { \
+				default_handler; \
+			} \
+			return _rc; \
+		} \
+	} while (false)
+
+/** Handle standard device request. */
+int handle_std_request(usbvirt_device_t *device,
+    usb_device_request_setup_packet_t *request, uint8_t *data)
+{
+	device->lib_debug(device, 3, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO,
+	    "handling standard request %d", request->request);
+	
+	HANDLE_REQUEST(request, data, USB_DEVREQ_GET_DESCRIPTOR,
+	    device, on_get_descriptor,
+	    handle_get_descriptor(device, request->value_high, request->value_low,
+	        request->index, request->length));
+	
+	HANDLE_REQUEST(request, data, USB_DEVREQ_SET_ADDRESS,
+	    device, on_set_address,
+	    handle_set_address(device, request->value,
+	        request->index, request->length));
+	
+	HANDLE_REQUEST(request, data, USB_DEVREQ_SET_CONFIGURATION,
+	    device, on_set_configuration,
+	    handle_set_configuration(device, request->value,
+	        request->index, request->length));
+	
+	return ENOTSUP;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbvirt/transaction.c
===================================================================
--- uspace/lib/usbvirt/transaction.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
+++ uspace/lib/usbvirt/transaction.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -0,0 +1,267 @@
+/*
+ * 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 libusbvirt usb
+ * @{
+ */
+/** @file
+ * @brief Transaction processing.
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <mem.h>
+
+#include "hub.h"
+#include "private.h"
+
+static usb_direction_t setup_transaction_direction(usbvirt_device_t *,
+    usb_endpoint_t, void *, size_t);
+static void process_control_transfer(usbvirt_device_t *,
+    usb_endpoint_t, usbvirt_control_transfer_t *);
+
+/** Convert virtual USB transaction type to string.
+ */
+const char *usbvirt_str_transaction_type(usbvirt_transaction_type_t type)
+{
+	switch (type) {
+		case USBVIRT_TRANSACTION_SETUP:
+			return "setup";
+		case USBVIRT_TRANSACTION_IN:
+			return "in";
+		case USBVIRT_TRANSACTION_OUT:
+			return "out";
+		default:
+			return "unknown";
+	}
+}
+
+/** SETUP transaction handling.
+ * The setup transaction only prepares control transfer on given endpoint.
+ */
+int transaction_setup(usbvirt_device_t *device, usb_endpoint_t endpoint,
+    void *buffer, size_t size)
+{
+	device->lib_debug(device, 1, USBVIRT_DEBUGTAG_TRANSACTION,
+	    "setup transaction: endpoint=%d, size=%u", endpoint, size);
+	
+	usbvirt_control_transfer_t *transfer = &device->current_control_transfers[endpoint];
+	
+	if (transfer->request != NULL) {
+		free(transfer->request);
+	}
+	if (transfer->data != NULL) {
+		free(transfer->data);
+	}
+	
+	transfer->direction = setup_transaction_direction(device, endpoint,
+	    buffer, size);
+	transfer->request = malloc(size);
+	memcpy(transfer->request, buffer, size);
+	transfer->request_size = size;
+	transfer->data = NULL;
+	transfer->data_size = 0;
+	
+	if (transfer->direction == USB_DIRECTION_IN) {
+		process_control_transfer(device, endpoint, transfer);
+	}
+	
+	return EOK;
+}
+
+/** OUT transaction handling.
+ * The OUT transaction can trigger processing of a control transfer.
+ */
+int transaction_out(usbvirt_device_t *device, usb_endpoint_t endpoint,
+    void *buffer, size_t size)
+{
+	device->lib_debug(device, 1, USBVIRT_DEBUGTAG_TRANSACTION,
+	    "out transaction: endpoint=%d, size=%u", endpoint, size);
+	
+	/*
+	 * First check whether it is a transaction over control pipe.
+	 */
+	usbvirt_control_transfer_t *transfer = &device->current_control_transfers[endpoint];
+	if (transfer->request != NULL) {
+		if (transfer->direction == USB_DIRECTION_OUT) {
+			/*
+			 * For out transactions, append the data to the buffer.
+			 */
+			uint8_t *new_buffer = (uint8_t *) malloc(transfer->data_size + size);
+			if (transfer->data) {
+				memcpy(new_buffer, transfer->data, transfer->data_size);
+			}
+			memcpy(new_buffer + transfer->data_size, buffer, size);
+			
+			if (transfer->data) {
+				free(transfer->data);
+			}
+			transfer->data = new_buffer;
+			transfer->data_size += size;
+		} else {
+			/*
+			 * For in transactions, this means end of the
+			 * transaction.
+			 */
+			free(transfer->request);
+			if (transfer->data) {
+				free(transfer->data);
+			}
+			transfer->request = NULL;
+			transfer->request_size = 0;
+			transfer->data = NULL;
+			transfer->data_size = 0;
+		}
+		
+		return EOK;
+	}
+	
+	/*
+	 * Otherwise, announce that some data has come.
+	 */
+	if (device->ops && device->ops->on_data) {
+		return device->ops->on_data(device, endpoint, buffer, size);
+	} else {
+		return ENOTSUP;
+	}
+}
+
+/** IN transaction handling.
+ * The IN transaction can trigger processing of a control transfer.
+ */
+int transaction_in(usbvirt_device_t *device, usb_endpoint_t endpoint,
+    void *buffer, size_t size, size_t *data_size)
+{
+	device->lib_debug(device, 1, USBVIRT_DEBUGTAG_TRANSACTION,
+	    "in transaction: endpoint=%d, size=%u", endpoint, size);
+	
+	/*
+	 * First check whether it is a transaction over control pipe.
+	 */
+	usbvirt_control_transfer_t *transfer = &device->current_control_transfers[endpoint];
+	if (transfer->request != NULL) {
+		if (transfer->direction == USB_DIRECTION_OUT) {
+			/*
+			 * This means end of input data.
+			 */
+			process_control_transfer(device, endpoint, transfer);
+		} else {
+			/*
+			 * For in transactions, this means sending next part
+			 * of the buffer.
+			 */
+			// FIXME: handle when the HC wants the data back
+			// in more chunks
+			size_t actual_size = 0;
+			if (transfer->data) {
+				actual_size = transfer->data_size;
+			}
+			if (actual_size > size) {
+				actual_size = size;
+			}
+			if (actual_size > 0) {
+				memcpy(buffer, transfer->data, actual_size);
+				if (data_size) {
+					*data_size = actual_size;
+				}
+			}
+		}
+		
+		return EOK;
+	}
+	
+	if (size == 0) {
+		return EINVAL;
+	}
+	
+	int rc = 1;
+	
+	if (device->ops && device->ops->on_data_request) {
+		rc = device->ops->on_data_request(device, endpoint, buffer, size, data_size);
+	}
+	
+	return rc;
+}
+
+/** Determine direction of control transfer.
+ * First, try the user provided callback, otherwise guess, believing that
+ * it uses the same format as control pipe 0.
+ */
+static usb_direction_t setup_transaction_direction(usbvirt_device_t *device,
+    usb_endpoint_t endpoint,
+    void *data, size_t size)
+{
+	int direction = -1;
+	if (device->ops && device->ops->decide_control_transfer_direction) {
+		direction = device->ops->decide_control_transfer_direction(endpoint,
+		    data, size);
+	}
+	
+	/*
+	 * If the user-supplied routine have not handled the direction
+	 * (or simply was not provided) we will guess, hoping that it 
+	 * uses same format as standard request on control pipe zero.
+	 */
+	if (direction < 0) {
+		if (size > 0) {
+			uint8_t *ptr = (uint8_t *) data;
+			if ((ptr[0] & 128) == 128) {
+				direction = USB_DIRECTION_IN;
+			} else {
+				direction = USB_DIRECTION_OUT;
+			}
+		} else {
+			/* This shall not happen anyway. */
+			direction = USB_DIRECTION_OUT;
+		}
+	}
+	
+	return (usb_direction_t) direction;
+}
+
+/** Process control transfer.
+ */
+static void process_control_transfer(usbvirt_device_t *device,
+    usb_endpoint_t endpoint,
+    usbvirt_control_transfer_t *transfer)
+{
+	int rc = EFORWARD;
+	
+	if (device->ops && device->ops->on_control_transfer) {
+		rc = device->ops->on_control_transfer(device, endpoint, transfer);
+	}
+	
+	if (rc == EFORWARD) {
+		if (endpoint == 0) {
+			rc = control_pipe(device, transfer);
+		}
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -113,5 +113,6 @@
 	printf(NAME ": ATA disk driver\n");
 
-	printf("I/O address %p/%p\n", ctl_physical, cmd_physical);
+	printf("I/O address %p/%p\n", (void *) ctl_physical,
+	    (void *) cmd_physical);
 
 	if (ata_bd_init() != EOK)
@@ -181,5 +182,5 @@
 	}
 
-	printf(" %" PRIu64 " blocks", d->blocks, d->blocks / (2 * 1024));
+	printf(" %" PRIu64 " blocks", d->blocks);
 
 	mbytes = d->blocks / (2 * 1024);
Index: uspace/srv/bd/part/guid_part/guid_part.c
===================================================================
--- uspace/srv/bd/part/guid_part/guid_part.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/bd/part/guid_part/guid_part.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -155,5 +155,5 @@
 
 	if (block_size < 512 || (block_size % 512) != 0) {
-		printf(NAME ": invalid block size %d.\n");
+		printf(NAME ": invalid block size %zu.\n", block_size);
 		return ENOTSUP;
 	}
Index: uspace/srv/bd/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/bd/part/mbr_part/mbr_part.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/bd/part/mbr_part/mbr_part.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -206,5 +206,5 @@
 
 	if (block_size < 512 || (block_size % 512) != 0) {
-		printf(NAME ": invalid block size %d.\n");
+		printf(NAME ": invalid block size %zu.\n", block_size);
 		return ENOTSUP;
 	}
Index: uspace/srv/bd/rd/rd.c
===================================================================
--- uspace/srv/bd/rd/rd.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/bd/rd/rd.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -230,5 +230,6 @@
 	}
 	
-	printf("%s: Found RAM disk at %p, %d bytes\n", NAME, rd_ph_addr, rd_size);
+	printf("%s: Found RAM disk at %p, %zu bytes\n", NAME,
+	    (void *) rd_ph_addr, rd_size);
 	
 	int rc = devmap_driver_register(NAME, rd_connection);
Index: uspace/srv/clip/clip.c
===================================================================
--- uspace/srv/clip/clip.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/clip/clip.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -172,6 +172,5 @@
 			break;
 		default:
-			if (!(callid & IPC_CALLID_NOTIFICATION))
-				ipc_answer_0(callid, ENOENT);
+			ipc_answer_0(callid, ENOENT);
 		}
 	}
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/devman/devman.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -117,4 +117,12 @@
 	printf(NAME": the '%s' driver was added to the list of available "
 	    "drivers.\n", drv->name);
+
+	printf(NAME ": match ids:");
+	link_t *cur;
+	for (cur = drv->match_ids.ids.next; cur != &drv->match_ids.ids; cur = cur->next) {
+		match_id_t *match_id = list_get_instance(cur, match_id_t, link);
+		printf(" %d:%s", match_id->score, match_id->id);
+	}
+	printf("\n");
 }
 
@@ -1020,5 +1028,5 @@
 	
 	size_t idx = get_new_class_dev_idx(cl);
-	asprintf(&dev_name, "%s%d", base_name, idx);
+	asprintf(&dev_name, "%s%zu", base_name, idx);
 	
 	return dev_name;
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/devman/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -36,4 +36,5 @@
  */
 
+#include <inttypes.h>
 #include <assert.h>
 #include <ipc/services.h>
@@ -405,6 +406,5 @@
 			break;
 		default:
-			if (!(callid & IPC_CALLID_NOTIFICATION))
-				ipc_answer_0(callid, ENOENT);
+			ipc_answer_0(callid, ENOENT);
 		}
 	}
@@ -418,6 +418,6 @@
 	node_t *dev = find_dev_node(&device_tree, handle);
 	if (dev == NULL) {
-		printf(NAME ": devman_forward error - no device with handle %x "
-		    "was found.\n", handle);
+		printf(NAME ": devman_forward error - no device with handle %" PRIun
+		    " was found.\n", handle);
 		ipc_answer_0(iid, ENOENT);
 		return;
@@ -435,6 +435,6 @@
 	
 	if (driver == NULL) {
-		printf(NAME ": devman_forward error - the device is not in "
-		    "usable state.\n", handle);
+		printf(NAME ": devman_forward error - the device is not in %" PRIun
+		    " usable state.\n", handle);
 		ipc_answer_0(iid, ENOENT);
 		return;
@@ -450,5 +450,5 @@
 		printf(NAME ": devman_forward: cound not forward to driver %s ",
 		    driver->name);
-		printf("the driver's phone is %x).\n", driver->phone);
+		printf("the driver's phone is %" PRIun ").\n", driver->phone);
 		ipc_answer_0(iid, EINVAL);
 		return;
Index: uspace/srv/devmap/devmap.c
===================================================================
--- uspace/srv/devmap/devmap.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/devmap/devmap.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -555,5 +555,5 @@
 	if (devmap_device_find_name(namespace->name, device->name) != NULL) {
 		printf("%s: Device '%s/%s' already registered\n", NAME,
-		    device->namespace, device->name);
+		    device->namespace->name, device->name);
 		devmap_namespace_destroy(namespace);
 		fibril_mutex_unlock(&devices_list_mutex);
@@ -1052,6 +1052,5 @@
 			break;
 		default:
-			if (!(callid & IPC_CALLID_NOTIFICATION))
-				ipc_answer_0(callid, ENOENT);
+			ipc_answer_0(callid, ENOENT);
 		}
 	}
@@ -1111,6 +1110,5 @@
 			break;
 		default:
-			if (!(callid & IPC_CALLID_NOTIFICATION))
-				ipc_answer_0(callid, ENOENT);
+			ipc_answer_0(callid, ENOENT);
 		}
 	}
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hid/console/console.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -804,5 +804,5 @@
 			if (screenbuffer_init(&consoles[i].scr,
 			    fb_info.cols, fb_info.rows) == NULL) {
-				printf(NAME ": Unable to allocate screen buffer %u\n", i);
+				printf(NAME ": Unable to allocate screen buffer %zu\n", i);
 				return false;
 			}
@@ -813,5 +813,5 @@
 			
 			char vc[DEVMAP_NAME_MAXLEN + 1];
-			snprintf(vc, DEVMAP_NAME_MAXLEN, "%s/vc%u", NAMESPACE, i);
+			snprintf(vc, DEVMAP_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
 			
 			if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) {
Index: uspace/srv/hid/console/gcons.c
===================================================================
--- uspace/srv/hid/console/gcons.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hid/console/gcons.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -157,5 +157,5 @@
 		
 		char data[5];
-		snprintf(data, 5, "%u", index + 1);
+		snprintf(data, 5, "%zu", index + 1);
 		
 		size_t i;
Index: uspace/srv/hid/fb/serial_console.c
===================================================================
--- uspace/srv/hid/fb/serial_console.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hid/fb/serial_console.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -47,4 +47,5 @@
 #include <io/style.h>
 #include <str.h>
+#include <inttypes.h>
 #include <io/screenbuffer.h>
 
@@ -135,5 +136,6 @@
 	
 	char control[MAX_CONTROL];
-	snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
+	snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f",
+	    row + 1, col + 1);
 	serial_puts(control);
 }
@@ -253,5 +255,5 @@
 {
 	char control[MAX_CONTROL];
-	snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);
+	snprintf(control, MAX_CONTROL, "\033[0;%" PRIun "r", last_row);
 	serial_puts(control);
 }
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -50,4 +50,5 @@
 #include <sysinfo.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include "s3c24xx_ts.h"
@@ -136,6 +137,6 @@
 	ts->last_y = 0;
 
-	printf(NAME ": device at physical address 0x%x, inr %d.\n",
-	    ts->paddr, inr);
+	printf(NAME ": device at physical address %p, inr %" PRIun ".\n",
+	    (void *) ts->paddr, inr);
 
 	async_set_interrupt_received(s3c24xx_ts_irq_handler);
Index: uspace/srv/hw/char/i8042/i8042.c
===================================================================
--- uspace/srv/hw/char/i8042/i8042.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hw/char/i8042/i8042.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -46,4 +46,5 @@
 #include <stdio.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include "i8042.h"
@@ -201,5 +202,6 @@
 	ipc_register_irq(inr_a, device_assign_devno(), 0, &i8042_kbd);
 	ipc_register_irq(inr_b, device_assign_devno(), 0, &i8042_kbd);
-	printf("%s: registered for interrupts %d and %d\n", NAME, inr_a, inr_b);
+	printf("%s: registered for interrupts %" PRIun " and %" PRIun "\n",
+	    NAME, inr_a, inr_b);
 
 	wait_ready();
@@ -262,5 +264,5 @@
 			break;
 		case IPC_FIRST_USER_METHOD:
-			printf(NAME ": write %d to devid %d\n",
+			printf(NAME ": write %" PRIun " to devid %d\n",
 			    IPC_GET_ARG1(call), dev_id);
 			i8042_port_write(dev_id, IPC_GET_ARG1(call));
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -48,4 +48,5 @@
 #include <sysinfo.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include "s3c24xx_uart.h"
@@ -95,5 +96,6 @@
 	if (rc != EOK) {
 		devmap_hangup_phone(DEVMAP_DRIVER);
-		printf(NAME ": Unable to register device %s.\n");
+		printf(NAME ": Unable to register device %s.\n",
+		    NAMESPACE "/" NAME);
 		return -1;
 	}
@@ -134,5 +136,5 @@
 			break;
 		case CHAR_WRITE_BYTE:
-			printf(NAME ": write %d to device\n",
+			printf(NAME ": write %" PRIun " to device\n",
 			    IPC_GET_ARG1(call));
 			s3c24xx_uart_sendb(uart, (uint8_t) IPC_GET_ARG1(call));
@@ -185,6 +187,6 @@
 	uart->client_phone = -1;
 
-	printf(NAME ": device at physical address 0x%x, inr %d.\n",
-	    uart->paddr, inr);
+	printf(NAME ": device at physical address %p, inr %" PRIun ".\n",
+	    (void *) uart->paddr, inr);
 
 	async_set_interrupt_received(s3c24xx_uart_irq_handler);
Index: uspace/srv/hw/cir/fhc/fhc.c
===================================================================
--- uspace/srv/hw/cir/fhc/fhc.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hw/cir/fhc/fhc.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -129,5 +129,5 @@
 	}
 	
-	printf(NAME ": FHC UART registers at %p, %d bytes\n", fhc_uart_phys,
+	printf(NAME ": FHC UART registers at %p, %zu bytes\n", fhc_uart_phys,
 	    fhc_uart_size);
 	
Index: uspace/srv/hw/netif/dp8390/dp8390.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hw/netif/dp8390/dp8390.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -1516,6 +1516,6 @@
 	if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
 	{
-		printf("%s: No ethernet card found at 0x%x\n", 
-			dep->de_name, dep->de_base_port);
+		printf("%s: No ethernet card found at %#lx\n",
+		    dep->de_name, dep->de_base_port);
 		dep->de_mode= DEM_DISABLED;
 		return;
Index: uspace/srv/hw/netif/dp8390/ne2000.c
===================================================================
--- uspace/srv/hw/netif/dp8390/ne2000.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/hw/netif/dp8390/ne2000.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -267,14 +267,14 @@
 	if (!debug)
 	{
-		printf("%s: NE%d000 at %X:%d\n",
-			dep->de_name, dep->de_16bit ? 2 : 1,
-			dep->de_base_port, dep->de_irq);
+		printf("%s: NE%d000 at %#lx:%d\n",
+		    dep->de_name, dep->de_16bit ? 2 : 1,
+		    dep->de_base_port, dep->de_irq);
 	}
 	else
 	{
 		printf("%s: Novell NE%d000 ethernet card at I/O address "
-			"0x%X, memory size 0x%X, irq %d\n",
-			dep->de_name, dep->de_16bit ? 2 : 1,
-			dep->de_base_port, dep->de_ramsize, dep->de_irq);
+		    "%#lx, memory size %#lx, irq %d\n",
+		    dep->de_name, dep->de_16bit ? 2 : 1,
+		    dep->de_base_port, dep->de_ramsize, dep->de_irq);
 	}
 }
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/loader/main.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -411,6 +411,5 @@
 			break;
 		}
-		if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&
-		    IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) {
+		if (IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) {
 			DPRINTF("Responding EINVAL to method %d.\n",
 			    IPC_GET_METHOD(call));
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/net/il/arp/arp.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -391,5 +391,5 @@
 	device->packet_dimension.content = mtu;
 	fibril_rwlock_write_unlock(&arp_globals.lock);
-	printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
+	printf("arp - device %d changed mtu to %zu\n\n", device_id, mtu);
 	return EOK;
 }
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/net/il/ip/ip.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -461,5 +461,5 @@
 	
 	if (ip_netif->packet_dimension.content < IP_MIN_CONTENT) {
-		printf("Maximum transmission unit %d bytes is too small, at "
+		printf("Maximum transmission unit %zu bytes is too small, at "
 		    "least %d bytes are needed\n",
 		    ip_netif->packet_dimension.content, IP_MIN_CONTENT);
@@ -502,5 +502,5 @@
 	fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
 
-	printf("%s: Device %d changed MTU to %d\n", NAME, device_id, mtu);
+	printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
 
 	return EOK;
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/net/nil/eth/eth.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -315,5 +315,5 @@
 			device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
 		
-		printf("Device %d already exists:\tMTU\t= %d\n",
+		printf("Device %d already exists:\tMTU\t= %zu\n",
 		    device->device_id, device->mtu);
 		fibril_rwlock_write_unlock(&eth_globals.devices_lock);
@@ -407,5 +407,5 @@
 	}
 	
-	printf("%s: Device registered (id: %d, service: %d: mtu: %d, "
+	printf("%s: Device registered (id: %d, service: %d: mtu: %zu, "
 	    "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n",
 	    NAME, device->device_id, device->service, device->mtu,
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -175,5 +175,5 @@
 			device->mtu = NET_DEFAULT_MTU;
 		
-		printf("Device %d already exists:\tMTU\t= %d\n",
+		printf("Device %d already exists:\tMTU\t= %zu\n",
 		    device->device_id, device->mtu);
 		fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
@@ -232,5 +232,5 @@
 	}
 	
-	printf("%s: Device registered (id: %d, service: %d, mtu: %d)\n",
+	printf("%s: Device registered (id: %d, service: %d, mtu: %zu)\n",
 	    NAME, device->device_id, device->service, device->mtu);
 	fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/net/tl/udp/udp.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -711,5 +711,5 @@
 	int socket_id;
 	size_t addrlen;
-	size_t size;
+	size_t size = 0;
 	ipc_call_t answer;
 	int answer_count;
Index: uspace/srv/ns/task.c
===================================================================
--- uspace/srv/ns/task.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/ns/task.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -262,6 +262,6 @@
 	if (ht == NULL) {
 		/* No such task exists. */
-		retval = ENOENT;
-		goto out;
+		ipc_answer_0(callid, ENOENT);
+		return;
 	}
 
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/taskmon/taskmon.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -60,10 +60,11 @@
 	thread = IPC_GET_ARG3(*call);
 
-	if (asprintf(&s_taskid, "%" PRIuTASKID, taskid) < 0) {
+	if (asprintf(&s_taskid, "%" PRIu64, taskid) < 0) {
 		printf("Memory allocation failed.\n");
 		return;
 	}
 
-	printf(NAME ": Task %" PRIuTASKID " fault in thread %p.\n", taskid, thread);
+	printf(NAME ": Task %" PRIu64 " fault in thread %p.\n", taskid,
+	    (void *) thread);
 
 	fname = "/app/taskdump";
@@ -72,14 +73,14 @@
 	char *dump_fname;
 
-	if (asprintf(&dump_fname, "/data/core%" PRIuTASKID, taskid) < 0) {
+	if (asprintf(&dump_fname, "/data/core%" PRIu64, taskid) < 0) {
 		printf("Memory allocation failed.\n");
 		return;
 	}
 
-	printf(NAME ": Executing %s -c %s -t %s\n", dump_fname, s_taskid);
+	printf(NAME ": Executing %s -c %s -t %s\n", fname, dump_fname, s_taskid);
 	rc = task_spawnl(NULL, fname, fname, "-c", dump_fname, "-t", s_taskid,
 	    NULL);
 #else
-	printf(NAME ": Executing %s -t %s\n", s_taskid);
+	printf(NAME ": Executing %s -t %s\n", fname, s_taskid);
 	rc = task_spawnl(NULL, fname, fname, "-t", s_taskid, NULL);
 #endif
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision 0d6915f7096859a6d55dc5232f1de58b7f6d02d2)
+++ uspace/srv/vfs/vfs_ops.c	(revision b12d3cc3ff8f0ff3656ec8964938909a8bb0ad7a)
@@ -55,5 +55,6 @@
 
 /* Forward declarations of static functions. */
-static int vfs_truncate_internal(fs_handle_t, devmap_handle_t, fs_index_t, aoff64_t);
+static int vfs_truncate_internal(fs_handle_t, devmap_handle_t, fs_index_t,
+    aoff64_t);
 
 /**
@@ -250,4 +251,6 @@
 void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
 {
+	devmap_handle_t devmap_handle;
+
 	/*
 	 * We expect the library to do the device-name to device-handle
@@ -255,5 +258,5 @@
 	 * in the request.
 	 */
-	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+	devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
 	
 	/*
@@ -291,6 +294,6 @@
 	 */
 	char *fs_name;
-	rc = async_data_write_accept((void **) &fs_name, true, 0, FS_NAME_MAXLEN,
-	    0, NULL);
+	rc = async_data_write_accept((void **) &fs_name, true, 0,
+	    FS_NAME_MAXLEN, 0, NULL);
 	if (rc != EOK) {
 		free(mp);
@@ -458,6 +461,6 @@
 
 		phone = vfs_grab_phone(mp_node->fs_handle);
-		rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->devmap_handle,
-		    mp_node->index);
+		rc = async_req_2_0(phone, VFS_OUT_UNMOUNT,
+		    mp_node->devmap_handle, mp_node->index);
 		vfs_release_phone(mp_node->fs_handle, phone);
 		if (rc != EOK) {
@@ -740,6 +743,6 @@
 		aid_t msg;
 		ipc_call_t answer;
-		msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->devmap_handle,
-		    file->node->index, &answer);
+		msg = async_send_2(fs_phone, VFS_OUT_CLOSE,
+		    file->node->devmap_handle, file->node->index, &answer);
 		
 		/* Wait for reply from the FS server. */
@@ -834,11 +837,11 @@
 	ipc_call_t answer;
 	if (read) {
-		if (file->append)
-			file->pos = file->node->size;
-		
 		rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ,
 		    file->node->devmap_handle, file->node->index, file->pos,
 		    &answer);
 	} else {
+		if (file->append)
+			file->pos = file->node->size;
+		
 		rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE,
 		    file->node->devmap_handle, file->node->index, file->pos,
@@ -888,6 +891,6 @@
 {
 	int fd = (int) IPC_GET_ARG1(*request);
-	off64_t off =
-	    (off64_t) MERGE_LOUP32(IPC_GET_ARG2(*request), IPC_GET_ARG3(*request));
+	off64_t off = (off64_t) MERGE_LOUP32(IPC_GET_ARG2(*request),
+	    IPC_GET_ARG3(*request));
 	int whence = (int) IPC_GET_ARG4(*request);
 	
@@ -903,56 +906,57 @@
 	off64_t newoff;
 	switch (whence) {
-		case SEEK_SET:
-			if (off >= 0) {
-				file->pos = (aoff64_t) off;
-				fibril_mutex_unlock(&file->lock);
-				ipc_answer_1(rid, EOK, off);
-				return;
-			}
-			break;
-		case SEEK_CUR:
-			if ((off >= 0) && (file->pos + off < file->pos)) {
-				fibril_mutex_unlock(&file->lock);
-				ipc_answer_0(rid, EOVERFLOW);
-				return;
-			}
-			
-			if ((off < 0) && (file->pos < (aoff64_t) -off)) {
-				fibril_mutex_unlock(&file->lock);
-				ipc_answer_0(rid, EOVERFLOW);
-				return;
-			}
-			
-			file->pos += off;
-			newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
-			
+	case SEEK_SET:
+		if (off >= 0) {
+			file->pos = (aoff64_t) off;
 			fibril_mutex_unlock(&file->lock);
-			ipc_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
-			return;
-		case SEEK_END:
-			fibril_rwlock_read_lock(&file->node->contents_rwlock);
-			aoff64_t size = file->node->size;
-			
-			if ((off >= 0) && (size + off < size)) {
-				fibril_rwlock_read_unlock(&file->node->contents_rwlock);
-				fibril_mutex_unlock(&file->lock);
-				ipc_answer_0(rid, EOVERFLOW);
-				return;
-			}
-			
-			if ((off < 0) && (size < (aoff64_t) -off)) {
-				fibril_rwlock_read_unlock(&file->node->contents_rwlock);
-				fibril_mutex_unlock(&file->lock);
-				ipc_answer_0(rid, EOVERFLOW);
-				return;
-			}
-			
-			file->pos = size + off;
-			newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
-			
+			ipc_answer_1(rid, EOK, off);
+			return;
+		}
+		break;
+	case SEEK_CUR:
+		if ((off >= 0) && (file->pos + off < file->pos)) {
+			fibril_mutex_unlock(&file->lock);
+			ipc_answer_0(rid, EOVERFLOW);
+			return;
+		}
+		
+		if ((off < 0) && (file->pos < (aoff64_t) -off)) {
+			fibril_mutex_unlock(&file->lock);
+			ipc_answer_0(rid, EOVERFLOW);
+			return;
+		}
+		
+		file->pos += off;
+		newoff = (file->pos > OFF64_MAX) ?  OFF64_MAX : file->pos;
+		
+		fibril_mutex_unlock(&file->lock);
+		ipc_answer_2(rid, EOK, LOWER32(newoff),
+		    UPPER32(newoff));
+		return;
+	case SEEK_END:
+		fibril_rwlock_read_lock(&file->node->contents_rwlock);
+		aoff64_t size = file->node->size;
+		
+		if ((off >= 0) && (size + off < size)) {
 			fibril_rwlock_read_unlock(&file->node->contents_rwlock);
 			fibril_mutex_unlock(&file->lock);
-			ipc_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
-			return;
+			ipc_answer_0(rid, EOVERFLOW);
+			return;
+		}
+		
+		if ((off < 0) && (size < (aoff64_t) -off)) {
+			fibril_rwlock_read_unlock(&file->node->contents_rwlock);
+			fibril_mutex_unlock(&file->lock);
+			ipc_answer_0(rid, EOVERFLOW);
+			return;
+		}
+		
+		file->pos = size + off;
+		newoff = (file->pos > OFF64_MAX) ?  OFF64_MAX : file->pos;
+		
+		fibril_rwlock_read_unlock(&file->node->contents_rwlock);
+		fibril_mutex_unlock(&file->lock);
+		ipc_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
+		return;
 	}
 	
@@ -977,6 +981,6 @@
 {
 	int fd = IPC_GET_ARG1(*request);
-	aoff64_t size =
-	    (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(*request), IPC_GET_ARG3(*request));
+	aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(*request),
+	    IPC_GET_ARG3(*request));
 	int rc;
 
