Index: .bzrignore
===================================================================
--- .bzrignore	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ .bzrignore	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -262,2 +262,4 @@
 uspace/lib/c/arch/ia32/_link.ld
 kernel/arch/arm32/_link.ld
+uspace/app/corecfg/corecfg
+uspace/dist/app/corecfg
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/Makefile	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -220,5 +220,4 @@
 	generic/src/mm/km.c \
 	generic/src/mm/reserve.c \
-	generic/src/mm/buddy.c \
 	generic/src/mm/frame.c \
 	generic/src/mm/page.c \
Index: kernel/arch/abs32le/include/arch/mm/page.h
===================================================================
--- kernel/arch/abs32le/include/arch/mm/page.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/abs32le/include/arch/mm/page.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -57,8 +57,8 @@
 
 /* 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_FRAMES_ARCH  1
+#define PTL1_FRAMES_ARCH  1
+#define PTL2_FRAMES_ARCH  1
+#define PTL3_FRAMES_ARCH  1
 
 /* Macros calculating indices for each level. */
Index: kernel/arch/amd64/include/arch/mm/page.h
===================================================================
--- kernel/arch/amd64/include/arch/mm/page.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/amd64/include/arch/mm/page.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -61,8 +61,8 @@
 
 /* Page table sizes for each level. */
-#define PTL0_SIZE_ARCH  ONE_FRAME
-#define PTL1_SIZE_ARCH  ONE_FRAME
-#define PTL2_SIZE_ARCH  ONE_FRAME
-#define PTL3_SIZE_ARCH  ONE_FRAME
+#define PTL0_FRAMES_ARCH  1
+#define PTL1_FRAMES_ARCH  1
+#define PTL2_FRAMES_ARCH  1
+#define PTL3_FRAMES_ARCH  1
 
 /* Macros calculating indices into page tables in each level. */
Index: kernel/arch/arm32/include/arch/mm/page.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/page.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/arm32/include/arch/mm/page.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -73,8 +73,8 @@
 
 /* Page table sizes for each level. */
-#define PTL0_SIZE_ARCH          FOUR_FRAMES
-#define PTL1_SIZE_ARCH          0
-#define PTL2_SIZE_ARCH          0
-#define PTL3_SIZE_ARCH          ONE_FRAME
+#define PTL0_FRAMES_ARCH  4
+#define PTL1_FRAMES_ARCH  1
+#define PTL2_FRAMES_ARCH  1
+#define PTL3_FRAMES_ARCH  1
 
 /* Macros calculating indices into page tables for each level. */
Index: kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c
===================================================================
--- kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -60,5 +60,5 @@
 
 static struct beagleboard {
-	amdm37x_irc_regs_t *irc_addr;
+	omap_irc_regs_t *irc_addr;
 	omap_uart_t uart;
 	amdm37x_gpt_t timer;
@@ -103,5 +103,5 @@
 	    PAGE_NOT_CACHEABLE);
 	ASSERT(beagleboard.irc_addr);
-	amdm37x_irc_init(beagleboard.irc_addr);
+	omap_irc_init(beagleboard.irc_addr);
 
 	/* Initialize timer. Use timer1, because it is in WKUP power domain
@@ -123,5 +123,5 @@
 
 	/* Enable timer interrupt */
-	amdm37x_irc_enable(beagleboard.irc_addr, AMDM37x_GPT1_IRQ);
+	omap_irc_enable(beagleboard.irc_addr, AMDM37x_GPT1_IRQ);
 
 	/* Start timer here */
@@ -147,5 +147,5 @@
 static void bbxm_irq_exception(unsigned int exc_no, istate_t *istate)
 {
-	const unsigned inum = amdm37x_irc_inum_get(beagleboard.irc_addr);
+	const unsigned inum = omap_irc_inum_get(beagleboard.irc_addr);
 
 	irq_t *irq = irq_dispatch_and_lock(inum);
@@ -161,5 +161,5 @@
 	/** amdm37x manual ch. 12.5.2 (p. 2428) places irc ack at the end
 	 * of ISR. DO this to avoid strange behavior. */
-	amdm37x_irc_irq_ack(beagleboard.irc_addr);
+	omap_irc_irq_ack(beagleboard.irc_addr);
 }
 
@@ -188,5 +188,5 @@
 		indev_t *srln = srln_wire(srln_instance, sink);
 		omap_uart_input_wire(&beagleboard.uart, srln);
-		amdm37x_irc_enable(beagleboard.irc_addr, AMDM37x_UART3_IRQ);
+		omap_irc_enable(beagleboard.irc_addr, AMDM37x_UART3_IRQ);
 	}
 #endif
Index: kernel/arch/arm32/src/mach/beaglebone/beaglebone.c
===================================================================
--- kernel/arch/arm32/src/mach/beaglebone/beaglebone.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/arm32/src/mach/beaglebone/beaglebone.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -63,5 +63,5 @@
 
 static struct beaglebone {
-	am335x_irc_regs_t *irc_addr;
+	omap_irc_regs_t *irc_addr;
 	am335x_cm_per_regs_t *cm_per_addr;
 	am335x_cm_dpll_regs_t *cm_dpll_addr;
@@ -104,5 +104,5 @@
 
 	/* Initialize the interrupt controller */
-	am335x_irc_init(bbone.irc_addr);
+	omap_irc_init(bbone.irc_addr);
 }
 
@@ -153,5 +153,5 @@
 	}
 	/* Enable the interrupt */
-	am335x_irc_enable(bbone.irc_addr, AM335x_DMTIMER2_IRQ);
+	omap_irc_enable(bbone.irc_addr, AM335x_DMTIMER2_IRQ);
 	/* Start the timer */
 	am335x_timer_start(&bbone.timer);
@@ -176,5 +176,5 @@
 static void bbone_irq_exception(unsigned int exc_no, istate_t *istate)
 {
-	const unsigned inum = am335x_irc_inum_get(bbone.irc_addr);
+	const unsigned inum = omap_irc_inum_get(bbone.irc_addr);
 
 	irq_t *irq = irq_dispatch_and_lock(inum);
@@ -187,5 +187,5 @@
 	}
 
-	am335x_irc_irq_ack(bbone.irc_addr);
+	omap_irc_irq_ack(bbone.irc_addr);
 }
 
@@ -214,5 +214,5 @@
 		indev_t *srln = srln_wire(srln_instance, sink);
 		omap_uart_input_wire(&bbone.uart, srln);
-		am335x_irc_enable(bbone.irc_addr, AM335x_UART0_IRQ);
+		omap_irc_enable(bbone.irc_addr, AM335x_UART0_IRQ);
 	}
 #endif
Index: kernel/arch/arm32/src/mm/page.c
===================================================================
--- kernel/arch/arm32/src/mm/page.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/arm32/src/mm/page.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -69,5 +69,5 @@
 #ifdef HIGH_EXCEPTION_VECTORS
 	/* Create mapping for exception table at high offset */
-	uintptr_t ev_frame = frame_alloc(ONE_FRAME, FRAME_NONE, 0);
+	uintptr_t ev_frame = frame_alloc(1, FRAME_NONE, 0);
 	page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, ev_frame, flags);
 #else
Index: kernel/arch/arm32/src/ras.c
===================================================================
--- kernel/arch/arm32/src/ras.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/arm32/src/ras.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -51,8 +51,8 @@
 void ras_init(void)
 {
-	uintptr_t frame = frame_alloc(ONE_FRAME,
-	    FRAME_ATOMIC | FRAME_HIGHMEM, 0);
+	uintptr_t frame =
+	    frame_alloc(1, FRAME_ATOMIC | FRAME_HIGHMEM, 0);
 	if (!frame)
-		frame = frame_alloc(ONE_FRAME, FRAME_LOWMEM, 0);
+		frame = frame_alloc(1, FRAME_LOWMEM, 0);
 	
 	ras_page = (uintptr_t *) km_map(frame,
Index: kernel/arch/ia32/include/arch/mm/page.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/page.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/ia32/include/arch/mm/page.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -66,8 +66,8 @@
 
 /* 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_FRAMES_ARCH  1
+#define PTL1_FRAMES_ARCH  1
+#define PTL2_FRAMES_ARCH  1
+#define PTL3_FRAMES_ARCH  1
 
 /* Macros calculating indices for each level. */
Index: kernel/arch/ia64/src/mm/vhpt.c
===================================================================
--- kernel/arch/ia64/src/mm/vhpt.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/ia64/src/mm/vhpt.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -42,6 +42,6 @@
 uintptr_t vhpt_set_up(void)
 {
-	vhpt_base = (vhpt_entry_t *) PA2KA(frame_alloc(VHPT_WIDTH - FRAME_WIDTH,
-	    FRAME_ATOMIC, 0));
+	vhpt_base = (vhpt_entry_t *)
+	    PA2KA(frame_alloc(SIZE2FRAMES(VHPT_SIZE), FRAME_ATOMIC, 0));
 	if (!vhpt_base)
 		panic("Kernel configured with VHPT but no memory for table.");
@@ -83,5 +83,5 @@
 void vhpt_invalidate_all()
 {
-	memsetb(vhpt_base, 1 << VHPT_WIDTH, 0);
+	memsetb(vhpt_base, VHPT_SIZE, 0);
 }
 
Index: kernel/arch/mips32/include/arch/mm/page.h
===================================================================
--- kernel/arch/mips32/include/arch/mm/page.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/mips32/include/arch/mm/page.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -78,8 +78,8 @@
 
 /* Macros describing size of page tables in 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_FRAMES_ARCH  1
+#define PTL1_FRAMES_ARCH  1
+#define PTL2_FRAMES_ARCH  1
+#define PTL3_FRAMES_ARCH  1
 
 /* Macros calculating entry indices for each level. */
@@ -196,5 +196,4 @@
 	p->p = 1;
 }
-	
 
 extern void page_arch_init(void);
Index: kernel/arch/mips32/src/mm/tlb.c
===================================================================
--- kernel/arch/mips32/src/mm/tlb.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/mips32/src/mm/tlb.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -48,14 +48,16 @@
 #include <symtab.h>
 
-#define PFN_SHIFT	12
-#define VPN_SHIFT	12
-#define ADDR2VPN(a)	((a) >> VPN_SHIFT)
-#define ADDR2VPN2(a)	(ADDR2VPN((a)) >> 1)
-#define VPN2ADDR(vpn)	((vpn) << VPN_SHIFT)
-#define VPN22ADDR(vpn2)	(VPN2ADDR(vpn2) << 1)
-#define PFN2ADDR(pfn)	((pfn) << PFN_SHIFT)
-
-#define BANK_SELECT_BIT(a)	(((a) >> PAGE_WIDTH) & 1) 
-	
+#define PFN_SHIFT  12
+#define VPN_SHIFT  12
+
+#define ADDR2HI_VPN(a)   ((a) >> VPN_SHIFT)
+#define ADDR2HI_VPN2(a)  (ADDR2HI_VPN((a)) >> 1)
+
+#define HI_VPN2ADDR(vpn)    ((vpn) << VPN_SHIFT)
+#define HI_VPN22ADDR(vpn2)  (HI_VPN2ADDR(vpn2) << 1)
+
+#define LO_PFN2ADDR(pfn)  ((pfn) << PFN_SHIFT)
+
+#define BANK_SELECT_BIT(a)  (((a) >> PAGE_WIDTH) & 1)
 
 /** Initialize TLB.
@@ -266,5 +268,5 @@
 {
 	hi->value = 0;
-	hi->vpn2 = ADDR2VPN2(ALIGN_DOWN(addr, PAGE_SIZE));
+	hi->vpn2 = ADDR2HI_VPN2(ALIGN_DOWN(addr, PAGE_SIZE));
 	hi->asid = asid;
 }
@@ -295,8 +297,8 @@
 		
 		printf("%-4u %-6u %0#10x %-#6x  %1u%1u%1u%1u  %0#10x\n",
-		    i, hi.asid, VPN22ADDR(hi.vpn2), mask.mask,
-		    lo0.g, lo0.v, lo0.d, lo0.c, PFN2ADDR(lo0.pfn));
+		    i, hi.asid, HI_VPN22ADDR(hi.vpn2), mask.mask,
+		    lo0.g, lo0.v, lo0.d, lo0.c, LO_PFN2ADDR(lo0.pfn));
 		printf("                               %1u%1u%1u%1u  %0#10x\n",
-		    lo1.g, lo1.v, lo1.d, lo1.c, PFN2ADDR(lo1.pfn));
+		    lo1.g, lo1.v, lo1.d, lo1.c, LO_PFN2ADDR(lo1.pfn));
 	}
 	
Index: kernel/arch/ppc32/include/arch/mm/page.h
===================================================================
--- kernel/arch/ppc32/include/arch/mm/page.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/ppc32/include/arch/mm/page.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -70,8 +70,8 @@
 
 /* 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_FRAMES_ARCH  1
+#define PTL1_FRAMES_ARCH  1
+#define PTL2_FRAMES_ARCH  1
+#define PTL3_FRAMES_ARCH  1
 
 /* Macros calculating indices into page tables on each level. */
Index: kernel/arch/sparc64/src/mm/sun4u/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/as.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/sparc64/src/mm/sun4u/as.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -63,19 +63,14 @@
 {
 #ifdef CONFIG_TSB
-	/*
-	 * The order must be calculated with respect to the emulated
-	 * 16K page size.
-	 *
-	 */
-	uint8_t order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
-	    sizeof(tsb_entry_t)) >> FRAME_WIDTH);
-	
-	uintptr_t tsb = PA2KA(frame_alloc(order, flags, 0));
+	size_t frames = SIZE2FRAMES((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
+	    sizeof(tsb_entry_t));
+	
+	uintptr_t tsb = PA2KA(frame_alloc(frames, flags, 0));
 	if (!tsb)
 		return -1;
 	
 	as->arch.itsb = (tsb_entry_t *) tsb;
-	as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT *
-	    sizeof(tsb_entry_t));
+	as->arch.dtsb = (tsb_entry_t *) (tsb +
+	    ITSB_ENTRY_COUNT * sizeof(tsb_entry_t));
 	
 	memsetb(as->arch.itsb,
Index: kernel/arch/sparc64/src/mm/sun4v/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/as.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/arch/sparc64/src/mm/sun4v/as.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -66,8 +66,8 @@
 {
 #ifdef CONFIG_TSB
-	uint8_t order = fnzb32(
-		(TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH);
+	size_t frames =
+	    SIZE2FRAMES(TSB_ENTRY_COUNT * sizeof(tsb_entry_t));
 	
-	uintptr_t tsb = frame_alloc(order, flags, 0);
+	uintptr_t tsb = frame_alloc(frames, flags, 0);
 	if (!tsb)
 		return -1;
Index: kernel/genarch/include/genarch/drivers/am335x/irc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/am335x/irc.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/genarch/include/genarch/drivers/am335x/irc.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -38,214 +38,14 @@
 #define KERN_AM335x_IRQC_H_
 
-#define AM335x_IRC_BASE_ADDRESS 0x48200000
-#define AM335x_IRC_SIZE         4096
+#define AM335x_IRC_BASE_ADDRESS     0x48200000
+#define AM335x_IRC_SIZE             4096
 
-#define AM335x_IRC_IRQ_COUNT    128
+#define AM335x_IRC_IRQ_COUNT        128
+#define AM335x_IRC_IRQ_GROUPS_COUNT 4
 
-#include <typedefs.h>
+#define OMAP_IRC_IRQ_COUNT        AM335x_IRC_IRQ_COUNT
+#define OMAP_IRC_IRQ_GROUPS_COUNT AM335x_IRC_IRQ_GROUPS_COUNT
 
-typedef struct {
-	const ioport32_t revision;
-#define AM335x_IRC_REV_MASK 0xFF
-
-	const uint8_t padd0[12];
-
-	/* This register controls the various parameters
-	 * of the OCP interface.
-	 */
-	ioport32_t sysconfig;
-#define AM335x_IRC_SYSCONFIG_AUTOIDLE_FLAG   (1 << 0)
-#define AM335x_IRC_SYSCONFIG_SOFTRESET_FLAG  (1 << 1)
-
-	/* This register provides status information about the module */
-	const ioport32_t sysstatus;
-#define AM335x_IRC_SYSSTATUS_RESET_DONE_FLAG (1 << 0)
-
-	const uint8_t padd1[40];
-
-	/* This register supplies the currently active IRQ interrupt number */
-	ioport32_t sir_irq;
-#define AM335x_IRC_SIR_IRQ_ACTIVEIRQ_MASK       0x7F
-#define AM335x_IRC_SIR_IRQ_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
-
-	/* This register supplies the currently active FIQ interrupt number */
-	const ioport32_t sir_fiq;
-#define AM335x_IRC_FIQ_IRQ_ACTIVEFIQ_MASK       0x7F
-#define AM335x_IRC_FIQ_IRQ_SPURIOUSFIQFLAG_MASK 0xFFFFFFF8
-
-	/* This register contains the new interrupt agreement bits */
-	ioport32_t control;
-#define AM335x_IRC_CONTROL_NEWIRQAGR_FLAG       (1 << 0)
-#define AM335x_IRC_CONTROL_NEWFIQAGR_FLAG       (1 << 1)
-
-	/* This register controls protection of the other registers.
-	 * This register can only be accessed in priviledged mode, regardless
-	 * of the current value of the protection bit.
-	 */
-	ioport32_t protection;
-#define AM335x_IRC_PROTECTION_FLAG              (1 << 0)
-
-	/* This register controls the clock auto-idle for the functional
-	 * clock and the input synchronizers.
-	 */
-	ioport32_t idle;
-#define AM335x_IRC_IDLE_FUNCIDLE_FLAG           (1 << 0)
-#define AM335x_IRC_IDLE_TURBO_FLAG              (1 << 1)
-
-	const uint8_t padd2[12];
-
-	/* This register supplies the currently active IRQ priority level */
-	const ioport32_t irq_priority;
-#define AM335x_IRC_IRQ_PRIORITY_IRQPRIORITY_MASK     0x7F
-#define AM335x_IRC_IRQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
-
-	/* This register supplies the currently active FIQ priority level */
-	const ioport32_t fiq_priority;
-#define AM335x_IRC_FIQ_PRIORITY_FIQPRIORITY_MASK     0x7F
-#define AM335x_IRC_FIQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
-
-	/* This register sets the priority threshold */
-	ioport32_t threshold;
-#define AM335x_IRC_THRESHOLD_PRIORITYTHRESHOLD_MASK     0xFF
-#define AM335x_IRC_THRESHOLD_PRIORITYTHRESHOLD_ENABLED  0x00
-#define AM335x_IRC_THRESHOLD_PRIORITYTHRESHOLD_DISABLED 0xFF
-
-	const uint8_t padd[20];
-
-	struct {
-		/* Raw interrupt input status before masking */
-		const ioport32_t itr;
-
-		/* Interrupt mask */
-		ioport32_t mir;
-
-		/* This register is used to clear the interrupt mask bits,
-		 * Write 1 clears the mask bit to 0.
-		 */
-		ioport32_t mir_clear;
-
-		/* This register is used to set the interrupt mask bits,
-		 * Write 1 sets the mask bit to 1.
-		 */
-		ioport32_t mir_set;
-
-		/* This register is used to set the software interrupt bits,
-		 * it is also used to read the current active software
-		 * interrupts.
-		 * Write 1 sets the software interrups bits to 1.
-		 */
-		ioport32_t isr_set;
-
-		/* This register is used to clear the software interrups bits.
-		 * Write 1 clears the software interrupt bits to 0.
-		 */
-		ioport32_t isr_clear;
-
-		/* This register contains the IRQ status after masking. */
-		const ioport32_t pending_irq;
-
-		/* This register contains the FIQ status after masking. */
-		const ioport32_t pending_fiq;
-	} interrupts[4];
-
-	/* These registers contain the priority for the interrups and
-	 * the FIQ/IRQ steering.
-	 */
-	ioport32_t ilr[AM335x_IRC_IRQ_COUNT];
-/* 0 = Interrupt routed to IRQ, 1 = interrupt routed to FIQ */
-#define AM335x_IRC_ILR_FIQNIRQ_FLAG    (1 << 0)
-#define AM335x_IRC_ILR_PRIORITY_MASK   0x3F
-#define AM335x_IRC_ILR_PRIORITY_SHIFT  2
-
-} am335x_irc_regs_t;
-
-static inline void am335x_irc_init(am335x_irc_regs_t *regs)
-{
-	int i;
-
-	/* Initialization sequence */
-
-	/* 1 - Program the SYSCONFIG register: if necessary, enable the
-	 *     autogating by setting the AUTOIDLE bit.
-	 */
-	regs->sysconfig &= ~AM335x_IRC_SYSCONFIG_AUTOIDLE_FLAG;
-
-	/* 2 - Program the IDLE register: if necessary, disable functional
-	 *     clock autogating or enable synchronizer autogating by setting
-	 *     the FUNCIDLE bit or the TURBO bit accordingly.
-	 */
-	regs->idle &= ~AM335x_IRC_IDLE_FUNCIDLE_FLAG;
-	regs->idle &= ~AM335x_IRC_IDLE_TURBO_FLAG;
-
-	/* 3 - Program ILRm register for each interrupt line: Assign a
-	 *     priority level and set the FIQNIRQ bit for an FIQ interrupt
-	 *     (by default, interrupts are mapped to IRQ and
-	 *     priority is 0 (highest).
-	 */
-
-	for (i = 0; i < AM335x_IRC_IRQ_COUNT; ++i)
-		regs->ilr[i] = 0;
-
-	/* 4 - Program the MIRn register: Enable interrupts (by default,
-	 *     all interrupt lines are masked).
-	 */
-	for (i = 0; i < 4; ++i)
-		regs->interrupts[i].mir_set = 0xFFFFFFFF;
-}
-
-/** Get the currently active IRQ interrupt number
- *
- * @param regs     Pointer to the irc memory mapped registers
- *
- * @return         The active IRQ interrupt number
- */
-static inline unsigned am335x_irc_inum_get(am335x_irc_regs_t *regs)
-{
-	return regs->sir_irq & AM335x_IRC_SIR_IRQ_ACTIVEIRQ_MASK;
-}
-
-/** Reset IRQ output and enable new IRQ generation
- *
- * @param regs    Pointer to the irc memory mapped registers
- */
-static inline void am335x_irc_irq_ack(am335x_irc_regs_t *regs)
-{
-	regs->control = AM335x_IRC_CONTROL_NEWIRQAGR_FLAG;
-}
-
-/** Reset FIQ output and enable new FIQ generation
- *
- * @param regs    Pointer to the irc memory mapped registers
- */
-static inline void am335x_irc_fiq_ack(am335x_irc_regs_t *regs)
-{
-	regs->control = AM335x_IRC_CONTROL_NEWFIQAGR_FLAG;
-}
-
-/** Clear an interrupt mask bit
- *
- * @param regs    Pointer to the irc memory mapped registers
- * @param inum    The interrupt to be enabled
- */
-static inline void am335x_irc_enable(am335x_irc_regs_t *regs, unsigned inum)
-{
-	ASSERT(inum < AM335x_IRC_IRQ_COUNT);
-	const unsigned set = inum / 32;
-	const unsigned pos = inum % 32;
-	regs->interrupts[set].mir_clear = (1 << pos);
-}
-
-/** Set an interrupt mask bit
- *
- * @param regs    Pointer to the irc memory mapped registers
- * @param inum    The interrupt to be disabled
- */
-static inline void am335x_irc_disable(am335x_irc_regs_t *regs, unsigned inum)
-{
-	ASSERT(inum < AM335x_IRC_IRQ_COUNT);
-	const unsigned set = inum / 32;
-	const unsigned pos = inum % 32;
-	regs->interrupts[set].mir_set = (1 << pos);
-}
+#include <genarch/drivers/omap/irc.h>
 
 #endif
Index: kernel/genarch/include/genarch/drivers/amdm37x/irc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/amdm37x/irc.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/genarch/include/genarch/drivers/amdm37x/irc.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -38,165 +38,14 @@
 
 /* AMDM37x TRM p. 1079 */
-#define AMDM37x_IRC_BASE_ADDRESS 0x48200000
-#define AMDM37x_IRC_SIZE 4096
+#define AMDM37x_IRC_BASE_ADDRESS     0x48200000
+#define AMDM37x_IRC_SIZE             4096
 
-#define AMDM37x_IRC_IRQ_COUNT 96
+#define AMDM37x_IRC_IRQ_COUNT        96
+#define AMDM37x_IRC_IRQ_GROUPS_COUNT 3
 
-#include <typedefs.h>
+#define OMAP_IRC_IRQ_COUNT        AMDM37x_IRC_IRQ_COUNT
+#define OMAP_IRC_IRQ_GROUPS_COUNT AMDM37x_IRC_IRQ_GROUPS_COUNT
 
-typedef struct {
-	const ioport32_t revision; /**< Revision */
-#define AMDM37x_IRC_REV_MASK (0xff)
-
-	uint8_t padd0_[12];
-
-	ioport32_t sysconfig; /**< SYS config */
-#define AMDM37x_IRC_SYSCONFIG_AUTOIDLE_FLAG (1 << 0)
-#define AMDM37x_IRC_SYSCONFIG_SOFTRESET_FLAG (1 << 1)
-
-	const ioport32_t sysstatus; /**< SYS status */
-#define AMDM37x_IRC_SYSSTATUS_RESET_DONE_FLAG (1 << 0)
-
-	uint8_t padd1_[40];
-
-	const ioport32_t sir_irq;   /**< Currently active irq number */
-#define AMDM37x_IRC_SIR_IRQ_ACTIVEIRQ_MASK (0x7f)
-#define AMDM37x_IRC_SIR_IRQ_SPURIOUSIRQFLAG_MASK (0xfffffff8)
-
-	const ioport32_t sir_fiq;
-#define AMDM37x_IRC_SIR_FIQ_ACTIVEIRQ_MASK (0x7f)
-#define AMDM37x_IRC_SIR_FIQ_SPURIOUSIRQFLAG_MASK (0xfffffff8)
-
-	ioport32_t control;   /**< New interrupt agreement. */
-#define AMDM37x_IRC_CONTROL_NEWIRQAGR_FLAG (1 << 0)
-#define AMDM37x_IRC_CONTROL_NEWFIQAGR_FLAG (1 << 1)
-
-	ioport32_t protection;  /**< Protect other registers. */
-#define AMDM37x_IRC_PROTECTION_PROETCTION_FLAG (1 << 0)
-
-	ioport32_t idle;   /**< Idle and autogating */
-#define AMDM37x_IRC_IDLE_FUNCIDLE_FLAG (1 << 0)
-#define AMDM37x_IRC_IDLE_TURBO_FLAG (1 << 1)
-
-	uint8_t padd2_[12];
-
-	ioport32_t irq_priority; /**< Active IRQ priority */
-#define AMDM37x_IRC_IRQ_PRIORITY_IRQPRIORITY_MASK (0x7f)
-#define AMDM37x_IRC_IRQ_PRIORITY_SPURIOUSIRQFLAG_MASK (0xfffffff8)
-
-	ioport32_t fiq_priority; /**< Active FIQ priority */
-#define AMDM37x_IRC_FIQ_PRIORITY_FIQPRIORITY_MASK (0x7f)
-#define AMDM37x_IRC_FIQ_PRIORITY_SPURIOUSFIQFLAG_MASK (0xfffffff8)
-
-	ioport32_t threshold; /**< Priority threshold */
-#define AMDM37x_IRC_THRESHOLD_PRIORITYTHRESHOLD_MASK (0xff)
-#define AMDM37x_IRC_THRESHOLD_PRIORITYTHRESHOLD_ENABLED (0x00)
-#define AMDM37x_IRC_THRESHOLD_PRIORITYTHRESHOLD_DISABLED (0xff)
-
-	uint8_t padd3__[20];
-
-	struct {
-		const ioport32_t itr;   /**< Interrupt input status before masking */
-		ioport32_t mir;   /**< Interrupt mask */
-		ioport32_t mir_clear; /**< Clear mir mask bits */
-		ioport32_t mir_set;   /**< Set mir mask bits */
-		ioport32_t isr_set;   /**< Set software interrupt bits */
-		ioport32_t isr_clear; /**< Clear software interrupt bits */
-		const ioport32_t pending_irq; /**< IRQ status after masking */
-		const ioport32_t pending_fiq; /**< FIQ status after masking */
-	} interrupts[3];
-
-	uint8_t padd4_[32];
-
-	ioport32_t ilr[96];   /**< FIQ/IRQ steering */
-#define AMDM37x_IRC_ILR_FIQNIRQ (1 << 0)
-#define AMDM37x_IRC_ILR_PRIORITY_MASK (0x3f)
-#define AMDM37x_IRC_ILR_PRIORITY_SHIFT (2)
-
-} amdm37x_irc_regs_t;
-
-static inline void amdm37x_irc_dump(amdm37x_irc_regs_t *regs)
-{
-#define DUMP_REG(name) \
-	printf("%s %p(%x).\n", #name, &regs->name, regs->name);
-
-	DUMP_REG(revision);
-	DUMP_REG(sysconfig);
-	DUMP_REG(sysstatus);
-	DUMP_REG(sir_irq);
-	DUMP_REG(sir_fiq);
-	DUMP_REG(control);
-	DUMP_REG(protection);
-	DUMP_REG(idle);
-	DUMP_REG(irq_priority);
-	DUMP_REG(fiq_priority);
-	DUMP_REG(threshold);
-
-	for (int i = 0; i < 3; ++i) {
-		DUMP_REG(interrupts[i].itr);
-		DUMP_REG(interrupts[i].mir);
-		DUMP_REG(interrupts[i].isr_set);
-		DUMP_REG(interrupts[i].pending_irq);
-		DUMP_REG(interrupts[i].pending_fiq);
-	}
-	for (int i = 0; i < AMDM37x_IRC_IRQ_COUNT; ++i) {
-		DUMP_REG(ilr[i]);
-	}
-
-#undef DUMP_REG
-}
-
-static inline void amdm37x_irc_init(amdm37x_irc_regs_t *regs)
-{
-	/* AMDM37x TRM sec 12.5.1 p. 2425 */
-	/* Program system config register */
-	//TODO enable this when you know the meaning
-	//regs->sysconfig |= AMDM37x_IRC_SYSCONFIG_AUTOIDLE_FLAG;
-
-	/* Program idle register */
-	//TODO enable this when you know the meaning
-	//regs->sysconfig |= AMDM37x_IRC_IDLE_TURBO_FLAG;
-
-	/* Program ilr[m] assign priority, decide fiq */
-	for (unsigned i = 0; i < AMDM37x_IRC_IRQ_COUNT; ++i) {
-		regs->ilr[i] = 0; /* highest prio(default) route to irq */
-	}
-
-	/* Disable all interrupts */
-	regs->interrupts[0].mir_set = 0xffffffff;
-	regs->interrupts[1].mir_set = 0xffffffff;
-	regs->interrupts[2].mir_set = 0xffffffff;
-}
-
-static inline unsigned amdm37x_irc_inum_get(amdm37x_irc_regs_t *regs)
-{
-	return regs->sir_irq & AMDM37x_IRC_SIR_IRQ_ACTIVEIRQ_MASK;
-}
-
-static inline void amdm37x_irc_irq_ack(amdm37x_irc_regs_t *regs)
-{
-	regs->control = AMDM37x_IRC_CONTROL_NEWIRQAGR_FLAG;
-}
-
-static inline void amdm37x_irc_fiq_ack(amdm37x_irc_regs_t *regs)
-{
-	regs->control = AMDM37x_IRC_CONTROL_NEWFIQAGR_FLAG;
-}
-
-static inline void amdm37x_irc_enable(amdm37x_irc_regs_t *regs, unsigned inum)
-{
-	ASSERT(inum < AMDM37x_IRC_IRQ_COUNT);
-	const unsigned set = inum / 32;
-	const unsigned pos = inum % 32;
-	regs->interrupts[set].mir_clear = (1 << pos);
-}
-
-static inline void amdm37x_irc_disable(amdm37x_irc_regs_t *regs, unsigned inum)
-{
-	ASSERT(inum < AMDM37x_IRC_IRQ_COUNT);
-	const unsigned set = inum / 32;
-	const unsigned pos = inum % 32;
-	regs->interrupts[set].mir_set = (1 << pos);
-}
+#include <genarch/drivers/omap/irc.h>
 
 #endif
Index: kernel/genarch/include/genarch/drivers/omap/irc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/omap/irc.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
+++ kernel/genarch/include/genarch/drivers/omap/irc.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2012 Maurizio Lombardi
+ *
+ * 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 genarch
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Texas Instruments OMAP on-chip interrupt controller driver.
+ */
+
+#ifndef KERN_OMAP_IRQC_H_
+#define KERN_OMAP_IRQC_H_
+
+#include <typedefs.h>
+
+#define OMAP_IRC_IRQ_GROUPS_PAD (4 - OMAP_IRC_IRQ_GROUPS_COUNT)
+
+typedef struct {
+	const ioport32_t revision;
+#define OMAP_IRC_REV_MASK 0xFF
+
+	const uint8_t padd0[12];
+
+	/* This register controls the various parameters
+	 * of the OCP interface.
+	 */
+	ioport32_t sysconfig;
+#define OMAP_IRC_SYSCONFIG_AUTOIDLE_FLAG   (1 << 0)
+#define OMAP_IRC_SYSCONFIG_SOFTRESET_FLAG  (1 << 1)
+
+	/* This register provides status information about the module */
+	const ioport32_t sysstatus;
+#define OMAP_IRC_SYSSTATUS_RESET_DONE_FLAG (1 << 0)
+
+	const uint8_t padd1[40];
+
+	/* This register supplies the currently active IRQ interrupt number */
+	ioport32_t sir_irq;
+#define OMAP_IRC_SIR_IRQ_ACTIVEIRQ_MASK       0x7F
+#define OMAP_IRC_SIR_IRQ_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
+
+	/* This register supplies the currently active FIQ interrupt number */
+	const ioport32_t sir_fiq;
+#define OMAP_IRC_FIQ_IRQ_ACTIVEFIQ_MASK       0x7F
+#define OMAP_IRC_FIQ_IRQ_SPURIOUSFIQFLAG_MASK 0xFFFFFFF8
+
+	/* This register contains the new interrupt agreement bits */
+	ioport32_t control;
+#define OMAP_IRC_CONTROL_NEWIRQAGR_FLAG       (1 << 0)
+#define OMAP_IRC_CONTROL_NEWFIQAGR_FLAG       (1 << 1)
+
+	/* This register controls protection of the other registers.
+	 * This register can only be accessed in priviledged mode, regardless
+	 * of the current value of the protection bit.
+	 */
+	ioport32_t protection;
+#define OMAP_IRC_PROTECTION_FLAG              (1 << 0)
+
+	/* This register controls the clock auto-idle for the functional
+	 * clock and the input synchronizers.
+	 */
+	ioport32_t idle;
+#define OMAP_IRC_IDLE_FUNCIDLE_FLAG           (1 << 0)
+#define OMAP_IRC_IDLE_TURBO_FLAG              (1 << 1)
+
+	const uint8_t padd2[12];
+
+	/* This register supplies the currently active IRQ priority level */
+	const ioport32_t irq_priority;
+#define OMAP_IRC_IRQ_PRIORITY_IRQPRIORITY_MASK     0x7F
+#define OMAP_IRC_IRQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
+
+	/* This register supplies the currently active FIQ priority level */
+	const ioport32_t fiq_priority;
+#define OMAP_IRC_FIQ_PRIORITY_FIQPRIORITY_MASK     0x7F
+#define OMAP_IRC_FIQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
+
+	/* This register sets the priority threshold */
+	ioport32_t threshold;
+#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_MASK     0xFF
+#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_ENABLED  0x00
+#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_DISABLED 0xFF
+
+	const uint8_t padd3[20];
+
+	struct {
+		/* Raw interrupt input status before masking */
+		const ioport32_t itr;
+
+		/* Interrupt mask */
+		ioport32_t mir;
+
+		/* This register is used to clear the interrupt mask bits,
+		 * Write 1 clears the mask bit to 0.
+		 */
+		ioport32_t mir_clear;
+
+		/* This register is used to set the interrupt mask bits,
+		 * Write 1 sets the mask bit to 1.
+		 */
+		ioport32_t mir_set;
+
+		/* This register is used to set the software interrupt bits,
+		 * it is also used to read the current active software
+		 * interrupts.
+		 * Write 1 sets the software interrups bits to 1.
+		 */
+		ioport32_t isr_set;
+
+		/* This register is used to clear the software interrups bits.
+		 * Write 1 clears the software interrupt bits to 0.
+		 */
+		ioport32_t isr_clear;
+
+		/* This register contains the IRQ status after masking. */
+		const ioport32_t pending_irq;
+
+		/* This register contains the FIQ status after masking. */
+		const ioport32_t pending_fiq;
+	} interrupts[OMAP_IRC_IRQ_GROUPS_COUNT];
+
+	const uint32_t padd4[8 * OMAP_IRC_IRQ_GROUPS_PAD];
+
+	/* These registers contain the priority for the interrups and
+	 * the FIQ/IRQ steering.
+	 */
+	ioport32_t ilr[OMAP_IRC_IRQ_COUNT];
+/* 0 = Interrupt routed to IRQ, 1 = interrupt routed to FIQ */
+#define OMAP_IRC_ILR_FIQNIRQ_FLAG    (1 << 0)
+#define OMAP_IRC_ILR_PRIORITY_MASK   0x3F
+#define OMAP_IRC_ILR_PRIORITY_SHIFT  2
+
+} omap_irc_regs_t;
+
+static inline void omap_irc_init(omap_irc_regs_t *regs)
+{
+	int i;
+
+	/* Initialization sequence */
+
+	/* 1 - Program the SYSCONFIG register: if necessary, enable the
+	 *     autogating by setting the AUTOIDLE bit.
+	 */
+	regs->sysconfig &= ~OMAP_IRC_SYSCONFIG_AUTOIDLE_FLAG;
+
+	/* 2 - Program the IDLE register: if necessary, disable functional
+	 *     clock autogating or enable synchronizer autogating by setting
+	 *     the FUNCIDLE bit or the TURBO bit accordingly.
+	 */
+	regs->idle &= ~OMAP_IRC_IDLE_FUNCIDLE_FLAG;
+	regs->idle &= ~OMAP_IRC_IDLE_TURBO_FLAG;
+
+	/* 3 - Program ILRm register for each interrupt line: Assign a
+	 *     priority level and set the FIQNIRQ bit for an FIQ interrupt
+	 *     (by default, interrupts are mapped to IRQ and
+	 *     priority is 0 (highest).
+	 */
+
+	for (i = 0; i < OMAP_IRC_IRQ_COUNT; ++i)
+		regs->ilr[i] = 0;
+
+	/* 4 - Program the MIRn register: Enable interrupts (by default,
+	 *     all interrupt lines are masked).
+	 */
+	for (i = 0; i < OMAP_IRC_IRQ_GROUPS_COUNT; ++i)
+		regs->interrupts[i].mir_set = 0xFFFFFFFF;
+}
+
+/** Get the currently active IRQ interrupt number
+ *
+ * @param regs     Pointer to the irc memory mapped registers
+ *
+ * @return         The active IRQ interrupt number
+ */
+static inline unsigned omap_irc_inum_get(omap_irc_regs_t *regs)
+{
+	return regs->sir_irq & OMAP_IRC_SIR_IRQ_ACTIVEIRQ_MASK;
+}
+
+/** Reset IRQ output and enable new IRQ generation
+ *
+ * @param regs    Pointer to the irc memory mapped registers
+ */
+static inline void omap_irc_irq_ack(omap_irc_regs_t *regs)
+{
+	regs->control = OMAP_IRC_CONTROL_NEWIRQAGR_FLAG;
+}
+
+/** Reset FIQ output and enable new FIQ generation
+ *
+ * @param regs    Pointer to the irc memory mapped registers
+ */
+static inline void omap_irc_fiq_ack(omap_irc_regs_t *regs)
+{
+	regs->control = OMAP_IRC_CONTROL_NEWFIQAGR_FLAG;
+}
+
+/** Clear an interrupt mask bit
+ *
+ * @param regs    Pointer to the irc memory mapped registers
+ * @param inum    The interrupt to be enabled
+ */
+static inline void omap_irc_enable(omap_irc_regs_t *regs, unsigned inum)
+{
+	ASSERT(inum < OMAP_IRC_IRQ_COUNT);
+	const unsigned set = inum / 32;
+	const unsigned pos = inum % 32;
+	regs->interrupts[set].mir_clear = (1 << pos);
+}
+
+/** Set an interrupt mask bit
+ *
+ * @param regs    Pointer to the irc memory mapped registers
+ * @param inum    The interrupt to be disabled
+ */
+static inline void omap_irc_disable(omap_irc_regs_t *regs, unsigned inum)
+{
+	ASSERT(inum < OMAP_IRC_IRQ_COUNT);
+	const unsigned set = inum / 32;
+	const unsigned pos = inum % 32;
+	regs->interrupts[set].mir_set = (1 << pos);
+}
+
+static inline void omap_irc_dump(omap_irc_regs_t *regs)
+{
+#define DUMP_REG(name) \
+	printf("%s %p(%x).\n", #name, &regs->name, regs->name);
+
+	DUMP_REG(revision);
+	DUMP_REG(sysconfig);
+	DUMP_REG(sysstatus);
+	DUMP_REG(sir_irq);
+	DUMP_REG(sir_fiq);
+	DUMP_REG(control);
+	DUMP_REG(protection);
+	DUMP_REG(idle);
+	DUMP_REG(irq_priority);
+	DUMP_REG(fiq_priority);
+	DUMP_REG(threshold);
+
+	for (int i = 0; i < OMAP_IRC_IRQ_GROUPS_COUNT; ++i) {
+		DUMP_REG(interrupts[i].itr);
+		DUMP_REG(interrupts[i].mir);
+		DUMP_REG(interrupts[i].isr_set);
+		DUMP_REG(interrupts[i].pending_irq);
+		DUMP_REG(interrupts[i].pending_fiq);
+	}
+	for (int i = 0; i < OMAP_IRC_IRQ_COUNT; ++i) {
+		DUMP_REG(ilr[i]);
+	}
+
+#undef DUMP_REG
+}
+
+#endif
+
+/**
+ * @}
+ */
Index: kernel/genarch/include/genarch/mm/page_pt.h
===================================================================
--- kernel/genarch/include/genarch/mm/page_pt.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/genarch/include/genarch/mm/page_pt.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -58,9 +58,9 @@
 #define PTL3_ENTRIES  PTL3_ENTRIES_ARCH
 
-/* Table sizes in each level */
-#define PTL0_SIZE  PTL0_SIZE_ARCH
-#define PTL1_SIZE  PTL1_SIZE_ARCH
-#define PTL2_SIZE  PTL2_SIZE_ARCH
-#define PTL3_SIZE  PTL3_SIZE_ARCH
+/* Table sizes in each level (in frames) */
+#define PTL0_FRAMES  PTL0_FRAMES_ARCH
+#define PTL1_FRAMES  PTL1_FRAMES_ARCH
+#define PTL2_FRAMES  PTL2_FRAMES_ARCH
+#define PTL3_FRAMES  PTL3_FRAMES_ARCH
 
 /*
Index: kernel/genarch/src/mm/as_pt.c
===================================================================
--- kernel/genarch/src/mm/as_pt.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/genarch/src/mm/as_pt.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -73,7 +73,7 @@
 pte_t *ptl0_create(unsigned int flags)
 {
-	pte_t *dst_ptl0 = (pte_t *) PA2KA(frame_alloc(PTL0_SIZE,
-	    FRAME_LOWMEM, 0));
-	size_t table_size = FRAME_SIZE << PTL0_SIZE;
+	pte_t *dst_ptl0 = (pte_t *)
+	    PA2KA(frame_alloc(PTL0_FRAMES, FRAME_LOWMEM, 0));
+	size_t table_size = FRAMES2SIZE(PTL0_FRAMES);
 	
 	if (flags & FLAG_AS_KERNEL)
Index: kernel/genarch/src/mm/page_pt.c
===================================================================
--- kernel/genarch/src/mm/page_pt.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/genarch/src/mm/page_pt.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -82,7 +82,7 @@
 	
 	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
-		pte_t *newpt = (pte_t *) PA2KA(frame_alloc(PTL1_SIZE,
-		    FRAME_LOWMEM, 0));
-		memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0);
+		pte_t *newpt = (pte_t *)
+		    PA2KA(frame_alloc(PTL1_FRAMES, FRAME_LOWMEM, 0));
+		memsetb(newpt, FRAMES2SIZE(PTL1_FRAMES), 0);
 		SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
 		SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page),
@@ -101,7 +101,7 @@
 	
 	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
-		pte_t *newpt = (pte_t *) PA2KA(frame_alloc(PTL2_SIZE,
-		    FRAME_LOWMEM, 0));
-		memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0);
+		pte_t *newpt = (pte_t *)
+		    PA2KA(frame_alloc(PTL2_FRAMES, FRAME_LOWMEM, 0));
+		memsetb(newpt, FRAMES2SIZE(PTL2_FRAMES), 0);
 		SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
 		SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page),
@@ -118,7 +118,7 @@
 	
 	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
-		pte_t *newpt = (pte_t *) PA2KA(frame_alloc(PTL3_SIZE,
-		    FRAME_LOWMEM, 0));
-		memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0);
+		pte_t *newpt = (pte_t *)
+		    PA2KA(frame_alloc(PTL3_FRAMES, FRAME_LOWMEM, 0));
+		memsetb(newpt, FRAMES2SIZE(PTL3_FRAMES), 0);
 		SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
 		SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page),
@@ -371,12 +371,12 @@
 	uintptr_t ptl0 = PA2KA((uintptr_t) AS_KERNEL->genarch.page_table);
 	uintptr_t ptl0_step = ptl0_step_get();
-	size_t order;
+	size_t frames;
 	
 #if (PTL1_ENTRIES != 0)
-	order = PTL1_SIZE;
+	frames = PTL1_FRAMES;
 #elif (PTL2_ENTRIES != 0)
-	order = PTL2_SIZE;
+	frames = PTL2_FRAMES;
 #else
-	order = PTL3_SIZE;
+	frames = PTL3_FRAMES;
 #endif
 	
@@ -384,6 +384,6 @@
 	    addr - 1 < base + size - 1;
 	    addr += ptl0_step) {
-		uintptr_t l1 = PA2KA(frame_alloc(order, FRAME_LOWMEM, 0));
-		memsetb((void *) l1, FRAME_SIZE << order, 0);
+		uintptr_t l1 = PA2KA(frame_alloc(frames, FRAME_LOWMEM, 0));
+		memsetb((void *) l1, FRAMES2SIZE(frames), 0);
 		SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr), KA2PA(l1));
 		SET_PTL1_FLAGS(ptl0, PTL0_INDEX(addr),
Index: kernel/generic/include/adt/bitmap.h
===================================================================
--- kernel/generic/include/adt/bitmap.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/include/adt/bitmap.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -90,5 +90,4 @@
 extern void bitmap_clear_range(bitmap_t *, size_t, size_t);
 
-extern int bitmap_find_range(bitmap_t *, size_t, size_t, size_t);
 extern int bitmap_allocate_range(bitmap_t *, size_t, size_t, size_t, size_t *);
 extern void bitmap_free_range(bitmap_t *, size_t, size_t);
Index: kernel/generic/include/adt/list.h
===================================================================
--- kernel/generic/include/adt/list.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/include/adt/list.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -67,7 +67,9 @@
 	((type *) (((void *)(link)) - list_link_to_void(&(((type *) NULL)->member))))
 
-#define list_foreach(list, iterator) \
-	for (link_t *iterator = (list).head.next; \
-	    iterator != &(list).head; iterator = iterator->next)
+#define list_foreach(list, member, itype, iterator) \
+	for (itype *iterator = NULL; iterator == NULL; iterator = (itype *) 1) \
+	    for (link_t *_link = (list).head.next; \
+	    iterator = list_get_instance(_link, itype, member), \
+	    _link != &(list).head; _link = _link->next)
 
 #define assert_link_not_used(link) \
@@ -204,4 +206,28 @@
 }
 
+/** Get next item in list.
+ *
+ * @param link Current item link
+ * @param list List containing @a link
+ *
+ * @return Next item or NULL if @a link is the last item.
+ */
+static inline link_t *list_next(link_t *link, const list_t *list)
+{
+	return (link->next == &list->head) ? NULL : link->next;
+}
+
+/** Get previous item in list.
+ *
+ * @param link Current item link
+ * @param list List containing @a link
+ *
+ * @return Previous item or NULL if @a link is the first item.
+ */
+static inline link_t *list_prev(link_t *link, const list_t *list)
+{
+	return (link->prev == &list->head) ? NULL : link->prev;
+}
+
 /** Split or concatenate headless doubly-linked circular list
  *
@@ -270,10 +296,13 @@
 {
 	unsigned int cnt = 0;
-	
-	list_foreach(*list, link) {
+	link_t *link;
+	
+	link = list_first(list);
+	while (link != NULL) {
 		if (cnt == n)
 			return link;
 		
 		cnt++;
+		link = list_next(link, list);
 	}
 	
Index: kernel/generic/include/config.h
===================================================================
--- kernel/generic/include/config.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/include/config.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -37,11 +37,8 @@
 
 #include <arch/mm/page.h>
+#include <macros.h>
 
-#define ONE_FRAME    0
-#define TWO_FRAMES   1
-#define FOUR_FRAMES  2
-
-#define STACK_FRAMES  TWO_FRAMES
-#define STACK_SIZE    ((1 << STACK_FRAMES) << PAGE_WIDTH)
+#define STACK_FRAMES  2
+#define STACK_SIZE    FRAMES2SIZE(STACK_FRAMES)
 
 #define STACK_SIZE_USER  (1 * 1024 * 1024)
@@ -97,5 +94,5 @@
 	/** Size of initial stack. */
 	size_t stack_size;
-
+	
 	bool identity_configured;
 	/** Base address of the kernel identity mapped memory. */
@@ -103,7 +100,7 @@
 	/** Size of the kernel identity mapped memory. */
 	size_t identity_size;
-
-	bool non_identity_configured;   
-
+	
+	bool non_identity_configured;
+	
 	/** End of physical memory. */
 	uint64_t physmem_end;
Index: kernel/generic/include/macros.h
===================================================================
--- kernel/generic/include/macros.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/include/macros.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -117,4 +117,11 @@
 	overlaps(KA2PA((x)), (szx), KA2PA((y)), (szy))
 
+#define PFN2ADDR(frame)  ((frame) << FRAME_WIDTH)
+#define ADDR2PFN(addr)   ((addr) >> FRAME_WIDTH)
+
+#define FRAMES2SIZE(frames)  ((frames) << FRAME_WIDTH)
+#define SIZE2FRAMES(size) \
+	(((size) == 0) ? 0 : ((((size) - 1) >> FRAME_WIDTH) + 1))
+
 #define KiB2SIZE(kb)  ((kb) << 10)
 #define MiB2SIZE(mb)  ((mb) << 20)
Index: rnel/generic/include/mm/buddy.h
===================================================================
--- kernel/generic/include/mm/buddy.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ 	(revision )
@@ -1,91 +1,0 @@
-/*
- * Copyright (c) 2005 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.
- */
-
-/** @addtogroup genericmm
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_BUDDY_H_
-#define KERN_BUDDY_H_
-
-#include <typedefs.h>
-#include <adt/list.h>
-
-#define BUDDY_SYSTEM_INNER_BLOCK	0xff
-
-struct buddy_system;
-
-/** Buddy system operations to be implemented by each implementation. */
-typedef struct {
-	/**
-	 * Return pointer to left-side or right-side buddy for block passed as
-	 * argument.
-	 */
-	link_t *(* find_buddy)(struct buddy_system *, link_t *);
-	/**
-	 * Bisect the block passed as argument and return pointer to the new
-	 * right-side buddy.
-	 */
-	link_t *(* bisect)(struct buddy_system *, link_t *);
-	/** Coalesce two buddies into a bigger block. */
-	link_t *(* coalesce)(struct buddy_system *, link_t *, link_t *);
-	/** Set order of block passed as argument. */
-	void (*set_order)(struct buddy_system *, link_t *, uint8_t);
-	/** Return order of block passed as argument. */
-	uint8_t (*get_order)(struct buddy_system *, link_t *);
-	/** Mark block as busy. */
-	void (*mark_busy)(struct buddy_system *, link_t *);
-	/** Mark block as available. */
-	void (*mark_available)(struct buddy_system *, link_t *);
-	/** Find parent of block that has given order  */
-	link_t *(* find_block)(struct buddy_system *, link_t *, uint8_t);
-} buddy_system_operations_t;
-
-typedef struct buddy_system {
-	/** Maximal order of block which can be stored by buddy system. */
-	uint8_t max_order;
-	list_t *order;
-	buddy_system_operations_t *op;
-	/** Pointer to be used by the implementation. */
-	void *data;
-} buddy_system_t;
-
-extern void buddy_system_create(buddy_system_t *, uint8_t,
-    buddy_system_operations_t *, void *);
-extern link_t *buddy_system_alloc(buddy_system_t *, uint8_t);
-extern bool buddy_system_can_alloc(buddy_system_t *, uint8_t);
-extern void buddy_system_free(buddy_system_t *, link_t *);
-extern size_t buddy_conf_size(size_t);
-extern link_t *buddy_system_alloc_block(buddy_system_t *, link_t *);
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/mm/frame.h
===================================================================
--- kernel/generic/include/mm/frame.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/include/mm/frame.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -39,6 +39,6 @@
 #include <typedefs.h>
 #include <trace.h>
+#include <adt/bitmap.h>
 #include <adt/list.h>
-#include <mm/buddy.h>
 #include <synch/spinlock.h>
 #include <arch/mm/page.h>
@@ -90,24 +90,29 @@
 
 typedef struct {
-	size_t refcount;      /**< Tracking of shared frames */
-	link_t buddy_link;    /**< Link to the next free block inside
-                                   one order */
-	void *parent;         /**< If allocated by slab, this points there */
-	uint8_t buddy_order;  /**< Buddy system block order */
+	size_t refcount;  /**< Tracking of shared frames */
+	void *parent;     /**< If allocated by slab, this points there */
 } frame_t;
 
 typedef struct {
-	pfn_t base;                    /**< Frame_no of the first frame
-                                            in the frames array */
-	size_t count;                  /**< Size of zone */
-	size_t free_count;             /**< Number of free frame_t
-                                            structures */
-	size_t busy_count;             /**< Number of busy frame_t
-                                            structures */
-	zone_flags_t flags;            /**< Type of the zone */
+	/** Frame_no of the first frame in the frames array */
+	pfn_t base;
 	
-	frame_t *frames;               /**< Array of frame_t structures
-                                            in this zone */
-	buddy_system_t *buddy_system;  /**< Buddy system for the zone */
+	/** Size of zone */
+	size_t count;
+	
+	/** Number of free frame_t structures */
+	size_t free_count;
+	
+	/** Number of busy frame_t structures */
+	size_t busy_count;
+	
+	/** Type of the zone */
+	zone_flags_t flags;
+	
+	/** Frame bitmap */
+	bitmap_t bitmap;
+	
+	/** Array of frame_t structures in this zone */
+	frame_t *frames;
 } zone_t;
 
@@ -124,43 +129,9 @@
 extern zones_t zones;
 
-NO_TRACE static inline uintptr_t PFN2ADDR(pfn_t frame)
-{
-	return (uintptr_t) (frame << FRAME_WIDTH);
-}
-
-NO_TRACE static inline pfn_t ADDR2PFN(uintptr_t addr)
-{
-	return (pfn_t) (addr >> FRAME_WIDTH);
-}
-
-NO_TRACE static inline size_t SIZE2FRAMES(size_t size)
-{
-	if (size == 0)
-		return 0;
-	
-	return (size_t) ((size - 1) >> FRAME_WIDTH) + 1;
-}
-
-NO_TRACE static inline size_t FRAMES2SIZE(size_t frames)
-{
-	return (size_t) (frames << FRAME_WIDTH);
-}
-
-#define IS_BUDDY_ORDER_OK(index, order) \
-    ((~(((sysarg_t) -1) << (order)) & (index)) == 0)
-#define IS_BUDDY_LEFT_BLOCK(zone, frame) \
-    (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
-#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \
-    (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
-#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
-    (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
-#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
-    (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
-
 extern void frame_init(void);
 extern bool frame_adjust_zone_bounds(bool, uintptr_t *, size_t *);
-extern uintptr_t frame_alloc_generic(uint8_t, frame_flags_t, uintptr_t, size_t *);
-extern uintptr_t frame_alloc(uint8_t, frame_flags_t, uintptr_t);
-extern uintptr_t frame_alloc_noreserve(uint8_t, frame_flags_t, uintptr_t);
+extern uintptr_t frame_alloc_generic(size_t, frame_flags_t, uintptr_t, size_t *);
+extern uintptr_t frame_alloc(size_t, frame_flags_t, uintptr_t);
+extern uintptr_t frame_alloc_noreserve(size_t, frame_flags_t, uintptr_t);
 extern void frame_free_generic(uintptr_t, frame_flags_t);
 extern void frame_free(uintptr_t);
Index: kernel/generic/include/mm/slab.h
===================================================================
--- kernel/generic/include/mm/slab.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/include/mm/slab.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -55,5 +55,5 @@
 /** Maximum wasted space we allow for cache */
 #define SLAB_MAX_BADNESS(cache) \
-	(((unsigned int) PAGE_SIZE << (cache)->order) >> 2)
+	(FRAMES2SIZE((cache)->frames) >> 2)
 
 /* slab_reclaim constants */
@@ -101,5 +101,5 @@
 	
 	/* Computed values */
-	uint8_t order;   /**< Order of frames to be allocated */
+	size_t frames;   /**< Number of frames to be allocated */
 	size_t objects;  /**< Number of objects that fit in */
 	
Index: kernel/generic/src/adt/bitmap.c
===================================================================
--- kernel/generic/src/adt/bitmap.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/adt/bitmap.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -280,4 +280,100 @@
 }
 
+static int constraint_satisfy(size_t index, size_t base, size_t constraint)
+{
+	return (((base + index) & constraint) == 0);
+}
+
+/** Find a continuous zero bit range
+ *
+ * Find a continuous zero bit range in the bitmap. The address
+ * computed as the sum of the index of the first zero bit and
+ * the base argument needs to be compliant with the constraint
+ * (those bits that are set in the constraint cannot be set in
+ * the address).
+ *
+ * If the index argument is non-NULL, the continuous zero range
+ * is set and the index of the first bit is stored to index.
+ * Otherwise the bitmap stays untouched.
+ *
+ * @param bitmap     Bitmap structure.
+ * @param count      Number of continuous zero bits to find.
+ * @param base       Address of the first bit in the bitmap.
+ * @param constraint Constraint for the address of the first zero bit.
+ * @param index      Place to store the index of the first zero
+ *                   bit. Can be NULL (in which case the bitmap
+ *                   is not modified).
+ *
+ * @return Non-zero if a continuous range of zero bits satisfying
+ *         the constraint has been found.
+ * @return Zero otherwise.
+ *
+ */
+int bitmap_allocate_range(bitmap_t *bitmap, size_t count, size_t base,
+    size_t constraint, size_t *index)
+{
+		if (count == 0)
+		return false;
+	
+	/*
+	 * This is a trivial implementation that should be
+	 * optimized further.
+	 */
+	
+	for (size_t i = 0; i < bitmap->elements; i++) {
+		if (!constraint_satisfy(i, base, constraint))
+			continue;
+		
+		if (!bitmap_get(bitmap, i)) {
+			bool continuous = true;
+			
+			for (size_t j = 1; j < count; j++) {
+				if ((i + j >= bitmap->elements) ||
+				    (bitmap_get(bitmap, i + j))) {
+					continuous = false;
+					break;
+				}
+			}
+			
+			if (continuous) {
+				if (index != NULL) {
+					bitmap_set_range(bitmap, i, count);
+					*index = i;
+				}
+				
+				return true;
+			}
+		}
+		
+	}
+	
+	return false;
+}
+
+/** Clear range of set bits.
+ *
+ * This is essentially bitmap_clear_range(), but it also
+ * checks whether all the cleared bits are actually set.
+ *
+ * @param bitmap Bitmap structure.
+ * @param start  Starting bit.
+ * @param count  Number of bits to clear.
+ *
+ */
+void bitmap_free_range(bitmap_t *bitmap, size_t start, size_t count)
+{
+	/*
+	 * This is a trivial implementation that should be
+	 * optimized further.
+	 */
+	
+	for (size_t i = 0; i < count; i++) {
+		if (!bitmap_get(bitmap, start + i))
+			panic("Freeing a bitmap range that is not set");
+	}
+	
+	bitmap_clear_range(bitmap, start, count);
+}
+
 /** @}
  */
Index: kernel/generic/src/adt/btree.c
===================================================================
--- kernel/generic/src/adt/btree.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/adt/btree.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -1031,9 +1031,5 @@
 	
 	printf("Printing list of leaves:\n");
-	list_foreach(t->leaf_list, cur) {
-		btree_node_t *node;
-		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
-		
+	list_foreach(t->leaf_list, leaf_link, btree_node_t, node) {
 		ASSERT(node);
 		
Index: kernel/generic/src/adt/hash_table.c
===================================================================
--- kernel/generic/src/adt/hash_table.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/adt/hash_table.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -117,5 +117,6 @@
 	ASSERT(chain < h->entries);
 	
-	list_foreach(h->entry[chain], cur) {
+	link_t *cur = list_first(&h->entry[chain]);
+	while (cur != NULL) {
 		if (h->op->compare(key, h->max_keys, cur)) {
 			/*
@@ -124,4 +125,5 @@
 			return cur;
 		}
+		cur = list_next(cur, &h->entry[chain]);
 	}
 	
Index: kernel/generic/src/adt/list.c
===================================================================
--- kernel/generic/src/adt/list.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/adt/list.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -101,6 +101,8 @@
 	unsigned int count = 0;
 	
-	list_foreach(*list, link) {
+	link_t *link = list_first(list);
+	while (link != NULL) {
 		count++;
+		link = list_next(link, list);
 	}
 	
Index: kernel/generic/src/console/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/console/cmd.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -656,8 +656,5 @@
 	
 	size_t len = 0;
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp;
-		hlp = list_get_instance(cur, cmd_info_t, link);
-		
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		spinlock_lock(&hlp->lock);
 		if (str_length(hlp->name) > len)
@@ -672,8 +669,5 @@
 	}
 	
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp;
-		hlp = list_get_instance(cur, cmd_info_t, link);
-		
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		spinlock_lock(&hlp->lock);
 		printf("%-*s %s\n", _len, hlp->name, hlp->description);
@@ -912,8 +906,5 @@
 	spinlock_lock(&cmd_lock);
 	
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp;
-		
-		hlp = list_get_instance(cur, cmd_info_t, link);
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		spinlock_lock(&hlp->lock);
 		
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/console/console.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -125,6 +125,5 @@
 static void stdout_write(outdev_t *dev, wchar_t ch)
 {
-	list_foreach(dev->list, cur) {
-		outdev_t *sink = list_get_instance(cur, outdev_t, link);
+	list_foreach(dev->list, link, outdev_t, sink) {
 		if ((sink) && (sink->op->write))
 			sink->op->write(sink, ch);
@@ -134,6 +133,5 @@
 static void stdout_redraw(outdev_t *dev)
 {
-	list_foreach(dev->list, cur) {
-		outdev_t *sink = list_get_instance(cur, outdev_t, link);
+	list_foreach(dev->list, link, outdev_t, sink) {
 		if ((sink) && (sink->op->redraw))
 			sink->op->redraw(sink);
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/console/kconsole.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -118,7 +118,5 @@
 	 * Make sure the command is not already listed.
 	 */
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
-		
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		if (hlp == cmd) {
 			/* The command is already there. */
@@ -612,6 +610,5 @@
 	cmd_info_t *cmd = NULL;
 	
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		spinlock_lock(&hlp->lock);
 		
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/cpu/cpu.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -74,5 +74,5 @@
 		for (i = 0; i < config.cpu_count; i++) {
 			cpus[i].stack = (uint8_t *) PA2KA(frame_alloc(STACK_FRAMES,
-			    FRAME_LOWMEM | FRAME_ATOMIC, 0));
+			    FRAME_LOWMEM | FRAME_ATOMIC, STACK_SIZE - 1));
 			cpus[i].id = i;
 			
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/ddi/ddi.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -322,19 +322,12 @@
 }
 
-NO_TRACE static int dmamem_map_anonymous(size_t size, unsigned int map_flags,
-    unsigned int flags, uintptr_t *phys, uintptr_t *virt, uintptr_t bound)
+NO_TRACE static int dmamem_map_anonymous(size_t size, uintptr_t constraint,
+    unsigned int map_flags, unsigned int flags, uintptr_t *phys,
+    uintptr_t *virt, uintptr_t bound)
 {
 	ASSERT(TASK);
 	
 	size_t frames = SIZE2FRAMES(size);
-	uint8_t order;
-	
-	/* We need the 2^order >= frames */
-	if (frames == 1)
-		order = 0;
-	else
-		order = fnzb(frames - 1) + 1;
-	
-	*phys = frame_alloc_noreserve(order, 0, 0);
+	*phys = frame_alloc_noreserve(frames, 0, constraint);
 	if (*phys == 0)
 		return ENOMEM;
@@ -390,7 +383,13 @@
 		 */
 		
+		uintptr_t constraint;
+		int rc = copy_from_uspace(&constraint, phys_ptr,
+		    sizeof(constraint));
+		if (rc != EOK)
+			return rc;
+		
 		uintptr_t phys;
 		uintptr_t virt = (uintptr_t) -1;
-		int rc = dmamem_map_anonymous(size, map_flags, flags,
+		rc = dmamem_map_anonymous(size, constraint, map_flags, flags,
 		    &phys, &virt, bound);
 		if (rc != EOK)
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/ipc/ipc.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -774,7 +774,5 @@
 static void ipc_print_call_list(list_t *list)
 {
-	list_foreach(*list, cur) {
-		call_t *call = list_get_instance(cur, call_t, ab_link);
-		
+	list_foreach(*list, ab_link, call_t, call) {
 #ifdef __32_BITS__
 		printf("%10p ", call);
Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -151,6 +151,5 @@
 	irq_spinlock_lock(&TASK->answerbox.lock, true);
 	
-	list_foreach(TASK->answerbox.dispatched_calls, lst) {
-		call_t *call = list_get_instance(lst, call_t, ab_link);
+	list_foreach(TASK->answerbox.dispatched_calls, ab_link, call_t, call) {
 		if ((sysarg_t) call == callid) {
 			result = call;
Index: kernel/generic/src/lib/ra.c
===================================================================
--- kernel/generic/src/lib/ra.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/lib/ra.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -391,7 +391,5 @@
 
 	irq_spinlock_lock(&arena->lock, true);
-	list_foreach(arena->spans, cur) {
-		ra_span_t *span = list_get_instance(cur, ra_span_t, span_link);
-
+	list_foreach(arena->spans, span_link, ra_span_t, span) {
 		base = ra_span_alloc(span, size, alignment);
 		if (base)
@@ -407,7 +405,5 @@
 {
 	irq_spinlock_lock(&arena->lock, true);
-	list_foreach(arena->spans, cur) {
-		ra_span_t *span = list_get_instance(cur, ra_span_t, span_link);
-
+	list_foreach(arena->spans, span_link, ra_span_t, span) {
 		if (iswithin(span->base, span->size, base, size)) {
 			ra_span_free(span, base, size);
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/mm/as.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -488,7 +488,5 @@
 	
 	/* Eventually check the addresses behind each area */
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t, node) {
 		
 		for (btree_key_t i = 0; i < node->keys; i++) {
@@ -904,7 +902,6 @@
 		 * reference from all frames found there.
 		 */
-		list_foreach(sh_info->pagemap.leaf_list, cur) {
-			btree_node_t *node
-			    = list_get_instance(cur, btree_node_t, leaf_link);
+		list_foreach(sh_info->pagemap.leaf_list, leaf_link,
+		    btree_node_t, node) {
 			btree_key_t i;
 			
@@ -956,9 +953,8 @@
 	 * Visit only the pages mapped by used_space B+tree.
 	 */
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node;
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
 		for (i = 0; i < node->keys; i++) {
 			uintptr_t ptr = node->key[i];
@@ -1238,7 +1234,6 @@
 	size_t used_pages = 0;
 	
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node
-		    = list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
@@ -1264,7 +1259,6 @@
 	size_t frame_idx = 0;
 	
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node = list_get_instance(cur, btree_node_t,
-		    leaf_link);
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
@@ -1316,7 +1310,6 @@
 	frame_idx = 0;
 	
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node
-		    = list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
@@ -2182,7 +2175,6 @@
 	size_t area_cnt = 0;
 	
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		area_cnt += node->keys;
 	}
@@ -2195,7 +2187,6 @@
 	size_t area_idx = 0;
 	
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
@@ -2231,7 +2222,6 @@
 	
 	/* Print out info about address space areas */
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node
-		    = list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/mm/backend_anon.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -118,9 +118,8 @@
 	 */
 	mutex_lock(&area->sh_info->lock);
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node;
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		unsigned int i;
 		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
 		for (i = 0; i < node->keys; i++) {
 			uintptr_t base = node->key[i];
Index: rnel/generic/src/mm/buddy.c
===================================================================
--- kernel/generic/src/mm/buddy.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ 	(revision )
@@ -1,284 +1,0 @@
-/*
- * Copyright (c) 2005 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.
- */
-
-/** @addtogroup genericmm
- * @{
- */
-
-/**
- * @file
- * @brief	Buddy allocator framework.
- *
- * This file contains buddy system allocator framework.
- * Specialized functions are needed for this abstract framework to be useful.
- */
-
-#include <mm/buddy.h>
-#include <mm/frame.h>
-#include <typedefs.h>
-#include <debug.h>
-#include <print.h>
-#include <macros.h>
-
-/** Return size needed for the buddy configuration data. */
-size_t buddy_conf_size(size_t max_order)
-{
-	return sizeof(buddy_system_t) + (max_order + 1) * sizeof(link_t);
-}
-
-
-/** Create buddy system.
- *
- * Allocate memory for and initialize new buddy system.
- *
- * @param b		Preallocated buddy system control data.
- * @param max_order	The biggest allocable size will be 2^max_order.
- * @param op		Operations for new buddy system.
- * @param data		Pointer to be used by implementation.
- *
- * @return		New buddy system.
- */
-void
-buddy_system_create(buddy_system_t *b, uint8_t max_order,
-    buddy_system_operations_t *op, void *data)
-{
-	int i;
-
-	ASSERT(max_order < BUDDY_SYSTEM_INNER_BLOCK);
-
-	ASSERT(op->find_buddy);
-	ASSERT(op->set_order);
-	ASSERT(op->get_order);
-	ASSERT(op->bisect);
-	ASSERT(op->coalesce);
-	ASSERT(op->mark_busy);
-
-	/*
-	 * Use memory after our own structure.
-	 */
-	b->order = (list_t *) (&b[1]);
-	
-	for (i = 0; i <= max_order; i++)
-		list_initialize(&b->order[i]);
-
-	b->max_order = max_order;
-	b->op = op;
-	b->data = data;
-}
-
-/** Check if buddy system can allocate block.
- *
- * @param b		Buddy system pointer.
- * @param i		Size of the block (2^i).
- *
- * @return		True if block can be allocated.
- */
-bool buddy_system_can_alloc(buddy_system_t *b, uint8_t i)
-{
-	uint8_t k;
-	
-	/*
-	 * If requested block is greater then maximal block
-	 * we know immediatly that we cannot satisfy the request.
-	 */
-	if (i > b->max_order)
-		return false;
-
-	/*
-	 * Check if any bigger or equal order has free elements
-	 */
-	for (k = i; k <= b->max_order; k++) {
-		if (!list_empty(&b->order[k])) {
-			return true;
-		}
-	}
-	
-	return false;
-}
-
-/** Allocate PARTICULAR block from buddy system.
- *
- * @return		Block of data or NULL if no such block was found.
- */
-link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block)
-{
-	link_t *left,*right, *tmp;
-	uint8_t order;
-
-	left = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK);
-	ASSERT(left);
-	list_remove(left);
-	while (1) {
-		if (!b->op->get_order(b, left)) {
-			b->op->mark_busy(b, left);
-			return left;
-		}
-		
-		order = b->op->get_order(b, left);
-
-		right = b->op->bisect(b, left);
-		b->op->set_order(b, left, order - 1);
-		b->op->set_order(b, right, order - 1);
-
-		tmp = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK);
-
-		if (tmp == right) {
-			right = left;
-			left = tmp;
-		} 
-		ASSERT(tmp == left);
-		b->op->mark_busy(b, left);
-		buddy_system_free(b, right);
-		b->op->mark_available(b, left);
-	}
-}
-
-/** Allocate block from buddy system.
- *
- * @param b		Buddy system pointer.
- * @param i		Returned block will be 2^i big.
- *
- * @return		Block of data represented by link_t.
- */
-link_t *buddy_system_alloc(buddy_system_t *b, uint8_t i)
-{
-	link_t *res, *hlp;
-
-	ASSERT(i <= b->max_order);
-
-	/*
-	 * If the list of order i is not empty,
-	 * the request can be immediatelly satisfied.
-	 */
-	res = list_first(&b->order[i]);
-	if (res != NULL) {
-		list_remove(res);
-		b->op->mark_busy(b, res);
-		return res;
-	}
-	/*
-	 * If order i is already the maximal order,
-	 * the request cannot be satisfied.
-	 */
-	if (i == b->max_order)
-		return NULL;
-
-	/*
-	 * Try to recursively satisfy the request from higher order lists.
-	 */	
-	hlp = buddy_system_alloc(b, i + 1);
-	
-	/*
-	 * The request could not be satisfied
-	 * from higher order lists.
-	 */
-	if (!hlp)
-		return NULL;
-		
-	res = hlp;
-	
-	/*
-	 * Bisect the block and set order of both of its parts to i.
-	 */
-	hlp = b->op->bisect(b, res);
-	b->op->set_order(b, res, i);
-	b->op->set_order(b, hlp, i);
-	
-	/*
-	 * Return the other half to buddy system. Mark the first part
-	 * full, so that it won't coalesce again.
-	 */
-	b->op->mark_busy(b, res);
-	buddy_system_free(b, hlp);
-	
-	return res;
-}
-
-/** Return block to buddy system.
- *
- * @param b		Buddy system pointer.
- * @param block		Block to return.
- */
-void buddy_system_free(buddy_system_t *b, link_t *block)
-{
-	link_t *buddy, *hlp;
-	uint8_t i;
-
-	/*
-	 * Determine block's order.
-	 */
-	i = b->op->get_order(b, block);
-
-	ASSERT(i <= b->max_order);
-
-	if (i != b->max_order) {
-		/*
-		 * See if there is any buddy in the list of order i.
-		 */
-		buddy = b->op->find_buddy(b, block);
-		if (buddy) {
-
-			ASSERT(b->op->get_order(b, buddy) == i);
-			/*
-			 * Remove buddy from the list of order i.
-			 */
-			list_remove(buddy);
-		
-			/*
-			 * Invalidate order of both block and buddy.
-			 */
-			b->op->set_order(b, block, BUDDY_SYSTEM_INNER_BLOCK);
-			b->op->set_order(b, buddy, BUDDY_SYSTEM_INNER_BLOCK);
-		
-			/*
-			 * Coalesce block and buddy into one block.
-			 */
-			hlp = b->op->coalesce(b, block, buddy);
-
-			/*
-			 * Set order of the coalesced block to i + 1.
-			 */
-			b->op->set_order(b, hlp, i + 1);
-
-			/*
-			 * Recursively add the coalesced block to the list of
-			 * order i + 1.
-			 */
-			buddy_system_free(b, hlp);
-			return;
-		}
-	}
-
-	/*
-	 * Insert block into the list of order i.
-	 */
-	list_append(block, &b->order[i]);
-}
-
-/** @}
- */
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/mm/frame.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -38,7 +38,6 @@
  *
  * This file contains the physical frame allocator and memory zone management.
- * The frame allocator is built on top of the buddy allocator.
- *
- * @see buddy.c
+ * The frame allocator is built on top of the two-level bitmap structure.
+ *
  */
 
@@ -62,4 +61,6 @@
 #include <str.h>
 
+#define BITMAP_BLOCK_SIZE  1024
+
 zones_t zones;
 
@@ -92,9 +93,4 @@
 }
 
-NO_TRACE static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
-{
-	return (frame - zone->frames);
-}
-
 /** Initialize frame structure.
  *
@@ -104,6 +100,6 @@
 NO_TRACE static void frame_initialize(frame_t *frame)
 {
-	frame->refcount = 1;
-	frame->buddy_order = 0;
+	frame->refcount = 0;
+	frame->parent = NULL;
 }
 
@@ -161,11 +157,6 @@
 	
 	/* Move other zones up */
-	size_t j;
-	for (j = zones.count; j > i; j--) {
+	for (size_t j = zones.count; j > i; j--)
 		zones.info[j] = zones.info[j - 1];
-		if (zones.info[j].buddy_system != NULL)
-			zones.info[j].buddy_system->data =
-			    (void *) &zones.info[j];
-	}
 	
 	zones.count++;
@@ -237,23 +228,31 @@
 }
 
-/** @return True if zone can allocate specified order */
-NO_TRACE static bool zone_can_alloc(zone_t *zone, uint8_t order)
-{
+/** @return True if zone can allocate specified number of frames */
+NO_TRACE static bool zone_can_alloc(zone_t *zone, size_t count,
+    pfn_t constraint)
+{
+	/*
+	 * The function bitmap_allocate_range() does not modify
+	 * the bitmap if the last argument is NULL.
+	 */
 	return ((zone->flags & ZONE_AVAILABLE) &&
-	    buddy_system_can_alloc(zone->buddy_system, order));
-}
-
-/** Find a zone that can allocate order frames.
+	    bitmap_allocate_range(&zone->bitmap, count, zone->base,
+	    constraint, NULL));
+}
+
+/** Find a zone that can allocate specified number of frames
  *
  * Assume interrupts are disabled and zones lock is
  * locked.
  *
- * @param order Size (2^order) of free space we are trying to find.
- * @param flags Required flags of the target zone.
- * @param hind  Preferred zone.
- *
- */
-NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags,
-    size_t hint)
+ * @param count      Number of free frames we are trying to find.
+ * @param flags      Required flags of the target zone.
+ * @param constraint Indication of bits that cannot be set in the
+ *                   physical frame number of the first allocated frame.
+ * @param hind       Preferred zone.
+ *
+ */
+NO_TRACE static size_t find_free_zone(size_t count, zone_flags_t flags,
+    pfn_t constraint, size_t hint)
 {
 	if (hint >= zones.count)
@@ -267,7 +266,7 @@
 		if (ZONE_FLAGS_MATCH(zones.info[i].flags, flags)) {
 			/*
-			 * Check if the zone has 2^order frames area available.
+			 * Check if the zone can satisfy the allocation request.
 			 */
-			if (zone_can_alloc(&zones.info[i], order))
+			if (zone_can_alloc(&zones.info[i], count, constraint))
 				return i;
 		}
@@ -282,169 +281,16 @@
 }
 
-/**************************/
-/* Buddy system functions */
-/**************************/
-
-/** Buddy system find_block implementation.
- *
- * Find block that is parent of current list.
- * That means go to lower addresses, until such block is found
- *
- * @param order Order of parent must be different then this
- *              parameter!!
- *
- */
-NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,
-    link_t *child, uint8_t order)
-{
-	frame_t *frame = list_get_instance(child, frame_t, buddy_link);
-	zone_t *zone = (zone_t *) buddy->data;
-	
-	size_t index = frame_index(zone, frame);
-	do {
-		if (zone->frames[index].buddy_order != order)
-			return &zone->frames[index].buddy_link;
-	} while (index-- > 0);
-	
-	return NULL;
-}
-
-/** Buddy system find_buddy implementation.
- *
- * @param buddy Buddy system.
- * @param block Block for which buddy should be found.
- *
- * @return Buddy for given block if found.
- *
- */
-NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy,
-    link_t *block)
-{
-	frame_t *frame = list_get_instance(block, frame_t, buddy_link);
-	zone_t *zone = (zone_t *) buddy->data;
-	ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),
-	    frame->buddy_order));
-	
-	bool is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
-	
-	size_t index;
-	if (is_left) {
-		index = (frame_index(zone, frame)) +
-		    (1 << frame->buddy_order);
-	} else {  /* is_right */
-		index = (frame_index(zone, frame)) -
-		    (1 << frame->buddy_order);
-	}
-	
-	if (frame_index_valid(zone, index)) {
-		if ((zone->frames[index].buddy_order == frame->buddy_order) &&
-		    (zone->frames[index].refcount == 0)) {
-			return &zone->frames[index].buddy_link;
-		}
-	}
-	
-	return NULL;
-}
-
-/** Buddy system bisect implementation.
- *
- * @param buddy Buddy system.
- * @param block Block to bisect.
- *
- * @return Right block.
- *
- */
-NO_TRACE static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
-{
-	frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
-	frame_t *frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
-	
-	return &frame_r->buddy_link;
-}
-
-/** Buddy system coalesce implementation.
- *
- * @param buddy   Buddy system.
- * @param block_1 First block.
- * @param block_2 First block's buddy.
- *
- * @return Coalesced block (actually block that represents lower
- *         address).
- *
- */
-NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,
-    link_t *block_1, link_t *block_2)
-{
-	frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
-	frame_t *frame2 = list_get_instance(block_2, frame_t, buddy_link);
-	
-	return ((frame1 < frame2) ? block_1 : block_2);
-}
-
-/** Buddy system set_order implementation.
- *
- * @param buddy Buddy system.
- * @param block Buddy system block.
- * @param order Order to set.
- *
- */
-NO_TRACE static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
-    uint8_t order)
-{
-	list_get_instance(block, frame_t, buddy_link)->buddy_order = order;
-}
-
-/** Buddy system get_order implementation.
- *
- * @param buddy Buddy system.
- * @param block Buddy system block.
- *
- * @return Order of block.
- *
- */
-NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy,
-    link_t *block)
-{
-	return list_get_instance(block, frame_t, buddy_link)->buddy_order;
-}
-
-/** Buddy system mark_busy implementation.
- *
- * @param buddy Buddy system.
- * @param block Buddy system block.
- *
- */
-NO_TRACE static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t *block)
-{
-	list_get_instance(block, frame_t, buddy_link)->refcount = 1;
-}
-
-/** Buddy system mark_available implementation.
- *
- * @param buddy Buddy system.
- * @param block Buddy system block.
- *
- */
-NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy,
-    link_t *block)
-{
-	list_get_instance(block, frame_t, buddy_link)->refcount = 0;
-}
-
-static buddy_system_operations_t zone_buddy_system_operations = {
-	.find_buddy = zone_buddy_find_buddy,
-	.bisect = zone_buddy_bisect,
-	.coalesce = zone_buddy_coalesce,
-	.set_order = zone_buddy_set_order,
-	.get_order = zone_buddy_get_order,
-	.mark_busy = zone_buddy_mark_busy,
-	.mark_available = zone_buddy_mark_available,
-	.find_block = zone_buddy_find_block
-};
-
 /******************/
 /* Zone functions */
 /******************/
 
+/** Return frame from zone. */
+NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t index)
+{
+	ASSERT(index < zone->count);
+	
+	return &zone->frames[index];
+}
+
 /** Allocate frame in particular zone.
  *
@@ -452,28 +298,37 @@
  * Panics if allocation is impossible.
  *
- * @param zone  Zone to allocate from.
- * @param order Allocate exactly 2^order frames.
+ * @param zone       Zone to allocate from.
+ * @param count      Number of frames to allocate
+ * @param constraint Indication of bits that cannot be set in the
+ *                   physical frame number of the first allocated frame.
  *
  * @return Frame index in zone.
  *
  */
-NO_TRACE static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
+NO_TRACE static size_t zone_frame_alloc(zone_t *zone, size_t count,
+    pfn_t constraint)
 {
 	ASSERT(zone->flags & ZONE_AVAILABLE);
 	
-	/* Allocate frames from zone buddy system */
-	link_t *link = buddy_system_alloc(zone->buddy_system, order);
-	
-	ASSERT(link);
+	/* Allocate frames from zone */
+	size_t index;
+	int avail = bitmap_allocate_range(&zone->bitmap, count, zone->base,
+	    constraint, &index);
+	
+	ASSERT(avail);
+	
+	/* Update frame reference count */
+	for (size_t i = 0; i < count; i++) {
+		frame_t *frame = zone_get_frame(zone, index + i);
+		
+		ASSERT(frame->refcount == 0);
+		frame->refcount = 1;
+	}
 	
 	/* Update zone information. */
-	zone->free_count -= (1 << order);
-	zone->busy_count += (1 << order);
-	
-	/* Frame will be actually a first frame of the block. */
-	frame_t *frame = list_get_instance(link, frame_t, buddy_link);
-	
-	/* Get frame address */
-	return make_frame_index(zone, frame);
+	zone->free_count -= count;
+	zone->busy_count += count;
+	
+	return index;
 }
 
@@ -482,25 +337,27 @@
  * Assume zone is locked and is available for deallocation.
  *
- * @param zone      Pointer to zone from which the frame is to be freed.
- * @param frame_idx Frame index relative to zone.
- *
- * @return          Number of freed frames.
- *
- */
-NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t frame_idx)
+ * @param zone  Pointer to zone from which the frame is to be freed.
+ * @param index Frame index relative to zone.
+ *
+ * @return Number of freed frames.
+ *
+ */
+NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t index)
 {
 	ASSERT(zone->flags & ZONE_AVAILABLE);
 	
-	frame_t *frame = &zone->frames[frame_idx];
+	frame_t *frame = zone_get_frame(zone, index);
 	size_t size = 0;
 	
-	ASSERT(frame->refcount);
+	ASSERT(frame->refcount > 0);
 	
 	if (!--frame->refcount) {
-		size = 1 << frame->buddy_order;
-		buddy_system_free(zone->buddy_system, &frame->buddy_link);		
+		bitmap_free_range(&zone->bitmap, index, 1);
+		
 		/* Update zone information. */
-		zone->free_count += size;
-		zone->busy_count -= size;
+		zone->free_count++;
+		zone->busy_count--;
+		
+		size = FRAME_SIZE;
 	}
 	
@@ -508,28 +365,16 @@
 }
 
-/** Return frame from zone. */
-NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
-{
-	ASSERT(frame_idx < zone->count);
-	return &zone->frames[frame_idx];
-}
-
 /** Mark frame in zone unavailable to allocation. */
-NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
+NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t index)
 {
 	if (!(zone->flags & ZONE_AVAILABLE))
 		return;
-//	ASSERT(zone->flags & ZONE_AVAILABLE);
-	
-	frame_t *frame = zone_get_frame(zone, frame_idx);
-	if (frame->refcount)
+	
+	frame_t *frame = zone_get_frame(zone, index);
+	if (frame->refcount > 0)
 		return;
 	
-	link_t *link __attribute__ ((unused));
-	
-	link = buddy_system_alloc_block(zone->buddy_system,
-	    &frame->buddy_link);
-	
-	ASSERT(link);
+	bitmap_set_range(&zone->bitmap, index, 1);
+	
 	zone->free_count--;
 	reserve_force_alloc(1);
@@ -538,16 +383,15 @@
 /** Merge two zones.
  *
- * Expect buddy to point to space at least zone_conf_size large.
  * Assume z1 & z2 are locked and compatible and zones lock is
  * locked.
  *
- * @param z1     First zone to merge.
- * @param z2     Second zone to merge.
- * @param old_z1 Original date of the first zone.
- * @param buddy  Merged zone buddy.
+ * @param z1       First zone to merge.
+ * @param z2       Second zone to merge.
+ * @param old_z1   Original data of the first zone.
+ * @param confdata Merged zone configuration data.
  *
  */
 NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
-    buddy_system_t *buddy)
+    void *confdata)
 {
 	ASSERT(zones.info[z1].flags & ZONE_AVAILABLE);
@@ -564,69 +408,26 @@
 	zones.info[z1].free_count += zones.info[z2].free_count;
 	zones.info[z1].busy_count += zones.info[z2].busy_count;
-	zones.info[z1].buddy_system = buddy;
-	
-	uint8_t order = fnzb(zones.info[z1].count);
-	buddy_system_create(zones.info[z1].buddy_system, order,
-	    &zone_buddy_system_operations, (void *) &zones.info[z1]);
-	
-	zones.info[z1].frames =
-	    (frame_t *) ((uint8_t *) zones.info[z1].buddy_system
-	    + buddy_conf_size(order));
-	
-	/* This marks all frames busy */
-	size_t i;
-	for (i = 0; i < zones.info[z1].count; i++)
-		frame_initialize(&zones.info[z1].frames[i]);
-	
-	/* Copy frames from both zones to preserve full frame orders,
-	 * parents etc. Set all free frames with refcount = 0 to 1, because
-	 * we add all free frames to buddy allocator later again, clearing
-	 * order to 0. Don't set busy frames with refcount = 0, as they
-	 * will not be reallocated during merge and it would make later
-	 * problems with allocation/free.
+	
+	bitmap_initialize(&zones.info[z1].bitmap, zones.info[z1].count,
+	    BITMAP_BLOCK_SIZE, confdata +
+	    (sizeof(frame_t) * zones.info[z1].count));
+	
+	zones.info[z1].frames = (frame_t *) confdata;
+	
+	/*
+	 * Copy frames and bits from both zones to preserve parents, etc.
 	 */
-	for (i = 0; i < old_z1->count; i++)
+	
+	for (size_t i = 0; i < old_z1->count; i++) {
+		bitmap_set(&zones.info[z1].bitmap, i,
+		    bitmap_get(&old_z1->bitmap, i));
 		zones.info[z1].frames[i] = old_z1->frames[i];
-	
-	for (i = 0; i < zones.info[z2].count; i++)
-		zones.info[z1].frames[base_diff + i]
-		    = zones.info[z2].frames[i];
-	
-	i = 0;
-	while (i < zones.info[z1].count) {
-		if (zones.info[z1].frames[i].refcount) {
-			/* Skip busy frames */
-			i += 1 << zones.info[z1].frames[i].buddy_order;
-		} else {
-			/* Free frames, set refcount = 1
-			 * (all free frames have refcount == 0, we need not
-			 * to check the order)
-			 */
-			zones.info[z1].frames[i].refcount = 1;
-			zones.info[z1].frames[i].buddy_order = 0;
-			i++;
-		}
-	}
-	
-	/* Add free blocks from the original zone z1 */
-	while (zone_can_alloc(old_z1, 0)) {
-		/* Allocate from the original zone */
-		pfn_t frame_idx = zone_frame_alloc(old_z1, 0);
-		
-		/* Free the frame from the merged zone */
-		frame_t *frame = &zones.info[z1].frames[frame_idx];
-		frame->refcount = 0;
-		buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link);
-	}
-	
-	/* Add free blocks from the original zone z2 */
-	while (zone_can_alloc(&zones.info[z2], 0)) {
-		/* Allocate from the original zone */
-		pfn_t frame_idx = zone_frame_alloc(&zones.info[z2], 0);
-		
-		/* Free the frame from the merged zone */
-		frame_t *frame = &zones.info[z1].frames[base_diff + frame_idx];
-		frame->refcount = 0;
-		buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link);
+	}
+	
+	for (size_t i = 0; i < zones.info[z2].count; i++) {
+		bitmap_set(&zones.info[z1].bitmap, base_diff + i,
+		    bitmap_get(&zones.info[z2].bitmap, i));
+		zones.info[z1].frames[base_diff + i] =
+		    zones.info[z2].frames[i];
 	}
 }
@@ -651,55 +452,11 @@
 	size_t cframes = SIZE2FRAMES(zone_conf_size(count));
 	
-	if ((pfn < zones.info[znum].base)
-	    || (pfn >= zones.info[znum].base + zones.info[znum].count))
+	if ((pfn < zones.info[znum].base) ||
+	    (pfn >= zones.info[znum].base + zones.info[znum].count))
 		return;
 	
-	frame_t *frame __attribute__ ((unused));
-
-	frame = &zones.info[znum].frames[pfn - zones.info[znum].base];
-	ASSERT(!frame->buddy_order);
-	
-	size_t i;
-	for (i = 0; i < cframes; i++) {
-		zones.info[znum].busy_count++;
+	for (size_t i = 0; i < cframes; i++)
 		(void) zone_frame_free(&zones.info[znum],
 		    pfn - zones.info[znum].base + i);
-	}
-}
-
-/** Reduce allocated block to count of order 0 frames.
- *
- * The allocated block needs 2^order frames. Reduce all frames
- * in the block to order 0 and free the unneeded frames. This means that
- * when freeing the previously allocated block starting with frame_idx,
- * you have to free every frame.
- *
- * @param znum      Zone.
- * @param frame_idx Index the first frame of the block.
- * @param count     Allocated frames in block.
- *
- */
-NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx,
-    size_t count)
-{
-	ASSERT(zones.info[znum].flags & ZONE_AVAILABLE);
-	ASSERT(frame_idx + count < zones.info[znum].count);
-	
-	uint8_t order = zones.info[znum].frames[frame_idx].buddy_order;
-	ASSERT((size_t) (1 << order) >= count);
-	
-	/* Reduce all blocks to order 0 */
-	size_t i;
-	for (i = 0; i < (size_t) (1 << order); i++) {
-		frame_t *frame = &zones.info[znum].frames[i + frame_idx];
-		frame->buddy_order = 0;
-		if (!frame->refcount)
-			frame->refcount = 1;
-		ASSERT(frame->refcount == 1);
-	}
-	
-	/* Free unneeded frames */
-	for (i = count; i < (size_t) (1 << order); i++)
-		(void) zone_frame_free(&zones.info[znum], i + frame_idx);
 }
 
@@ -721,5 +478,6 @@
 	bool ret = true;
 	
-	/* We can join only 2 zones with none existing inbetween,
+	/*
+	 * We can join only 2 zones with none existing inbetween,
 	 * the zones have to be available and with the same
 	 * set of flags
@@ -735,16 +493,12 @@
 	    + zones.info[z2].count));
 	
-	uint8_t order;
-	if (cframes == 1)
-		order = 0;
-	else
-		order = fnzb(cframes - 1) + 1;
-	
 	/* Allocate merged zone data inside one of the zones */
 	pfn_t pfn;
-	if (zone_can_alloc(&zones.info[z1], order)) {
-		pfn = zones.info[z1].base + zone_frame_alloc(&zones.info[z1], order);
-	} else if (zone_can_alloc(&zones.info[z2], order)) {
-		pfn = zones.info[z2].base + zone_frame_alloc(&zones.info[z2], order);
+	if (zone_can_alloc(&zones.info[z1], cframes, 0)) {
+		pfn = zones.info[z1].base +
+		    zone_frame_alloc(&zones.info[z1], cframes, 0);
+	} else if (zone_can_alloc(&zones.info[z2], cframes, 0)) {
+		pfn = zones.info[z2].base +
+		    zone_frame_alloc(&zones.info[z2], cframes, 0);
 	} else {
 		ret = false;
@@ -754,12 +508,7 @@
 	/* Preserve original data from z1 */
 	zone_t old_z1 = zones.info[z1];
-	old_z1.buddy_system->data = (void *) &old_z1;
 	
 	/* Do zone merging */
-	buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(pfn));
-	zone_merge_internal(z1, z2, &old_z1, buddy);
-	
-	/* Free unneeded config frames */
-	zone_reduce_region(z1, pfn - zones.info[z1].base, cframes);
+	zone_merge_internal(z1, z2, &old_z1, (void *) PA2KA(PFN2ADDR(pfn)));
 	
 	/* Subtract zone information from busy frames */
@@ -774,11 +523,6 @@
 	
 	/* Move zones down */
-	size_t i;
-	for (i = z2 + 1; i < zones.count; i++) {
+	for (size_t i = z2 + 1; i < zones.count; i++)
 		zones.info[i - 1] = zones.info[i];
-		if (zones.info[i - 1].buddy_system != NULL)
-			zones.info[i - 1].buddy_system->data =
-			    (void *) &zones.info[i - 1];
-	}
 	
 	zones.count--;
@@ -799,7 +543,8 @@
 void zone_merge_all(void)
 {
-	size_t i = 0;
+	size_t i = 1;
+	
 	while (i < zones.count) {
-		if (!zone_merge(i, i + 1))
+		if (!zone_merge(i - 1, i))
 			i++;
 	}
@@ -808,15 +553,15 @@
 /** Create new frame zone.
  *
- * @param zone  Zone to construct.
- * @param buddy Address of buddy system configuration information.
- * @param start Physical address of the first frame within the zone.
- * @param count Count of frames in zone.
- * @param flags Zone flags.
+ * @param zone     Zone to construct.
+ * @param start    Physical address of the first frame within the zone.
+ * @param count    Count of frames in zone.
+ * @param flags    Zone flags.
+ * @param confdata Configuration data of the zone.
  *
  * @return Initialized zone.
  *
  */
-NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy,
-    pfn_t start, size_t count, zone_flags_t flags)
+NO_TRACE static void zone_construct(zone_t *zone, pfn_t start, size_t count,
+    zone_flags_t flags, void *confdata)
 {
 	zone->base = start;
@@ -825,31 +570,26 @@
 	zone->free_count = count;
 	zone->busy_count = 0;
-	zone->buddy_system = buddy;
 	
 	if (flags & ZONE_AVAILABLE) {
 		/*
-		 * Compute order for buddy system and initialize
+		 * Initialize frame bitmap (located after the array of
+		 * frame_t structures in the configuration space).
 		 */
-		uint8_t order = fnzb(count);
-		buddy_system_create(zone->buddy_system, order,
-		    &zone_buddy_system_operations, (void *) zone);
-		
-		/* Allocate frames _after_ the confframe */
-		
-		/* Check sizes */
-		zone->frames = (frame_t *) ((uint8_t *) zone->buddy_system +
-		    buddy_conf_size(order));
-		
-		size_t i;
-		for (i = 0; i < count; i++)
+		
+		bitmap_initialize(&zone->bitmap, count, BITMAP_BLOCK_SIZE,
+		    confdata + (sizeof(frame_t) * count));
+		
+		/*
+		 * Initialize the array of frame_t structures.
+		 */
+		
+		zone->frames = (frame_t *) confdata;
+		
+		for (size_t i = 0; i < count; i++)
 			frame_initialize(&zone->frames[i]);
-		
-		/* Stuffing frames */
-		for (i = 0; i < count; i++) {
-			zone->frames[i].refcount = 0;
-			buddy_system_free(zone->buddy_system, &zone->frames[i].buddy_link);
-		}
-	} else
+	} else {
+		bitmap_initialize(&zone->bitmap, 0, 0, NULL);
 		zone->frames = NULL;
+	}
 }
 
@@ -863,5 +603,6 @@
 size_t zone_conf_size(size_t count)
 {
-	return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
+	return (count * sizeof(frame_t) +
+	    bitmap_size(count, BITMAP_BLOCK_SIZE));
 }
 
@@ -869,9 +610,8 @@
 pfn_t zone_external_conf_alloc(size_t count)
 {
-	size_t size = zone_conf_size(count);
-	size_t order = ispwr2(size) ? fnzb(size) : (fnzb(size) + 1);
-
-	return ADDR2PFN((uintptr_t) frame_alloc(order - FRAME_WIDTH,
-	    FRAME_LOWMEM | FRAME_ATOMIC, 0));
+	size_t frames = SIZE2FRAMES(zone_conf_size(count));
+	
+	return ADDR2PFN((uintptr_t)
+	    frame_alloc(frames, FRAME_LOWMEM | FRAME_ATOMIC, 0));
 }
 
@@ -881,5 +621,5 @@
  * @param count     Size of zone in frames.
  * @param confframe Where configuration frames are supposed to be.
- *                  Automatically checks, that we will not disturb the
+ *                  Automatically checks that we will not disturb the
  *                  kernel and possibly init. If confframe is given
  *                  _outside_ this zone, it is expected, that the area is
@@ -898,17 +638,20 @@
 	
 	if (flags & ZONE_AVAILABLE) {  /* Create available zone */
-		/* Theoretically we could have NULL here, practically make sure
+		/*
+		 * Theoretically we could have NULL here, practically make sure
 		 * nobody tries to do that. If some platform requires, remove
 		 * the assert
 		 */
 		ASSERT(confframe != ADDR2PFN((uintptr_t ) NULL));
-
+		
 		/* Update the known end of physical memory. */
 		config.physmem_end = max(config.physmem_end, PFN2ADDR(start + count));
 		
-		/* If confframe is supposed to be inside our zone, then make sure
+		/*
+		 * If confframe is supposed to be inside our zone, then make sure
 		 * it does not span kernel & init
 		 */
 		size_t confcount = SIZE2FRAMES(zone_conf_size(count));
+		
 		if ((confframe >= start) && (confframe < start + count)) {
 			for (; confframe < start + count; confframe++) {
@@ -923,6 +666,5 @@
 				
 				bool overlap = false;
-				size_t i;
-				for (i = 0; i < init.cnt; i++)
+				for (size_t i = 0; i < init.cnt; i++) {
 					if (overlaps(addr, PFN2ADDR(confcount),
 					    init.tasks[i].paddr,
@@ -931,4 +673,6 @@
 						break;
 					}
+				}
+				
 				if (overlap)
 					continue;
@@ -937,9 +681,6 @@
 			}
 			
-			if (confframe >= start + count) {
-				flags &= ~ZONE_AVAILABLE;
-				goto nonavail;
-//				panic("Cannot find configuration data for zone.");
-			}
+			if (confframe >= start + count)
+				panic("Cannot find configuration data for zone.");
 		}
 		
@@ -950,11 +691,10 @@
 		}
 		
-		buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(confframe));
-		zone_construct(&zones.info[znum], buddy, start, count, flags);
+		void *confdata = (void *) PA2KA(PFN2ADDR(confframe));
+		zone_construct(&zones.info[znum], start, count, flags, confdata);
 		
 		/* If confdata in zone, mark as unavailable */
 		if ((confframe >= start) && (confframe < start + count)) {
-			size_t i;
-			for (i = confframe; i < confframe + confcount; i++)
+			for (size_t i = confframe; i < confframe + confcount; i++)
 				zone_mark_unavailable(&zones.info[znum],
 				    i - zones.info[znum].base);
@@ -965,6 +705,5 @@
 		return znum;
 	}
-nonavail:
-	(void)0; // label trick
+	
 	/* Non-available zone */
 	size_t znum = zones_insert_zone(start, count, flags);
@@ -973,5 +712,6 @@
 		return (size_t) -1;
 	}
-	zone_construct(&zones.info[znum], NULL, start, count, flags);
+	
+	zone_construct(&zones.info[znum], start, count, flags, NULL);
 	
 	irq_spinlock_unlock(&zones.lock, true);
@@ -1015,25 +755,29 @@
 }
 
-/** Allocate power-of-two frames of physical memory.
- *
- * @param order Allocate exactly 2^order frames.
- * @param flags Flags for host zone selection and address processing.
- * @param pzone Preferred zone.
+/** Allocate frames of physical memory.
+ *
+ * @param count      Number of continuous frames to allocate.
+ * @param flags      Flags for host zone selection and address processing.
+ * @param constraint Indication of physical address bits that cannot be
+ *                   set in the address of the first allocated frame.
+ * @param pzone      Preferred zone.
  *
  * @return Physical address of the allocated frame.
  *
  */
-uintptr_t frame_alloc_generic(uint8_t order, frame_flags_t flags,
+uintptr_t frame_alloc_generic(size_t count, frame_flags_t flags,
     uintptr_t constraint, size_t *pzone)
 {
-	size_t size = ((size_t) 1) << order;
+	ASSERT(count > 0);
+	
 	size_t hint = pzone ? (*pzone) : 0;
+	pfn_t frame_constraint = ADDR2PFN(constraint);
 	
 	/*
 	 * If not told otherwise, we must first reserve the memory.
 	 */
-	if (!(flags & FRAME_NO_RESERVE)) 
-		reserve_force_alloc(size);
-
+	if (!(flags & FRAME_NO_RESERVE))
+		reserve_force_alloc(count);
+	
 loop:
 	irq_spinlock_lock(&zones.lock, true);
@@ -1042,9 +786,11 @@
 	 * First, find suitable frame zone.
 	 */
-	size_t znum = find_free_zone(order,
-	    FRAME_TO_ZONE_FLAGS(flags), hint);
-	
-	/* If no memory, reclaim some slab memory,
-	   if it does not help, reclaim all */
+	size_t znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
+	    frame_constraint, hint);
+	
+	/*
+	 * If no memory, reclaim some slab memory,
+	 * if it does not help, reclaim all.
+	 */
 	if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
 		irq_spinlock_unlock(&zones.lock, true);
@@ -1053,6 +799,6 @@
 		
 		if (freed > 0)
-			znum = find_free_zone(order,
-			    FRAME_TO_ZONE_FLAGS(flags), hint);
+			znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
+			    frame_constraint, hint);
 		
 		if (znum == (size_t) -1) {
@@ -1062,6 +808,6 @@
 			
 			if (freed > 0)
-				znum = find_free_zone(order,
-				    FRAME_TO_ZONE_FLAGS(flags), hint);
+				znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
+				    frame_constraint, hint);
 		}
 	}
@@ -1070,6 +816,8 @@
 		if (flags & FRAME_ATOMIC) {
 			irq_spinlock_unlock(&zones.lock, true);
+			
 			if (!(flags & FRAME_NO_RESERVE))
-				reserve_free(size);
+				reserve_free(count);
+			
 			return 0;
 		}
@@ -1090,10 +838,10 @@
 #ifdef CONFIG_DEBUG
 		printf("Thread %" PRIu64 " waiting for %zu frames, "
-		    "%zu available.\n", THREAD->tid, size, avail);
+		    "%zu available.\n", THREAD->tid, count, avail);
 #endif
 		
 		/*
-		 * Since the mem_avail_mtx is an active mutex, we need to disable interrupts
-		 * to prevent deadlock with TLB shootdown.
+		 * Since the mem_avail_mtx is an active mutex, we need to
+		 * disable interrupts to prevent deadlock with TLB shootdown.
 		 */
 		ipl_t ipl = interrupts_disable();
@@ -1101,7 +849,8 @@
 		
 		if (mem_avail_req > 0)
-			mem_avail_req = min(mem_avail_req, size);
+			mem_avail_req = min(mem_avail_req, count);
 		else
-			mem_avail_req = size;
+			mem_avail_req = count;
+		
 		size_t gen = mem_avail_gen;
 		
@@ -1119,6 +868,6 @@
 	}
 	
-	pfn_t pfn = zone_frame_alloc(&zones.info[znum], order)
-	    + zones.info[znum].base;
+	pfn_t pfn = zone_frame_alloc(&zones.info[znum], count,
+	    frame_constraint) + zones.info[znum].base;
 	
 	irq_spinlock_unlock(&zones.lock, true);
@@ -1130,13 +879,13 @@
 }
 
-uintptr_t frame_alloc(uint8_t order, frame_flags_t flags, uintptr_t constraint)
-{
-	return frame_alloc_generic(order, flags, constraint, NULL);
-}
-
-uintptr_t frame_alloc_noreserve(uint8_t order, frame_flags_t flags,
+uintptr_t frame_alloc(size_t count, frame_flags_t flags, uintptr_t constraint)
+{
+	return frame_alloc_generic(count, flags, constraint, NULL);
+}
+
+uintptr_t frame_alloc_noreserve(size_t count, frame_flags_t flags,
     uintptr_t constraint)
 {
-	return frame_alloc_generic(order, flags | FRAME_NO_RESERVE, constraint,
+	return frame_alloc_generic(count, flags | FRAME_NO_RESERVE, constraint,
 	    NULL);
 }
@@ -1154,6 +903,4 @@
 void frame_free_generic(uintptr_t frame, frame_flags_t flags)
 {
-	size_t size;
-	
 	irq_spinlock_lock(&zones.lock, true);
 	
@@ -1163,8 +910,9 @@
 	pfn_t pfn = ADDR2PFN(frame);
 	size_t znum = find_zone(pfn, 1, 0);
-
+	
 	ASSERT(znum != (size_t) -1);
 	
-	size = zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
+	size_t size =
+	    zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
 	
 	irq_spinlock_unlock(&zones.lock, true);
@@ -1173,5 +921,5 @@
 	 * Signal that some memory has been freed.
 	 */
-
+	
 	
 	/*
@@ -1179,6 +927,8 @@
 	 * to prevent deadlock with TLB shootdown.
 	 */
+	
 	ipl_t ipl = interrupts_disable();
 	mutex_lock(&mem_avail_mtx);
+	
 	if (mem_avail_req > 0)
 		mem_avail_req -= min(mem_avail_req, size);
@@ -1188,4 +938,5 @@
 		condvar_broadcast(&mem_avail_cv);
 	}
+	
 	mutex_unlock(&mem_avail_mtx);
 	interrupts_restore(ipl);
@@ -1236,7 +987,7 @@
 	irq_spinlock_lock(&zones.lock, true);
 	
-	size_t i;
-	for (i = 0; i < count; i++) {
+	for (size_t i = 0; i < count; i++) {
 		size_t znum = find_zone(start + i, 1, 0);
+		
 		if (znum == (size_t) -1)  /* PFN not found */
 			continue;
@@ -1263,4 +1014,5 @@
 	/* Tell the architecture to create some memory */
 	frame_low_arch_init();
+	
 	if (config.cpu_active == 1) {
 		frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)),
@@ -1269,10 +1021,7 @@
 		    SIZE2FRAMES(config.stack_size));
 		
-		size_t i;
-		for (i = 0; i < init.cnt; i++) {
-			pfn_t pfn = ADDR2PFN(init.tasks[i].paddr);
-			frame_mark_unavailable(pfn,
+		for (size_t i = 0; i < init.cnt; i++)
+			frame_mark_unavailable(ADDR2PFN(init.tasks[i].paddr),
 			    SIZE2FRAMES(init.tasks[i].size));
-		}
 		
 		if (ballocs.size)
@@ -1280,9 +1029,11 @@
 			    SIZE2FRAMES(ballocs.size));
 		
-		/* Black list first frame, as allocating NULL would
+		/*
+		 * Blacklist first frame, as allocating NULL would
 		 * fail in some places
 		 */
 		frame_mark_unavailable(0, 1);
 	}
+	
 	frame_high_arch_init();
 }
@@ -1290,21 +1041,24 @@
 /** Adjust bounds of physical memory region according to low/high memory split.
  *
- * @param low[in]	If true, the adjustment is performed to make the region
- *			fit in the low memory. Otherwise the adjustment is
- *			performed to make the region fit in the high memory.
- * @param basep[inout]	Pointer to a variable which contains the region's base
- *			address and which may receive the adjusted base address.
- * @param sizep[inout]	Pointer to a variable which contains the region's size
- *			and which may receive the adjusted size.
- * @retun		True if the region still exists even after the
- *			adjustment, false otherwise.
+ * @param low[in]      If true, the adjustment is performed to make the region
+ *                     fit in the low memory. Otherwise the adjustment is
+ *                     performed to make the region fit in the high memory.
+ * @param basep[inout] Pointer to a variable which contains the region's base
+ *                     address and which may receive the adjusted base address.
+ * @param sizep[inout] Pointer to a variable which contains the region's size
+ *                     and which may receive the adjusted size.
+ *
+ * @return True if the region still exists even after the adjustment.
+ * @return False otherwise.
+ *
  */
 bool frame_adjust_zone_bounds(bool low, uintptr_t *basep, size_t *sizep)
 {
 	uintptr_t limit = KA2PA(config.identity_base) + config.identity_size;
-
+	
 	if (low) {
 		if (*basep > limit)
 			return false;
+		
 		if (*basep + *sizep > limit)
 			*sizep = limit - *basep;
@@ -1312,4 +1066,5 @@
 		if (*basep + *sizep <= limit)
 			return false;
+		
 		if (*basep <= limit) {
 			*sizep -= limit - *basep;
@@ -1317,4 +1072,5 @@
 		}
 	}
+	
 	return true;
 }
@@ -1328,6 +1084,6 @@
 	
 	uint64_t total = 0;
-	size_t i;
-	for (i = 0; i < zones.count; i++)
+	
+	for (size_t i = 0; i < zones.count; i++)
 		total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
 	
@@ -1352,6 +1108,5 @@
 	*free = 0;
 	
-	size_t i;
-	for (i = 0; i < zones.count; i++) {
+	for (size_t i = 0; i < zones.count; i++) {
 		*total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
 		
@@ -1390,6 +1145,5 @@
 	 */
 	
-	size_t i;
-	for (i = 0;; i++) {
+	for (size_t i = 0;; i++) {
 		irq_spinlock_lock(&zones.lock, true);
 		
@@ -1444,6 +1198,5 @@
 	size_t znum = (size_t) -1;
 	
-	size_t i;
-	for (i = 0; i < zones.count; i++) {
+	for (size_t i = 0; i < zones.count; i++) {
 		if ((i == num) || (PFN2ADDR(zones.info[i].base) == num)) {
 			znum = i;
@@ -1458,9 +1211,9 @@
 	}
 	
-	uintptr_t base = PFN2ADDR(zones.info[i].base);
-	zone_flags_t flags = zones.info[i].flags;
-	size_t count = zones.info[i].count;
-	size_t free_count = zones.info[i].free_count;
-	size_t busy_count = zones.info[i].busy_count;
+	uintptr_t base = PFN2ADDR(zones.info[znum].base);
+	zone_flags_t flags = zones.info[znum].flags;
+	size_t count = zones.info[znum].count;
+	size_t free_count = zones.info[znum].free_count;
+	size_t busy_count = zones.info[znum].busy_count;
 	
 	irq_spinlock_unlock(&zones.lock, true);
Index: kernel/generic/src/mm/km.c
===================================================================
--- kernel/generic/src/mm/km.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/mm/km.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -247,6 +247,6 @@
 	 */
 	uintptr_t page;
-	uintptr_t frame = frame_alloc(ONE_FRAME,
-	    FRAME_HIGHMEM | FRAME_ATOMIC | flags, 0); 
+	uintptr_t frame =
+	    frame_alloc(1, FRAME_HIGHMEM | FRAME_ATOMIC | flags, 0);
 	if (frame) {
 		page = km_map(frame, PAGE_SIZE,
@@ -256,5 +256,5 @@
 		ASSERT(page);
 	} else {
-		frame = frame_alloc(ONE_FRAME, FRAME_LOWMEM | flags, 0);
+		frame = frame_alloc(1, FRAME_LOWMEM | flags, 0);
 		if (!frame)
 			return (uintptr_t) NULL;
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/mm/slab.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -183,5 +183,5 @@
 	
 	void *data = (void *)
-	    PA2KA(frame_alloc_generic(cache->order, flags, 0, &zone));
+	    PA2KA(frame_alloc_generic(cache->frames, flags, 0, &zone));
 	if (!data)
 		return NULL;
@@ -197,5 +197,5 @@
 		}
 	} else {
-		fsize = (PAGE_SIZE << cache->order);
+		fsize = FRAMES2SIZE(cache->frames);
 		slab = data + fsize - sizeof(*slab);
 	}
@@ -203,5 +203,5 @@
 	/* Fill in slab structures */
 	size_t i;
-	for (i = 0; i < ((size_t) 1 << cache->order); i++)
+	for (i = 0; i < cache->frames; i++)
 		frame_set_parent(ADDR2PFN(KA2PA(data)) + i, slab, zone);
 	
@@ -231,5 +231,5 @@
 	atomic_dec(&cache->allocated_slabs);
 	
-	return (1 << cache->order);
+	return cache->frames;
 }
 
@@ -558,8 +558,8 @@
 {
 	if (cache->flags & SLAB_CACHE_SLINSIDE)
-		return ((PAGE_SIZE << cache->order)
-		    - sizeof(slab_t)) / cache->size;
+		return (FRAMES2SIZE(cache->frames) - sizeof(slab_t)) /
+		    cache->size;
 	else
-		return (PAGE_SIZE << cache->order) / cache->size;
+		return FRAMES2SIZE(cache->frames) / cache->size;
 }
 
@@ -570,5 +570,5 @@
 {
 	size_t objects = comp_objects(cache);
-	size_t ssize = PAGE_SIZE << cache->order;
+	size_t ssize = FRAMES2SIZE(cache->frames);
 	
 	if (cache->flags & SLAB_CACHE_SLINSIDE)
@@ -634,15 +634,9 @@
 		cache->flags |= SLAB_CACHE_SLINSIDE;
 	
-	/* Minimum slab order */
-	size_t pages = SIZE2FRAMES(cache->size);
-	
-	/* We need the 2^order >= pages */
-	if (pages == 1)
-		cache->order = 0;
-	else
-		cache->order = fnzb(pages - 1) + 1;
+	/* Minimum slab frames */
+	cache->frames = SIZE2FRAMES(cache->size);
 	
 	while (badness(cache) > SLAB_MAX_BADNESS(cache))
-		cache->order += 1;
+		cache->frames <<= 1;
 	
 	cache->objects = comp_objects(cache);
@@ -810,6 +804,5 @@
 	
 	size_t frames = 0;
-	list_foreach(slab_cache_list, cur) {
-		slab_cache_t *cache = list_get_instance(cur, slab_cache_t, link);
+	list_foreach(slab_cache_list, link, slab_cache_t, cache) {
 		frames += _slab_reclaim(cache, flags);
 	}
@@ -871,5 +864,5 @@
 		
 		const char *name = cache->name;
-		uint8_t order = cache->order;
+		size_t frames = cache->frames;
 		size_t size = cache->size;
 		size_t objects = cache->objects;
@@ -881,6 +874,6 @@
 		irq_spinlock_unlock(&slab_cache_lock, true);
 		
-		printf("%-18s %8zu %8u %8zu %8ld %8ld %8ld %-5s\n",
-		    name, size, (1 << order), objects, allocated_slabs,
+		printf("%-18s %8zu %8zu %8zu %8ld %8ld %8ld %-5s\n",
+		    name, size, frames, objects, allocated_slabs,
 		    cached_objs, allocated_objs,
 		    flags & SLAB_CACHE_SLINSIDE ? "in" : "out");
@@ -936,6 +929,5 @@
 	irq_spinlock_lock(&slab_cache_lock, false);
 	
-	list_foreach(slab_cache_list, cur) {
-		slab_cache_t *slab = list_get_instance(cur, slab_cache_t, link);
+	list_foreach(slab_cache_list, link, slab_cache_t, slab) {
 		if ((slab->flags & SLAB_CACHE_MAGDEFERRED) !=
 		    SLAB_CACHE_MAGDEFERRED)
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/proc/scheduler.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -739,7 +739,6 @@
 			
 			printf("\trq[%u]: ", i);
-			list_foreach(cpus[cpu].rq[i].rq, cur) {
-				thread_t *thread = list_get_instance(cur,
-				    thread_t, rq_link);
+			list_foreach(cpus[cpu].rq[i].rq, rq_link, thread_t,
+			    thread) {
 				printf("%" PRIu64 "(%s) ", thread->tid,
 				    thread_states[thread->state]);
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/proc/task.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -452,7 +452,5 @@
 	
 	/* Current values of threads */
-	list_foreach(task->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
-		
+	list_foreach(task->threads, th_link, thread_t, thread) {
 		irq_spinlock_lock(&thread->lock, false);
 		
@@ -484,6 +482,5 @@
 	 */
 	
-	list_foreach(task->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
+	list_foreach(task->threads, th_link, thread_t, thread) {
 		bool sleeping = false;
 		
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/proc/thread.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -193,5 +193,5 @@
 	
 	thread->kstack = (uint8_t *)
-	    PA2KA(frame_alloc(STACK_FRAMES, kmflags, 0));
+	    PA2KA(frame_alloc(STACK_FRAMES, kmflags, STACK_SIZE - 1));
 	if (!thread->kstack) {
 #ifdef CONFIG_FPU
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/synch/futex.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -274,9 +274,7 @@
 	mutex_lock(&TASK->futexes_lock);
 
-	list_foreach(TASK->futexes.leaf_list, cur) {
-		btree_node_t *node;
+	list_foreach(TASK->futexes.leaf_list, leaf_link, btree_node_t, node) {
 		unsigned int i;
 		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
 		for (i = 0; i < node->keys; i++) {
 			futex_t *ftx;
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/sysinfo/stats.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -175,8 +175,6 @@
 	
 	/* Walk the B+ tree and count pages */
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
-		
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		unsigned int i;
 		for (i = 0; i < node->keys; i++) {
@@ -218,8 +216,5 @@
 	
 	/* Walk the B+ tree and count pages */
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
-		
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t, node) {
 		unsigned int i;
 		for (i = 0; i < node->keys; i++) {
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/time/clock.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -81,5 +81,5 @@
 void clock_counter_init(void)
 {
-	uintptr_t faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC, 0);
+	uintptr_t faddr = frame_alloc(1, FRAME_ATOMIC, 0);
 	if (faddr == 0)
 		panic("Cannot allocate page for clock.");
Index: kernel/generic/src/udebug/udebug.c
===================================================================
--- kernel/generic/src/udebug/udebug.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/udebug/udebug.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -406,7 +406,5 @@
 	
 	/* Finish debugging of all userspace threads */
-	list_foreach(task->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
-		
+	list_foreach(task->threads, th_link, thread_t, thread) {
 		mutex_lock(&thread->udebug.lock);
 		
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -196,7 +196,5 @@
 	/* Set udebug.active on all of the task's userspace threads. */
 	
-	list_foreach(TASK->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
-		
+	list_foreach(TASK->threads, th_link, thread_t, thread) {
 		mutex_lock(&thread->udebug.lock);
 		if (thread->uspace) {
@@ -389,7 +387,5 @@
 	
 	/* FIXME: make sure the thread isn't past debug shutdown... */
-	list_foreach(TASK->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
-		
+	list_foreach(TASK->threads, th_link, thread_t, thread) {
 		irq_spinlock_lock(&thread->lock, false);
 		bool uspace = thread->uspace;
Index: kernel/test/mm/falloc1.c
===================================================================
--- kernel/test/mm/falloc1.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/test/mm/falloc1.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -37,5 +37,5 @@
 #include <align.h>
 
-#define MAX_FRAMES  1024U
+#define MAX_FRAMES  1024
 #define MAX_ORDER   8
 #define TEST_RUNS   2
@@ -51,20 +51,17 @@
 		return "Unable to allocate frames";
 	
-	unsigned int results[MAX_ORDER + 1];
+	unsigned int results[MAX_FRAMES + 1];
+	
 	for (unsigned int run = 0; run < TEST_RUNS; run++) {
-		for (unsigned int order = 0; order <= MAX_ORDER; order++) {
-			TPRINTF("Allocating %u frames blocks ... ", 1 << order);
+		for (size_t count = 1; count <= MAX_FRAMES; count++) {
+			size_t bytes = FRAMES2SIZE(count);
+			
+			TPRINTF("Allocating %zu frames blocks (%zu bytes) ... ",
+			    count, bytes);
 			
 			unsigned int allocated = 0;
-			for (unsigned int i = 0; i < (MAX_FRAMES >> order); i++) {
+			for (unsigned int i = 0; i < (MAX_FRAMES / count); i++) {
 				frames[allocated] =
-				    PA2KA(frame_alloc(order, FRAME_ATOMIC, 0));
-				
-				if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) !=
-				    frames[allocated]) {
-					TPRINTF("Block at address %p (size %u) is not aligned\n",
-					    (void *) frames[allocated], (FRAME_SIZE << order) >> 10);
-					return "Test failed";
-				}
+				    PA2KA(frame_alloc(count, FRAME_ATOMIC, 0));
 				
 				if (frames[allocated])
@@ -78,9 +75,9 @@
 			TPRINTF("%d blocks allocated.\n", allocated);
 			
-			if (run) {
-				if (results[order] != allocated)
+			if (run > 0) {
+				if (results[count] != allocated)
 					return "Possible frame leak";
 			} else
-				results[order] = allocated;
+				results[count] = allocated;
 			
 			TPRINTF("Deallocating ... ");
Index: kernel/test/mm/falloc2.c
===================================================================
--- kernel/test/mm/falloc2.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/test/mm/falloc2.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -40,6 +40,5 @@
 #include <arch.h>
 
-#define MAX_FRAMES  256U
-#define MAX_ORDER   8
+#define MAX_FRAMES  256
 
 #define THREAD_RUNS  1
@@ -66,15 +65,17 @@
 	
 	for (unsigned int run = 0; run < THREAD_RUNS; run++) {
-		for (unsigned int order = 0; order <= MAX_ORDER; order++) {
+		for (size_t count = 1; count <= MAX_FRAMES; count++) {
+			size_t bytes = FRAMES2SIZE(count);
+			
 			TPRINTF("Thread #%" PRIu64 " (cpu%u): "
-			    "Allocating %u frames blocks ... \n", THREAD->tid,
-			    CPU->id, 1 << order);
+			    "Allocating %zu frames blocks (%zu bytes) ... \n", THREAD->tid,
+			    CPU->id, count, bytes);
 			
 			unsigned int allocated = 0;
-			for (unsigned int i = 0; i < (MAX_FRAMES >> order); i++) {
+			for (unsigned int i = 0; i < (MAX_FRAMES / count); i++) {
 				frames[allocated] =
-				    PA2KA(frame_alloc(order, FRAME_ATOMIC, 0));
+				    PA2KA(frame_alloc(count, FRAME_ATOMIC, 0));
 				if (frames[allocated]) {
-					memsetb((void *) frames[allocated], FRAME_SIZE << order, val);
+					memsetb((void *) frames[allocated], bytes, val);
 					allocated++;
 				} else
@@ -89,6 +90,5 @@
 			
 			for (unsigned int i = 0; i < allocated; i++) {
-				for (size_t k = 0; k <= (((size_t) FRAME_SIZE << order) - 1);
-				    k++) {
+				for (size_t k = 0; k < bytes; k++) {
 					if (((uint8_t *) frames[i])[k] != val) {
 						TPRINTF("Thread #%" PRIu64 " (cpu%u): "
Index: kernel/test/mm/mapping1.c
===================================================================
--- kernel/test/mm/mapping1.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ kernel/test/mm/mapping1.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -41,14 +41,12 @@
 const char *test_mapping1(void)
 {
-	uintptr_t page0, page1;
-	uint32_t v;
+	uintptr_t frame = frame_alloc(1, FRAME_NONE, 0);
 	
-	uintptr_t frame = frame_alloc(ONE_FRAME, FRAME_NONE, 0);
-	
-	page0 = km_map(frame, FRAME_SIZE,
+	uintptr_t page0 = km_map(frame, FRAME_SIZE,
 	    PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
 	TPRINTF("Virtual address %p mapped to physical address %p.\n",
 	    (void *) page0, (void *) frame);
-	page1 = km_map(frame, FRAME_SIZE,
+	
+	uintptr_t page1 = km_map(frame, FRAME_SIZE,
 	    PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
 	TPRINTF("Virtual address %p mapped to physical address %p.\n",
@@ -62,5 +60,5 @@
 		TPRINTF("Reading magic using the second virtual address.\n");
 		
-		v = *((uint32_t *) page1);
+		uint32_t v = *((uint32_t *) page1);
 		
 		if (v != TEST_MAGIC) {
Index: uspace/app/bdsh/cmds/modules/mount/mount.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mount/mount.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/app/bdsh/cmds/modules/mount/mount.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -74,8 +74,5 @@
 	get_mtab_list(&mtab_list);
 
-	list_foreach(mtab_list, cur) {
-		mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t,
-		    link);
-
+	list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
 		if (old_ent)
 			free(old_ent);
Index: uspace/app/edit/sheet.c
===================================================================
--- uspace/app/edit/sheet.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/app/edit/sheet.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -105,5 +105,4 @@
 	char *ipp;
 	size_t sz;
-	tag_t *tag;
 	char *newp;
 
@@ -128,7 +127,5 @@
 	/* Adjust tags. */
 
-	list_foreach(sh->tags, link) {
-		tag = list_get_instance(link, tag_t, link);
-
+	list_foreach(sh->tags, link, tag_t, tag) {
 		if (tag->b_off > pos->b_off)
 			tag->b_off += sz;
@@ -154,5 +151,4 @@
 	char *spp;
 	size_t sz;
-	tag_t *tag;
 	char *newp;
 	size_t shrink_size;
@@ -165,7 +161,5 @@
 
 	/* Adjust tags. */
-	list_foreach(sh->tags, link) {
-		tag = list_get_instance(link, tag_t, link);
-
+	list_foreach(sh->tags, link, tag_t, tag) {
 		if (tag->b_off >= epos->b_off)
 			tag->b_off -= sz;
Index: uspace/app/tester/mm/common.c
===================================================================
--- uspace/app/tester/mm/common.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/app/tester/mm/common.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -84,8 +84,6 @@
 }
 
-static bool overlap_match(link_t *link, void *addr, size_t size)
-{
-	mem_block_t *block = list_get_instance(link, mem_block_t, link);
-	
+static bool overlap_match(mem_block_t *block, void *addr, size_t size)
+{
 	/* Entry block control structure <mbeg, mend) */
 	uint8_t *mbeg = (uint8_t *) block;
@@ -125,6 +123,6 @@
 	bool fnd = false;
 	
-	list_foreach(mem_blocks, link) {
-		if (overlap_match(link, addr, size)) {
+	list_foreach(mem_blocks, link, mem_block_t, block) {
+		if (overlap_match(block, addr, size)) {
 			fnd = true;
 			break;
Index: uspace/app/usbinfo/dump.c
===================================================================
--- uspace/app/usbinfo/dump.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/app/usbinfo/dump.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -103,7 +103,5 @@
 void dump_match_ids(match_id_list_t *matches, const char *line_prefix)
 {
-	list_foreach(matches->ids, link) {
-		match_id_t *match = list_get_instance(link, match_id_t, link);
-
+	list_foreach(matches->ids, link, match_id_t, match) {
 		printf("%s%3d %s\n", line_prefix, match->score, match->id);
 	}
Index: uspace/app/usbinfo/hid.c
===================================================================
--- uspace/app/usbinfo/hid.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/app/usbinfo/hid.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -100,13 +100,11 @@
 	printf("%sParsed HID report descriptor for interface %d\n",
 	    get_indent(0), iface_no);
-	list_foreach(report->reports, report_it) {
-		usb_hid_report_description_t *description = list_get_instance(
-		    report_it, usb_hid_report_description_t, reports_link);
+	list_foreach(report->reports, reports_link,
+	    usb_hid_report_description_t, description) {
 		printf("%sReport %d (type %d)\n", get_indent(1),
 		    (int) description->report_id,
 		    (int) description->type);
-		list_foreach(description->report_items, item_it) {
-			usb_hid_report_field_t *field = list_get_instance(
-			    item_it, usb_hid_report_field_t, ritems_link);
+		list_foreach(description->report_items, ritems_link,
+		    usb_hid_report_field_t, field) {
 			printf("%sUsage page = 0x%04x    Usage = 0x%04x\n",
 			    get_indent(2),
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -454,5 +454,8 @@
 {
 	/* Value of the BAR */
-	uint32_t val, mask;
+	uint32_t val;
+	uint32_t bar;
+	uint32_t mask;
+
 	/* IO space address */
 	bool io;
@@ -492,6 +495,14 @@
 	/* Get the address mask. */
 	pci_conf_write_32(fun, addr, 0xffffffff);
-	mask &= pci_conf_read_32(fun, addr);
-	
+	bar = pci_conf_read_32(fun, addr);
+
+	/*
+ 	 * Unimplemented BARs read back as all 0's.
+ 	 */
+	if (!bar)
+		return addr + (addrw64 ? 8 : 4);
+
+	mask &= bar;	
+
 	/* Restore the original value. */
 	pci_conf_write_32(fun, addr, val);
@@ -541,5 +552,7 @@
 {
 	uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE);
-	if (irq != 0xff)
+	uint8_t pin = pci_conf_read_8(fun, PCI_BRIDGE_INT_PIN);
+
+	if (pin != 0 && irq != 0xff)
 		pci_add_interrupt(fun, irq);
 }
Index: uspace/drv/bus/usb/usbmid/explore.c
===================================================================
--- uspace/drv/bus/usb/usbmid/explore.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/drv/bus/usb/usbmid/explore.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -56,6 +56,5 @@
 static bool interface_in_list(const list_t *list, int interface_no)
 {
-	list_foreach(*list, l) {
-		usbmid_interface_t *iface = usbmid_interface_from_link(l);
+	list_foreach(*list, link, usbmid_interface_t, iface) {
 		if (iface->interface_no == interface_no) {
 			return true;
@@ -190,7 +189,5 @@
 
 	/* Start child function for every interface. */
-	list_foreach(usb_mid->interface_list, link) {
-		usbmid_interface_t *iface = usbmid_interface_from_link(link);
-
+	list_foreach(usb_mid->interface_list, link, usbmid_interface_t, iface) {
 		usb_log_info("Creating child for interface %d (%s).\n",
 		    iface->interface_no,
Index: uspace/drv/bus/usb/usbmid/usbmid.c
===================================================================
--- uspace/drv/bus/usb/usbmid/usbmid.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/drv/bus/usb/usbmid/usbmid.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -135,6 +135,5 @@
 	}
 
-	list_foreach(match_ids.ids, link) {
-		match_id_t *match_id = list_get_instance(link, match_id_t, link);
+	list_foreach(match_ids.ids, link, match_id_t, match_id) {
 		rc = ddf_fun_add_match_id(child, match_id->id, match_id->score);
 		if (rc != EOK) {
Index: uspace/drv/bus/usb/vhc/transfer.c
===================================================================
--- uspace/drv/bus/usb/vhc/transfer.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/drv/bus/usb/vhc/transfer.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -92,6 +92,5 @@
 
 	bool target_found = false;
-	list_foreach(vhc->devices, pos) {
-		vhc_virtdev_t *dev = list_get_instance(pos, vhc_virtdev_t, link);
+	list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
 		fibril_mutex_lock(&dev->guard);
 		if (dev->address == transfer->address) {
Index: uspace/lib/block/block.c
===================================================================
--- uspace/lib/block/block.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/block/block.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -93,6 +93,5 @@
 	fibril_mutex_lock(&dcl_lock);
 	
-	list_foreach(dcl, cur) {
-		devcon_t *devcon = list_get_instance(cur, devcon_t, link);
+	list_foreach(dcl, link, devcon_t, devcon) {
 		if (devcon->service_id == service_id) {
 			fibril_mutex_unlock(&dcl_lock);
@@ -124,6 +123,5 @@
 	
 	fibril_mutex_lock(&dcl_lock);
-	list_foreach(dcl, cur) {
-		devcon_t *d = list_get_instance(cur, devcon_t, link);
+	list_foreach(dcl, link, devcon_t, d) {
 		if (d->service_id == service_id) {
 			fibril_mutex_unlock(&dcl_lock);
Index: uspace/lib/c/generic/adt/hash_table.c
===================================================================
--- uspace/lib/c/generic/adt/hash_table.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/c/generic/adt/hash_table.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -227,10 +227,9 @@
 	
 	/* Check for duplicates. */
-	list_foreach(h->bucket[idx], cur) {
+	list_foreach(h->bucket[idx], link, ht_link_t, cur_link) {
 		/* 
 		 * We could filter out items using their hashes first, but 
 		 * calling equal() might very well be just as fast.
 		 */
-		ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
 		if (h->op->equal(cur_link, item))
 			return false;
@@ -258,6 +257,5 @@
 	size_t idx = h->op->key_hash(key) % h->bucket_cnt;
 
-	list_foreach(h->bucket[idx], cur) {
-		ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
+	list_foreach(h->bucket[idx], link, ht_link_t, cur_link) {
 		/* 
 		 * Is this is the item we are looking for? We could have first 
Index: uspace/lib/c/generic/adt/list.c
===================================================================
--- uspace/lib/c/generic/adt/list.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/c/generic/adt/list.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -102,6 +102,8 @@
 	unsigned int count = 0;
 	
-	list_foreach(*list, link) {
+	link_t *link = list_first(list);
+	while (link != NULL) {
 		count++;
+		link = list_next(link, list);
 	}
 	
Index: uspace/lib/c/generic/cfg.c
===================================================================
--- uspace/lib/c/generic/cfg.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/c/generic/cfg.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -83,7 +83,5 @@
 		return true;
 	
-	list_foreach(data->sections, link) {
-		const cfg_section_t *section = cfg_section_instance(link);
-		
+	cfg_file_foreach(data, section) {
 		if (!list_empty(&section->entries))
 			return false;
@@ -413,7 +411,5 @@
 const cfg_section_t *cfg_find_section(const cfg_file_t *data, const char *title)
 {
-	list_foreach(data->sections, link) {
-		const cfg_section_t *section = cfg_section_instance(link);
-		
+	cfg_file_foreach(data, section) {
 		if (str_cmp(section->title, title) == 0)
 			return section;
@@ -434,7 +430,5 @@
 const char *cfg_find_value(const cfg_section_t *section, const char *key)
 {
-	list_foreach(section->entries, link) {
-		const cfg_entry_t *entry = cfg_entry_instance(link);
-		
+	cfg_section_foreach(section, entry) {
 		if (str_cmp(entry->key, key) == 0)
 			return entry->value;
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/c/generic/devman.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -230,9 +230,5 @@
 	}
 	
-	match_id_t *match_id = NULL;
-	
-	list_foreach(match_ids->ids, link) {
-		match_id = list_get_instance(link, match_id_t, link);
-		
+	list_foreach(match_ids->ids, link, match_id_t, match_id) {
 		ipc_call_t answer2;
 		aid_t req2 = async_send_1(exch, DEVMAN_ADD_MATCH_ID,
Index: uspace/lib/c/generic/pio_trace.c
===================================================================
--- uspace/lib/c/generic/pio_trace.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/c/generic/pio_trace.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -95,8 +95,5 @@
 	pio_regions_t *regions = get_regions();
 	fibril_rwlock_read_lock(&regions->guard);
-	list_foreach(regions->list, it) {
-		assert(it);
-		region_t *reg = region_instance(it);
-		assert(reg);
+	list_foreach(regions->list, link, region_t, reg) {
 		if ((r >= reg->base) && (r < reg->base + reg->size)) {
 			if (reg->log)
@@ -131,10 +128,8 @@
 	fibril_rwlock_write_lock(&regions->guard);
 	list_foreach_safe(regions->list, it, next) {
-		assert(it);
 		region_t *reg = region_instance(it);
-		assert(reg);
 		if (r >= reg->base && (r < reg->base + reg->size)) {
-				list_remove(&reg->link);
-				region_destroy(reg);
+			list_remove(&reg->link);
+			region_destroy(reg);
 		}
 	}
Index: uspace/lib/c/include/adt/list.h
===================================================================
--- uspace/lib/c/include/adt/list.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/c/include/adt/list.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -67,10 +67,12 @@
 	((type *) (((void *)(link)) - list_link_to_void(&(((type *) NULL)->member))))
 
-#define list_foreach(list, iterator) \
-	for (link_t *iterator = (list).head.next; \
-	    iterator != &(list).head; iterator = iterator->next)
+#define list_foreach(list, member, itype, iterator) \
+	for (itype *iterator = NULL; iterator == NULL; iterator = (itype *) 1) \
+	    for (link_t *_link = (list).head.next; \
+	    iterator = list_get_instance(_link, itype, member), \
+	    _link != &(list).head; _link = _link->next)
 
 /** Unlike list_foreach(), allows removing items while traversing a list.
- * 
+ *
  * @code
  * list_t mylist;
@@ -238,5 +240,31 @@
 static inline link_t *list_last(list_t *list)
 {
-	return ((list->head.prev == &list->head) ? NULL : list->head.prev);
+	return (list->head.prev == &list->head) ? NULL : list->head.prev;
+}
+
+/** Get next item in list.
+ *
+ * @param link Current item link
+ * @param list List containing @a link
+ *
+ * @return Next item or NULL if @a link is the last item.
+ *
+ */
+static inline link_t *list_next(link_t *link, const list_t *list)
+{
+	return (link->next == &list->head) ? NULL : link->next;
+}
+
+/** Get previous item in list.
+ *
+ * @param link Current item link
+ * @param list List containing @a link
+ *
+ * @return Previous item or NULL if @a link is the first item.
+ *
+ */
+static inline link_t *list_prev(link_t *link, const list_t *list)
+{
+	return (link->prev == &list->head) ? NULL : link->prev;
 }
 
@@ -308,9 +336,11 @@
 	unsigned int cnt = 0;
 	
-	list_foreach(*list, link) {
+	link_t *link = list_first(list);
+	while (link != NULL) {
 		if (cnt == n)
 			return link;
 		
 		cnt++;
+		link = list_next(link, list);
 	}
 	
Index: uspace/lib/c/include/cfg.h
===================================================================
--- uspace/lib/c/include/cfg.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/c/include/cfg.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -80,5 +80,5 @@
 
 #define cfg_file_foreach(file, cur) \
-	list_foreach((file)->sections, (cur))
+	list_foreach((file)->sections, link, const cfg_section_t, (cur))
 
 #define cfg_section_instance(cur) \
@@ -86,5 +86,5 @@
 
 #define cfg_section_foreach(section, cur) \
-	list_foreach((section)->entries, (cur))
+	list_foreach((section)->entries, link, const cfg_entry_t, (cur))
 
 #define cfg_entry_instance(cur) \
Index: uspace/lib/draw/drawctx.c
===================================================================
--- uspace/lib/draw/drawctx.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/draw/drawctx.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -188,6 +188,5 @@
 	 * transferred to the original surface. */
 
-	list_foreach(*((list_t *) path), link) {
-		path_step_t *step = (path_step_t *) link;
+	list_foreach(*((list_t *) path), link, path_step_t, step) {
 		switch (step->type) {
 		case PATH_STEP_MOVETO:
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/drv/generic/driver.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -98,10 +98,7 @@
 static ddf_dev_t *driver_get_device(devman_handle_t handle)
 {
-	ddf_dev_t *dev = NULL;
-	
 	assert(fibril_mutex_is_locked(&devices_mutex));
 	
-	list_foreach(devices, link) {
-		dev = list_get_instance(link, ddf_dev_t, link);
+	list_foreach(devices, link, ddf_dev_t, dev) {
 		if (dev->handle == handle)
 			return dev;
@@ -113,10 +110,7 @@
 static ddf_fun_t *driver_get_function(devman_handle_t handle)
 {
-	ddf_fun_t *fun = NULL;
-	
 	assert(fibril_mutex_is_locked(&functions_mutex));
 	
-	list_foreach(functions, link) {
-		fun = list_get_instance(link, ddf_fun_t, link);
+	list_foreach(functions, link, ddf_fun_t, fun) {
 		if (fun->handle == handle)
 			return fun;
Index: uspace/lib/drv/generic/interrupt.c
===================================================================
--- uspace/lib/drv/generic/interrupt.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/drv/generic/interrupt.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -138,10 +138,7 @@
     interrupt_context_list_t *list, int id)
 {
-	interrupt_context_t *ctx;
-	
-	fibril_mutex_lock(&list->mutex);
-	
-	list_foreach(list->contexts, link) {
-		ctx = list_get_instance(link, interrupt_context_t, link);
+	fibril_mutex_lock(&list->mutex);
+	
+	list_foreach(list->contexts, link, interrupt_context_t, ctx) {
 		if (ctx->id == id) {
 			fibril_mutex_unlock(&list->mutex);
@@ -157,10 +154,7 @@
     interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
 {
-	interrupt_context_t *ctx;
-	
-	fibril_mutex_lock(&list->mutex);
-	
-	list_foreach(list->contexts, link) {
-		ctx = list_get_instance(link, interrupt_context_t, link);
+	fibril_mutex_lock(&list->mutex);
+	
+	list_foreach(list->contexts, link, interrupt_context_t, ctx) {
 		if (ctx->irq == irq && ctx->dev == dev) {
 			fibril_mutex_unlock(&list->mutex);
Index: uspace/lib/fs/libfs.c
===================================================================
--- uspace/lib/fs/libfs.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/fs/libfs.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -882,8 +882,5 @@
 
 	fibril_mutex_lock(&instances_mutex);
-	list_foreach(instances_list, link) {
-		fs_instance_t *cur = list_get_instance(link, fs_instance_t,
-		    link);
-
+	list_foreach(instances_list, link, fs_instance_t, cur) {
 		if (cur->service_id == service_id) {
 			fibril_mutex_unlock(&instances_mutex);
@@ -908,8 +905,5 @@
 {
 	fibril_mutex_lock(&instances_mutex);
-	list_foreach(instances_list, link) {
-		fs_instance_t *inst = list_get_instance(link, fs_instance_t,
-		    link);
-
+	list_foreach(instances_list, link, fs_instance_t, inst) {
 		if (inst->service_id == service_id) {
 			*idp = inst->data;
@@ -925,8 +919,5 @@
 {
 	fibril_mutex_lock(&instances_mutex);
-	list_foreach(instances_list, link) {
-		fs_instance_t *inst = list_get_instance(link, fs_instance_t,
-		    link);
-
+	list_foreach(instances_list, link, fs_instance_t, inst) {
 		if (inst->service_id == service_id) {
 			list_remove(&inst->link);
Index: uspace/lib/graph/graph.c
===================================================================
--- uspace/lib/graph/graph.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/graph/graph.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -165,8 +165,7 @@
 
 	fibril_mutex_lock(&visualizer_list_mtx);
-	list_foreach(visualizer_list, link) {
-		visualizer_t *cur = list_get_instance(link, visualizer_t, link);
-		if (cur->reg_svc_handle == handle) {
-			vs = cur;
+	list_foreach(visualizer_list, link, visualizer_t, vcur) {
+		if (vcur->reg_svc_handle == handle) {
+			vs = vcur;
 			break;
 		}
@@ -182,8 +181,7 @@
 
 	fibril_mutex_lock(&renderer_list_mtx);
-	list_foreach(renderer_list, link) {
-		renderer_t *cur = list_get_instance(link, renderer_t, link);
-		if (cur->reg_svc_handle == handle) {
-			rnd = cur;
+	list_foreach(renderer_list, link, renderer_t, rcur) {
+		if (rcur->reg_svc_handle == handle) {
+			rnd = rcur;
 			break;
 		}
@@ -322,6 +320,5 @@
 	fibril_mutex_lock(&vs->mode_mtx);
 	vslmode_list_element_t *mode_elem = NULL;
-	list_foreach(vs->modes, link) {
-		vslmode_list_element_t *cur = list_get_instance(link, vslmode_list_element_t, link);
+	list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
 		if (cur->mode.index == vs->def_mode_idx) {
 			mode_elem = cur;
@@ -382,6 +379,5 @@
 	fibril_mutex_lock(&vs->mode_mtx);
 	vslmode_list_element_t *mode_elem = NULL;
-	list_foreach(vs->modes, link) {
-		vslmode_list_element_t *cur = list_get_instance(link, vslmode_list_element_t, link);
+	list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
 		if (cur->mode.index == mode_idx) {
 			mode_elem = cur;
@@ -425,6 +421,5 @@
 	fibril_mutex_lock(&vs->mode_mtx);
 	vslmode_list_element_t *mode_elem = NULL;
-	list_foreach(vs->modes, link) {
-		vslmode_list_element_t *cur = list_get_instance(link, vslmode_list_element_t, link);
+	list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
 		if (cur->mode.index == mode_idx) {
 			mode_elem = cur;
Index: uspace/lib/gui/connection.c
===================================================================
--- uspace/lib/gui/connection.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/gui/connection.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -65,6 +65,5 @@
 
 	signal_node_t *sig_node = NULL;
-	list_foreach(connection_list, link) {
-		signal_node_t *cur = list_get_instance(link, signal_node_t, link);
+	list_foreach(connection_list, link, signal_node_t, cur) {
 		if (cur->signal == signal) {
 			sig_node = cur;
@@ -88,6 +87,5 @@
 
 	slot_node_t *slt_node = NULL;
-	list_foreach(sig_node->slots, link) {
-		slot_node_t *cur = list_get_instance(link, slot_node_t, link);
+	list_foreach(sig_node->slots, link, slot_node_t, cur) {
 		if (cur->widget == widget && cur->slot == slot) {
 			slt_node = cur;
@@ -121,6 +119,5 @@
 
 	signal_node_t *sig_node = NULL;
-	list_foreach(connection_list, link) {
-		signal_node_t *cur = list_get_instance(link, signal_node_t, link);
+	list_foreach(connection_list, link, signal_node_t, cur) {
 		if (cur->signal == signal) {
 			sig_node = cur;
@@ -135,6 +132,5 @@
 
 	slot_node_t *slt_node = NULL;
-	list_foreach(sig_node->slots, link) {
-		slot_node_t *cur = list_get_instance(link, slot_node_t, link);
+	list_foreach(sig_node->slots, link, slot_node_t, cur) {
 		if (cur->widget == widget && cur->slot == slot) {
 			slt_node = cur;
@@ -164,6 +160,5 @@
 
 	signal_node_t *sig_node = NULL;
-	list_foreach(connection_list, link) {
-		signal_node_t *cur = list_get_instance(link, signal_node_t, link);
+	list_foreach(connection_list, link, signal_node_t, cur) {
 		if (cur->signal == signal) {
 			sig_node = cur;
@@ -177,6 +172,5 @@
 	}
 
-	list_foreach(sig_node->slots, link) {
-		slot_node_t *cur = list_get_instance(link, slot_node_t, link);
+	list_foreach(sig_node->slots, link, slot_node_t, cur) {
 		cur->slot(cur->widget, data);
 	}
@@ -190,6 +184,5 @@
 
 	signal_node_t *sig_node = NULL;
-	list_foreach(connection_list, link) {
-		signal_node_t *cur = list_get_instance(link, signal_node_t, link);
+	list_foreach(connection_list, link, signal_node_t, cur) {
 		if (cur->signal == signal) {
 			sig_node = cur;
@@ -203,7 +196,5 @@
 	}
 
-	list_foreach(sig_node->slots, link) {
-		slot_node_t *cur = list_get_instance(link, slot_node_t, link);
-
+	list_foreach(sig_node->slots, link, slot_node_t, cur) {
 		void *data_copy = NULL;
 		if (data != NULL) {
Index: uspace/lib/gui/grid.c
===================================================================
--- uspace/lib/gui/grid.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/gui/grid.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -298,6 +298,5 @@
 	paint_internal(widget);
 	
-	list_foreach(widget->children, link) {
-		widget_t *child = list_get_instance(link, widget_t, link);
+	list_foreach(widget->children, link, widget_t, child) {
 		child->repaint(child);
 	}
Index: uspace/lib/gui/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/gui/terminal.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -685,7 +685,5 @@
 	terminal_t *term = NULL;
 	
-	list_foreach(terms, link) {
-		terminal_t *cur = list_get_instance(link, terminal_t, link);
-		
+	list_foreach(terms, link, terminal_t, cur) {
 		if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
 			term = cur;
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/gui/window.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -137,6 +137,5 @@
 {
 	if (widget->window->is_decorated) {
-		list_foreach(widget->children, link) {
-			widget_t *child = list_get_instance(link, widget_t, link);
+		list_foreach(widget->children, link, widget_t, child) {
 			child->rearrange(child, 
 			    widget->hpos + border_thickness,
@@ -146,6 +145,5 @@
 		}
 	} else {
-		list_foreach(widget->children, link) {
-			widget_t *child = list_get_instance(link, widget_t, link);
+		list_foreach(widget->children, link, widget_t, child) {
 			child->rearrange(child, widget->hpos, widget->vpos,
 			    widget->width, widget->height);
@@ -160,6 +158,5 @@
 	if (widget->window->is_decorated) {
 		paint_internal(widget);
-		list_foreach(widget->children, link) {
-			widget_t *child = list_get_instance(link, widget_t, link);
+		list_foreach(widget->children, link, widget_t, child) {
 			child->rearrange(child, 
 			    hpos + border_thickness,
@@ -169,6 +166,5 @@
 		}
 	} else {
-		list_foreach(widget->children, link) {
-			widget_t *child = list_get_instance(link, widget_t, link);
+		list_foreach(widget->children, link, widget_t, child) {
 			child->rearrange(child, hpos, vpos, width, height);
 		}
@@ -181,6 +177,5 @@
 		paint_internal(widget);
 	}
-	list_foreach(widget->children, link) {
-		widget_t *child = list_get_instance(link, widget_t, link);
+	list_foreach(widget->children, link, widget_t, child) {
 		child->repaint(child);
 	}
@@ -268,12 +263,10 @@
 			win_grab(widget->window->osess, event.pos_id, flags);
 		} else {
-			list_foreach(widget->children, link) {
-				widget_t *child = list_get_instance(link, widget_t, link);
+			list_foreach(widget->children, link, widget_t, child) {
 				child->handle_position_event(child, event);
 			}
 		}
 	} else {
-		list_foreach(widget->children, link) {
-			widget_t *child = list_get_instance(link, widget_t, link);
+		list_foreach(widget->children, link, widget_t, child) {
 			child->handle_position_event(child, event);
 		}
Index: uspace/lib/usbdev/src/recognise.c
===================================================================
--- uspace/lib/usbdev/src/recognise.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/usbdev/src/recognise.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -383,6 +383,5 @@
 		goto failure;
 	
-	list_foreach(match_ids.ids, id_link) {
-		match_id_t *match_id = list_get_instance(id_link, match_id_t, link);
+	list_foreach(match_ids.ids, link, match_id_t, match_id) {
 		rc = ddf_fun_add_match_id(child, match_id->id, match_id->score);
 		if (rc != EOK) {
Index: uspace/lib/usbhid/src/hiddescriptor.c
===================================================================
--- uspace/lib/usbhid/src/hiddescriptor.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/usbhid/src/hiddescriptor.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -333,10 +333,6 @@
 	}
 
-	usb_hid_report_description_t *report_des = NULL;
-	
-	list_foreach(report->reports, report_it) {
-		report_des = list_get_instance(report_it,
-				usb_hid_report_description_t, reports_link);
-
+	list_foreach(report->reports, reports_link,
+	    usb_hid_report_description_t, report_des) {
 		// if report id not set, return the first of the type
 		if(((report_des->report_id == report_id) || (report_id == 0)) && 
@@ -902,6 +898,4 @@
 void usb_hid_descriptor_print_list(list_t *list)
 {
-	usb_hid_report_field_t *report_item;
-
 	if(list == NULL || list_empty(list)) {
 	    usb_log_debug("\tempty\n");
@@ -909,8 +903,6 @@
 	}
 
-        list_foreach(*list, item) {
-		report_item = list_get_instance(item, usb_hid_report_field_t,
-				ritems_link);
-
+        list_foreach(*list, ritems_link, usb_hid_report_field_t,
+    	    report_item) {
 		usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
 		usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
@@ -937,7 +929,5 @@
 
 		usb_log_debug("\n");
-
-	}
-
+	}
 }
 
@@ -951,13 +941,9 @@
 void usb_hid_descriptor_print(usb_hid_report_t *report)
 {
-	if(report == NULL) {
+	if (report == NULL)
 		return;
-	}
-
-	usb_hid_report_description_t *report_des;
-
-	list_foreach(report->reports, report_it) {
-		report_des = list_get_instance(report_it,
-			usb_hid_report_description_t, reports_link);
+
+	list_foreach(report->reports, reports_link,
+	    usb_hid_report_description_t, report_des) {
 		usb_log_debug("Report ID: %d\n", report_des->report_id);
 		usb_log_debug("\tType: %d\n", report_des->type);
Index: uspace/lib/usbhid/src/hidparser.c
===================================================================
--- uspace/lib/usbhid/src/hidparser.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/usbhid/src/hidparser.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -130,6 +130,4 @@
     size_t size, uint8_t *report_id)
 {
-	usb_hid_report_field_t *item;
-
 	usb_hid_report_description_t *report_des;
 	usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
@@ -153,7 +151,6 @@
 
 	/* read data */
-	list_foreach(report_des->report_items, list_item) {
-		item = list_get_instance(list_item, usb_hid_report_field_t, 
-		    ritems_link);
+	list_foreach(report_des->report_items, ritems_link,
+	    usb_hid_report_field_t, item) {
 
 		if (USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) {
@@ -163,5 +160,5 @@
 				item->value = 
 					usb_hid_translate_data(item, data);
-		
+				
 				item->usage = USB_HID_EXTENDED_USAGE(
 				    item->usages[item->value -
@@ -184,6 +181,6 @@
 				/* variable item */
 				item->value = usb_hid_translate_data(item, 
-				    data);				
-			}			
+				    data);
+			}
 		}
 	}
@@ -295,8 +292,6 @@
 	usb_hid_report_description_t *report_des = NULL;
 
-	list_foreach(report->reports, report_it) {
-		report_des = list_get_instance(report_it,
-		    usb_hid_report_description_t, reports_link);
-		
+	list_foreach(report->reports, reports_link,
+	    usb_hid_report_description_t, report_des) {
 		if ((report_des->report_id == report_id) &&
 		    (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)) {
@@ -351,5 +346,5 @@
 
 	if (report->use_report_ids != 0) {
-		buffer[0] = report_id;		
+		buffer[0] = report_id;
 	}
 
@@ -362,10 +357,6 @@
 	}
 
-	usb_hid_report_field_t *report_item;
-
-	list_foreach(report_des->report_items, item) {
-		report_item = list_get_instance(item, usb_hid_report_field_t,
-		    ritems_link);
-
+	list_foreach(report_des->report_items, ritems_link,
+	    usb_hid_report_field_t, report_item) {
 		value = usb_hid_translate_data_reverse(report_item, 
 		    report_item->value);
@@ -382,7 +373,7 @@
 			}
 			size_t shift = 8 - offset % 8 - length;
-			value = value << shift;							
+			value = value << shift;
 			value = value & (((1 << length) - 1) << shift);
-				
+			
 			uint8_t mask = 0;
 			mask = 0xff - (((1 << length) - 1) << shift);
@@ -400,5 +391,5 @@
 
 					tmp_value = tmp_value << (offset % 8);
-	
+					
 					mask = ~(((1 << (8 - (offset % 8))) - 1)
 					    << (offset % 8));
@@ -413,5 +404,5 @@
 					value = value & ((1 << (length - 
 					    ((offset + length) % 8))) - 1);
-				
+					
 					mask = (1 << (length - 
 					    ((offset + length) % 8))) - 1;
Index: uspace/lib/usbhid/src/hidpath.c
===================================================================
--- uspace/lib/usbhid/src/hidpath.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/usbhid/src/hidpath.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -176,9 +176,6 @@
 	usb_log_debug("\tLENGTH: %d\n", path->depth);
 
-	usb_hid_report_usage_path_t *path_item;
-
-	list_foreach(path->items, item) {
-		path_item = list_get_instance(item, usb_hid_report_usage_path_t,
-			rpath_items_link);
+	list_foreach(path->items, rpath_items_link,
+	    usb_hid_report_usage_path_t, path_item) {
 
 		usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page);
@@ -237,18 +234,14 @@
 			usb_hid_report_usage_path_t, rpath_items_link);
 
-		list_foreach(report_path->items, report_link) {
-			report_item = list_get_instance(report_link,
-				usb_hid_report_usage_path_t, rpath_items_link);
+		list_foreach(report_path->items, rpath_items_link,
+		    usb_hid_report_usage_path_t, report_item) {
+
+			if (USB_HID_SAME_USAGE_PAGE(report_item->usage_page,
+				path_item->usage_page)) {
 				
-			if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page,
-				path_item->usage_page)){
-					
-				if(only_page == 0){
-					if(USB_HID_SAME_USAGE(
-						report_item->usage,
-						path_item->usage)) {
-							
+				if (only_page == 0) {
+					if (USB_HID_SAME_USAGE(report_item->usage,
+					    path_item->usage))
 						return EOK;
-					}
 				}
 				else {
@@ -266,44 +259,39 @@
 			return 1;
 		}
-		
+
 	/* path is prefix of the report_path */
 	case USB_HID_PATH_COMPARE_BEGIN:
-	
+
 		report_link = report_path->items.head.next;
 		path_link = path->items.head.next;
+		
+		while ((report_link != &report_path->items.head) &&
+		    (path_link != &path->items.head)) {
 			
-		while((report_link != &report_path->items.head) && 
-		      (path_link != &path->items.head)) {
-					  
 			report_item = list_get_instance(report_link, 
-				usb_hid_report_usage_path_t, rpath_items_link);
-					  
+			    usb_hid_report_usage_path_t, rpath_items_link);
+			
 			path_item = list_get_instance(path_link,
        				usb_hid_report_usage_path_t, rpath_items_link);
 
-			if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 
-				path_item->usage_page) || ((only_page == 0) && 
+			if (!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 
+			    path_item->usage_page) || ((only_page == 0) && 
 			    !USB_HID_SAME_USAGE(report_item->usage, 
-				path_item->usage))) {
-			
+			    path_item->usage))) {
 				return 1;
-			} 
-			else {
+			} else {
 				report_link = report_link->next;
-				path_link = path_link->next;			
+				path_link = path_link->next;
 			}
-			
-		}
-
-		if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && 
-			(path_link == &path->items.head)) || 
-		   ((report_link == &report_path->items.head) && 
-			(path_link == &path->items.head))) {
-				
+		}
+
+		if ((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && 
+		    (path_link == &path->items.head)) || 
+		    ((report_link == &report_path->items.head) && 
+		    (path_link == &path->items.head))) {
 			return EOK;
-		}
-		else {
+		} else {
 			return 1;
-		}						
+		}
 		break;
 
@@ -405,5 +393,4 @@
 	usb_hid_report_path_t *usage_path)
 {
-	usb_hid_report_usage_path_t *path_item;
 	usb_hid_report_usage_path_t *new_path_item;
 	usb_hid_report_path_t *new_usage_path = usb_hid_report_path ();
@@ -419,7 +406,6 @@
 	}
 
-	list_foreach(usage_path->items, path_link) {
-		path_item = list_get_instance(path_link,
-			usb_hid_report_usage_path_t, rpath_items_link);
+	list_foreach(usage_path->items, rpath_items_link,
+	    usb_hid_report_usage_path_t, path_item) {
 
 		new_path_item = malloc(sizeof(usb_hid_report_usage_path_t));
Index: uspace/lib/usbhost/src/usb_endpoint_manager.c
===================================================================
--- uspace/lib/usbhost/src/usb_endpoint_manager.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/lib/usbhost/src/usb_endpoint_manager.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -90,6 +90,5 @@
 	if (address < 0)
 		return NULL;
-	list_foreach(*get_list(instance, address), iterator) {
-		endpoint_t *ep = endpoint_get_instance(iterator);
+	list_foreach(*get_list(instance, address), link, endpoint_t, ep) {
 		if (ep_match(ep, address, endpoint, direction))
 			return ep;
@@ -196,6 +195,6 @@
 			fibril_mutex_lock(&instance->guard);
 			/* endpoint number is < 16, thus first byte is enough */
-			list_foreach(*get_list(instance, target.address), it) {
-				endpoint_t *ep = endpoint_get_instance(it);
+			list_foreach(*get_list(instance, target.address),
+			    link, endpoint_t, ep) {
 				if ((ep->address == target.address)
 				    && (ep->endpoint = data[4])) {
@@ -216,6 +215,6 @@
 		if ((data[0] & 0xf) == 0) {
 			fibril_mutex_lock(&instance->guard);
-			list_foreach(*get_list(instance, target.address), it) {
-				endpoint_t *ep = endpoint_get_instance(it);
+			list_foreach(*get_list(instance, target.address),
+			    link, endpoint_t, ep) {
 				if (ep->address == target.address) {
 					endpoint_toggle_set(ep,0);
@@ -408,11 +407,19 @@
     usb_address_t address, void (*callback)(endpoint_t *, void *), void *arg)
 {
+	list_t *list;
+	link_t *link;
+	link_t *next;
+
 	assert(address >= 0);
 	assert(instance);
 	fibril_mutex_lock(&instance->guard);
-	list_foreach(*get_list(instance, address), iterator) {
-		endpoint_t *ep = endpoint_get_instance(iterator);
+
+	list = get_list(instance, address);
+	link = list_first(list);
+	while (link != NULL) {
+		endpoint_t *ep = list_get_instance(link, endpoint_t, link);
+		next = list_next(link, list);
+
 		if (ep->address == address) {
-			iterator = iterator->next;
 			list_remove(&ep->link);
 			if (callback)
@@ -420,4 +427,5 @@
 			endpoint_destroy(ep);
 		}
+		link = next;
 	}
 	fibril_mutex_unlock(&instance->guard);
Index: uspace/srv/audio/hound/audio_sink.c
===================================================================
--- uspace/srv/audio/hound/audio_sink.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/audio/hound/audio_sink.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -140,6 +140,5 @@
 
 	pcm_format_silence(dest, size, &sink->format);
-	list_foreach(sink->connections, it) {
-		connection_t * conn = connection_from_sink_list(it);
+	list_foreach(sink->connections, sink_link, connection_t, conn) {
 		const int ret = connection_add_source_data(
 		    conn, dest, size, sink->format);
Index: uspace/srv/audio/hound/audio_source.c
===================================================================
--- uspace/srv/audio/hound/audio_source.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/audio/hound/audio_source.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -106,6 +106,5 @@
 		return ENOMEM;
 
-	list_foreach(source->connections, it) {
-		connection_t *conn = connection_from_source_list(it);
+	list_foreach(source->connections, source_link, connection_t, conn) {
 		const int ret = connection_push_data(conn, adata);
 		if (ret != EOK) {
Index: uspace/srv/audio/hound/connection.h
===================================================================
--- uspace/srv/audio/hound/connection.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/audio/hound/connection.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -76,14 +76,4 @@
  * @return pointer to a connection structure, NULL on failure.
  */
-static inline connection_t * connection_from_sink_list(link_t *l)
-{
-	return l ? list_get_instance(l, connection_t, sink_link) : NULL;
-}
-
-/**
- * List instance helper.
- * @param l link
- * @return pointer to a connection structure, NULL on failure.
- */
 static inline connection_t * connection_from_hound_list(link_t *l)
 {
Index: uspace/srv/audio/hound/hound.c
===================================================================
--- uspace/srv/audio/hound/hound.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/audio/hound/hound.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -47,20 +47,4 @@
 #include "str_error.h"
 
-#define FIND_BY_NAME(type) \
-do { \
-	assert(list); \
-	assert(name); \
-	list_foreach(*list, it) { \
-		audio_ ## type ## _t *dev = \
-		    audio_ ## type ## _list_instance(it); \
-		if (str_cmp(name, dev->name) == 0) { \
-			log_debug("%s with name '%s' is in the list", \
-			    #type, name); \
-			return dev; \
-		} \
-	} \
-	return NULL; \
-} while (0)
-
 /**
  * Search devices by name.
@@ -68,7 +52,18 @@
  * @return Pointer to the found device, NULL on failure.
  */
-static audio_device_t * find_device_by_name(list_t *list, const char *name)
-{
-	FIND_BY_NAME(device);
+static audio_device_t *find_device_by_name(list_t *list, const char *name)
+{
+	assert(list);
+	assert(name);
+
+	list_foreach(*list, link, audio_device_t, dev) {
+		if (str_cmp(name, dev->name) == 0) {
+			log_debug("device with name '%s' is in the list",
+			    name);
+			return dev;
+		}
+	}
+
+	return NULL;
 }
 
@@ -78,7 +73,18 @@
  * @return Pointer to the found source, NULL on failure.
  */
-static audio_source_t * find_source_by_name(list_t *list, const char *name)
-{
-	FIND_BY_NAME(source);
+static audio_source_t *find_source_by_name(list_t *list, const char *name)
+{
+	assert(list);
+	assert(name);
+
+	list_foreach(*list, link, audio_source_t, dev) {
+		if (str_cmp(name, dev->name) == 0) {
+			log_debug("source with name '%s' is in the list",
+			    name);
+			return dev;
+		}
+	}
+
+	return NULL;
 }
 
@@ -88,7 +94,18 @@
  * @return Pointer to the found sink, NULL on failure.
  */
-static audio_sink_t * find_sink_by_name(list_t *list, const char *name)
-{
-	FIND_BY_NAME(sink);
+static audio_sink_t *find_sink_by_name(list_t *list, const char *name)
+{
+	assert(list);
+	assert(name);
+
+	list_foreach(*list, link, audio_sink_t, dev) {
+		if (str_cmp(name, dev->name) == 0) {
+			log_debug("sink with name '%s' is in the list",
+			    name);
+			return dev;
+		}
+	}
+
+	return NULL;
 }
 
@@ -111,6 +128,6 @@
 		log_warning("Removing sink '%s' while still connected.", sink->name);
 	while (!list_empty(&sink->connections)) {
-		connection_t *conn =
-		    connection_from_sink_list(list_first(&sink->connections));
+		connection_t *conn = list_get_instance(
+		    list_first(&sink->connections), connection_t, sink_link);
 		list_remove(&conn->hound_link);
 		connection_destroy(conn);
@@ -128,13 +145,10 @@
 static void hound_remove_source_internal(hound_t *hound, audio_source_t *source)
 {
-	assert(hound);
-	assert(source);
 	log_verbose("Removing source '%s'.", source->name);
 	if (!list_empty(&source->connections))
 		log_warning("Removing source '%s' while still connected.", source->name);
 	while (!list_empty(&source->connections)) {
-		connection_t *conn =
-		    connection_from_source_list(list_first(&source->connections));
-		assert(conn);
+		connection_t *conn = list_get_instance(
+		    list_first(&source->connections), connection_t, source_link);
 		list_remove(&conn->hound_link);
 		connection_destroy(conn);
@@ -223,6 +237,5 @@
 	fibril_mutex_lock(&hound->list_guard);
 	hound_ctx_t *res = NULL;
-	list_foreach(hound->contexts, it) {
-		hound_ctx_t *ctx = hound_ctx_from_link(it);
+	list_foreach(hound->contexts, link, hound_ctx_t, ctx) {
 		if (hound_ctx_get_id(ctx) == id) {
 			res = ctx;
@@ -251,6 +264,5 @@
 	}
 
-	list_foreach(hound->devices, it) {
-		audio_device_t *dev = audio_device_list_instance(it);
+	list_foreach(hound->devices, link, audio_device_t, dev) {
 		if (dev->id == id) {
 			log_debug("Device with id %zu is already present", id);
Index: uspace/srv/audio/hound/hound_ctx.c
===================================================================
--- uspace/srv/audio/hound/hound_ctx.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/audio/hound/hound_ctx.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -176,14 +176,4 @@
 
 /**
- * List instance helper.
- * @param l link
- * @return pointer to a hound context structure, NULL on failure.
- */
-static inline hound_ctx_stream_t *hound_ctx_stream_from_link(link_t *l)
-{
-	return l ? list_get_instance(l, hound_ctx_stream_t, link) : NULL;
-}
-
-/**
  * New stream append helper.
  * @param ctx hound context.
@@ -417,6 +407,5 @@
 	pcm_format_silence(buffer, size, &source->format);
 	fibril_mutex_lock(&ctx->guard);
-	list_foreach(ctx->streams, it) {
-		hound_ctx_stream_t *stream = hound_ctx_stream_from_link(it);
+	list_foreach(ctx->streams, link, hound_ctx_stream_t, stream) {
 		ssize_t copied = hound_ctx_stream_add_self(
 		    stream, buffer, size, &source->format);
@@ -426,6 +415,5 @@
 	log_verbose("CTX: %p. Pushing audio to %u connections", ctx,
 	    list_count(&source->connections));
-	list_foreach(source->connections, it) {
-		connection_t *conn = connection_from_source_list(it);
+	list_foreach(source->connections, source_link, connection_t, conn) {
 		connection_push_data(conn, adata);
 	}
@@ -444,6 +432,5 @@
 	/* count available data */
 	size_t available_frames = -1;  /* this is ugly.... */
-	list_foreach(sink->connections, it) {
-		connection_t *conn = connection_from_source_list(it);
+	list_foreach(sink->connections, source_link, connection_t, conn) {
 		available_frames = min(available_frames,
 		    audio_pipe_frames(&conn->fifo));
@@ -466,6 +453,5 @@
 	/* mix data */
 	pcm_format_silence(buffer, bsize, &sink->format);
-	list_foreach(sink->connections, it) {
-		connection_t *conn = connection_from_source_list(it);
+	list_foreach(sink->connections, source_link, connection_t, conn) {
 		/* This should not trigger data update on the source */
 		const size_t copied = connection_add_source_data(
@@ -476,6 +462,5 @@
 	}
 	/* push to all streams */
-	list_foreach(ctx->streams, it) {
-		hound_ctx_stream_t *stream = hound_ctx_stream_from_link(it);
+	list_foreach(ctx->streams, link, hound_ctx_stream_t, stream) {
 		const int ret = stream_push_data(stream, adata);
 		if (ret != EOK)
Index: uspace/srv/audio/hound/hound_ctx.h
===================================================================
--- uspace/srv/audio/hound/hound_ctx.h	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/audio/hound/hound_ctx.h	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -58,14 +58,4 @@
 } hound_ctx_t;
 
-/**
- * List instance helper.
- * @param l link
- * @return pointer to a hound context structure, NULL on failure.
- */
-static inline hound_ctx_t *hound_ctx_from_link(link_t *l)
-{
-	return l ? list_get_instance(l, hound_ctx_t, link) : NULL;
-}
-
 typedef struct hound_ctx_stream hound_ctx_stream_t;
 
Index: uspace/srv/devman/dev.c
===================================================================
--- uspace/srv/devman/dev.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/devman/dev.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -144,8 +144,5 @@
 
 	size_t pos = 0;
-	list_foreach(dev->functions, item) {
-		fun_node_t *fun =
-		    list_get_instance(item, fun_node_t, dev_functions);
-
+	list_foreach(dev->functions, dev_functions, fun_node_t, fun) {
 		if (pos < buf_cnt) {
 			hdl_buf[pos] = fun->handle;
Index: uspace/srv/devman/driver.c
===================================================================
--- uspace/srv/devman/driver.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/devman/driver.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -210,11 +210,10 @@
 driver_t *find_best_match_driver(driver_list_t *drivers_list, dev_node_t *node)
 {
-	driver_t *best_drv = NULL, *drv = NULL;
+	driver_t *best_drv = NULL;
 	int best_score = 0, score = 0;
 	
 	fibril_mutex_lock(&drivers_list->drivers_mutex);
 	
-	list_foreach(drivers_list->drivers, link) {
-		drv = list_get_instance(link, driver_t, drivers);
+	list_foreach(drivers_list->drivers, drivers, driver_t, drv) {
 		score = get_match_score(drv, node);
 		if (score > best_score) {
@@ -310,10 +309,8 @@
 {
 	driver_t *res = NULL;
-	driver_t *drv = NULL;
 	
 	fibril_mutex_lock(&drv_list->drivers_mutex);
 	
-	list_foreach(drv_list->drivers, link) {
-		drv = list_get_instance(link, driver_t, drivers);
+	list_foreach(drv_list->drivers, drivers, driver_t, drv) {
 		if (str_cmp(drv->name, drv_name) == 0) {
 			res = drv;
Index: uspace/srv/devman/fun.c
===================================================================
--- uspace/srv/devman/fun.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/devman/fun.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -255,9 +255,5 @@
 	assert(fibril_rwlock_is_locked(&tree->rwlock));
 
-	fun_node_t *fun;
-
-	list_foreach(dev->functions, link) {
-		fun = list_get_instance(link, fun_node_t, dev_functions);
-
+	list_foreach(dev->functions, dev_functions, fun_node_t, fun) {
 		if (str_cmp(name, fun->name) == 0) {
 			fun_add_ref(fun);
Index: uspace/srv/fs/cdfs/cdfs_ops.c
===================================================================
--- uspace/srv/fs/cdfs/cdfs_ops.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/fs/cdfs/cdfs_ops.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -365,8 +365,5 @@
 	
 	/* Check for duplicate entries */
-	list_foreach(parent->cs_list, link) {
-		cdfs_dentry_t *dentry =
-		    list_get_instance(link, cdfs_dentry_t, link);
-		
+	list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) {
 		if (str_cmp(dentry->name, name) == 0)
 			return EEXIST;
@@ -524,8 +521,5 @@
 	}
 	
-	list_foreach(parent->cs_list, link) {
-		cdfs_dentry_t *dentry =
-		    list_get_instance(link, cdfs_dentry_t, link);
-		
+	list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) {
 		if (str_cmp(dentry->name, component) == 0) {
 			*fn = get_cached_node(parent->service_id, dentry->index);
Index: uspace/srv/fs/exfat/exfat_idx.c
===================================================================
--- uspace/srv/fs/exfat/exfat_idx.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/fs/exfat/exfat_idx.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -88,11 +88,8 @@
 static unused_t *unused_find(service_id_t service_id, bool lock)
 {
-	unused_t *u;
-
 	if (lock)
 		fibril_mutex_lock(&unused_lock);
 
-	list_foreach(unused_list, l) {
-		u = list_get_instance(l, unused_t, link);
+	list_foreach(unused_list, link, unused_t, u) {
 		if (u->service_id == service_id) 
 			return u;
Index: uspace/srv/fs/exfat/exfat_ops.c
===================================================================
--- uspace/srv/fs/exfat/exfat_ops.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/fs/exfat/exfat_ops.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -155,5 +155,4 @@
 static int exfat_node_fini_by_service_id(service_id_t service_id)
 {
-	exfat_node_t *nodep;
 	int rc;
 
@@ -166,6 +165,5 @@
 restart:
 	fibril_mutex_lock(&ffn_mutex);
-	list_foreach(ffn_list, lnk) {
-		nodep = list_get_instance(lnk, exfat_node_t, ffn_link);
+	list_foreach(ffn_list, ffn_link, exfat_node_t, nodep) {
 		if (!fibril_mutex_trylock(&nodep->lock)) {
 			fibril_mutex_unlock(&ffn_mutex);
Index: uspace/srv/fs/ext4fs/ext4fs_ops.c
===================================================================
--- uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -194,8 +194,5 @@
 	}
 	
-	list_foreach(instance_list, link) {
-		ext4fs_instance_t *tmp =
-		    list_get_instance(link, ext4fs_instance_t, link);
-		
+	list_foreach(instance_list, link, ext4fs_instance_t, tmp) {
 		if (tmp->service_id == service_id) {
 			*inst = tmp;
Index: uspace/srv/fs/fat/fat_idx.c
===================================================================
--- uspace/srv/fs/fat/fat_idx.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/fs/fat/fat_idx.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -88,11 +88,8 @@
 static unused_t *unused_find(service_id_t service_id, bool lock)
 {
-	unused_t *u;
-
 	if (lock)
 		fibril_mutex_lock(&unused_lock);
 
-	list_foreach(unused_list, l) {
-		u = list_get_instance(l, unused_t, link);
+	list_foreach(unused_list, link, unused_t, u) {
 		if (u->service_id == service_id) 
 			return u;
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -149,5 +149,4 @@
 static int fat_node_fini_by_service_id(service_id_t service_id)
 {
-	fat_node_t *nodep;
 	int rc;
 
@@ -160,6 +159,5 @@
 restart:
 	fibril_mutex_lock(&ffn_mutex);
-	list_foreach(ffn_list, lnk) {
-		nodep = list_get_instance(lnk, fat_node_t, ffn_link);
+	list_foreach(ffn_list, ffn_link, fat_node_t, nodep) {
 		if (!fibril_mutex_trylock(&nodep->lock)) {
 			fibril_mutex_unlock(&ffn_mutex);
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -259,7 +259,5 @@
 	tmpfs_node_t *parentp = TMPFS_NODE(pfn);
 
-	list_foreach(parentp->cs_list, lnk) {
-		tmpfs_dentry_t *dentryp;
-		dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
+	list_foreach(parentp->cs_list, link, tmpfs_dentry_t, dentryp) {
 		if (!str_cmp(dentryp->name, component)) {
 			*rfn = FS_NODE(dentryp->node);
@@ -365,7 +363,6 @@
 
 	/* Check for duplicit entries. */
-	list_foreach(parentp->cs_list, lnk) {
-		dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);	
-		if (!str_cmp(dentryp->name, nm))
+	list_foreach(parentp->cs_list, link, tmpfs_dentry_t, dp) {
+		if (!str_cmp(dp->name, nm))
 			return EEXIST;
 	}
@@ -400,8 +397,8 @@
 	if (!parentp)
 		return EBUSY;
-	
-	list_foreach(parentp->cs_list, lnk) {
-		dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
-		if (!str_cmp(dentryp->name, nm)) {
+
+	list_foreach(parentp->cs_list, link, tmpfs_dentry_t, dp) {
+		if (!str_cmp(dp->name, nm)) {
+			dentryp = dp;
 			childp = dentryp->node;
 			assert(FS_NODE(childp) == cfn);
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/hid/compositor/compositor.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -335,6 +335,5 @@
 	}
 
-	list_foreach(viewport_list, link) {
-		viewport_t *vp = list_get_instance(link, viewport_t, link);
+	list_foreach(viewport_list, link, viewport_t, vp) {
 		sysarg_t w_vp, h_vp;
 		surface_get_resolution(vp->surface, &w_vp, &h_vp);
@@ -354,6 +353,5 @@
 	fibril_mutex_lock(&pointer_list_mtx);
 
-	list_foreach(pointer_list, link) {
-		pointer_t *ptr = list_get_instance(link, pointer_t, link);
+	list_foreach(pointer_list, link, pointer_t, ptr) {
 		ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
 		ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y;
@@ -374,8 +372,6 @@
 	fibril_mutex_lock(&pointer_list_mtx);
 
-	list_foreach(viewport_list, link) {
-
+	list_foreach(viewport_list, link, viewport_t, vp) {
 		/* Determine what part of the viewport must be updated. */
-		viewport_t *vp = list_get_instance(link, viewport_t, link);
 		sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
 		surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp);
@@ -446,7 +442,5 @@
 			}
 
-			list_foreach(pointer_list, link) {
-
-				pointer_t *ptr = list_get_instance(link, pointer_t, link);
+			list_foreach(pointer_list, link, pointer_t, ptr) {
 				if (ptr->ghost.surface) {
 
@@ -522,9 +516,8 @@
 			}
 
-			list_foreach(pointer_list, link) {
+			list_foreach(pointer_list, link, pointer_t, ptr) {
 
 				/* Determine what part of the pointer intersects with the
 				 * updated area of the current viewport. */
-				pointer_t *ptr = list_get_instance(link, pointer_t, link);
 				sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr;
 				surface_t *sf_ptr = ptr->cursor.states[ptr->state];
@@ -569,6 +562,5 @@
 
 	/* Notify visualizers about updated regions. */
-	list_foreach(viewport_list, link) {
-		viewport_t *vp = list_get_instance(link, viewport_t, link);
+	list_foreach(viewport_list, link, viewport_t, vp) {
 		sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
 		surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
@@ -631,6 +623,5 @@
 
 	fibril_mutex_lock(&pointer_list_mtx);
-	list_foreach(pointer_list, link) {
-		pointer_t *pointer = list_get_instance(link, pointer_t, link);
+	list_foreach(pointer_list, link, pointer_t, pointer) {
 		if (pointer->id == pos_id) {
 			pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
@@ -710,15 +701,15 @@
 {
 	fibril_mutex_lock(&window_list_mtx);
-	window_t *window = NULL;
-	list_foreach(window_list, link) {
-		window = list_get_instance(link, window_t, link);
+
+	list_foreach(window_list, link, window_t, window) {
 		if (window == target) {
 			prodcons_produce(&window->queue, &event->link);
-		}
-	}
-	if (!window) {
-		free(event);
-	}
+			fibril_mutex_unlock(&window_list_mtx);
+			return;
+		}
+	}
+
 	fibril_mutex_unlock(&window_list_mtx);
+	free(event);
 }
 
@@ -863,6 +854,5 @@
 	window_t *win = NULL;
 	fibril_mutex_lock(&window_list_mtx);
-	list_foreach(window_list, link) {
-		window_t *cur = list_get_instance(link, window_t, link);
+	list_foreach(window_list, link, window_t, cur) {
 		if (cur->in_dsid == service_id || cur->out_dsid == service_id) {
 			win = cur;
@@ -1007,6 +997,5 @@
 		/* Close all clients and their windows. */
 		fibril_mutex_lock(&window_list_mtx);
-		list_foreach(window_list, link) {
-			window_t *win = list_get_instance(link, window_t, link);
+		list_foreach(window_list, link, window_t, win) {
 			window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
 			if (event) {
@@ -1034,6 +1023,5 @@
 	viewport_t *vp = NULL;
 	fibril_mutex_lock(&viewport_list_mtx);
-	list_foreach(viewport_list, link) {
-		viewport_t *cur = list_get_instance(link, viewport_t, link);
+	list_foreach(viewport_list, link, viewport_t, cur) {
 		if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
 			vp = cur;
@@ -1571,6 +1559,6 @@
 
 	/* Determine the window which the mouse click belongs to. */
-	list_foreach(window_list, link) {
-		win = list_get_instance(link, window_t, link);
+	list_foreach(window_list, link, window_t, cw) {
+		win = cw;
 		if (win->surface) {
 			surface_get_resolution(win->surface, &width, &height);
Index: uspace/srv/hid/input/input.c
===================================================================
--- uspace/srv/hid/input/input.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/hid/input/input.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -470,8 +470,5 @@
 {
 	/* For each keyboard device */
-	list_foreach(kbd_devs, kdev_link) {
-		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
-		    kbd_devs);
-		
+	list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {
 		/* Yield port */
 		if (kdev->port_ops != NULL)
@@ -483,8 +480,5 @@
 {
 	/* For each keyboard device */
-	list_foreach(kbd_devs, kdev_link) {
-		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
-		    kbd_devs);
-		
+	list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {
 		/* Reclaim port */
 		if (kdev->port_ops != NULL)
@@ -521,7 +515,5 @@
 		
 		/* Determine whether we already know this device. */
-		list_foreach(kbd_devs, kdev_link) {
-			kbd_dev_t *kdev = list_get_instance(kdev_link,
-			    kbd_dev_t, kbd_devs);
+		list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {
 			if (kdev->svc_id == svcs[i]) {
 				already_known = true;
@@ -574,7 +566,5 @@
 		
 		/* Determine whether we already know this device. */
-		list_foreach(mouse_devs, mdev_link) {
-			mouse_dev_t *mdev = list_get_instance(mdev_link,
-			    mouse_dev_t, mouse_devs);
+		list_foreach(mouse_devs, mouse_devs, mouse_dev_t, mdev) {
 			if (mdev->svc_id == svcs[i]) {
 				already_known = true;
Index: uspace/srv/hid/output/output.c
===================================================================
--- uspace/srv/hid/output/output.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/hid/output/output.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -82,7 +82,5 @@
 	int ret = EOK;
 	
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		assert(dev->ops.yield);
 		
@@ -99,7 +97,5 @@
 	int ret = EOK;
 	
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		assert(dev->ops.claim);
 		
@@ -117,7 +113,5 @@
 	sysarg_t rows = MAX_ROWS;
 	
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		cols = min(cols, dev->cols);
 		rows = min(rows, dev->rows);
@@ -131,7 +125,5 @@
 	console_caps_t caps = 0;
 	
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		assert(dev->ops.get_caps);
 		
@@ -145,6 +137,5 @@
 {
 	frontbuf_t *frontbuf = NULL;
-	list_foreach(frontbufs, link) {
-		frontbuf_t *cur = list_get_instance(link, frontbuf_t, link);
+	list_foreach(frontbufs, link, frontbuf_t, cur) {
 		if (cur == (frontbuf_t *) handle) {
 			frontbuf = cur;
@@ -216,7 +207,5 @@
 	chargrid_get_cursor(buf, &col, &row);
 	
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		assert(dev->ops.cursor_update);
 		
@@ -237,7 +226,5 @@
 static void srv_set_style(ipc_callid_t iid, ipc_call_t *icall)
 {
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		dev->attrs.type = CHAR_ATTR_STYLE;
 		dev->attrs.val.style =
@@ -250,7 +237,5 @@
 static void srv_set_color(ipc_callid_t iid, ipc_call_t *icall)
 {
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		dev->attrs.type = CHAR_ATTR_INDEX;
 		dev->attrs.val.index.bgcolor =
@@ -267,7 +252,5 @@
 static void srv_set_rgb_color(ipc_callid_t iid, ipc_call_t *icall)
 {
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		dev->attrs.type = CHAR_ATTR_RGB;
 		dev->attrs.val.rgb.bgcolor = IPC_GET_ARG1(*icall);
@@ -325,7 +308,5 @@
 	chargrid_t *buf = (chargrid_t *) frontbuf->data;
 	
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		assert(dev->ops.char_update);
 		
@@ -374,7 +355,5 @@
 	chargrid_t *buf = (chargrid_t *) frontbuf->data;
 	
-	list_foreach(outdevs, link) {
-		outdev_t *dev = list_get_instance(link, outdev_t, link);
-		
+	list_foreach(outdevs, link, outdev_t, dev) {
 		assert(dev->ops.char_update);
 		
Index: uspace/srv/hid/remcons/user.c
===================================================================
--- uspace/srv/hid/remcons/user.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/hid/remcons/user.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -128,6 +128,5 @@
 
 	fibril_mutex_lock(&users_guard);
-	list_foreach(users, link) {
-		telnet_user_t *tmp = list_get_instance(link, telnet_user_t, link);
+	list_foreach(users, link, telnet_user_t, tmp) {
 		if (tmp->service_id == id) {
 			user = tmp;
Index: uspace/srv/locsrv/category.c
===================================================================
--- uspace/srv/locsrv/category.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/locsrv/category.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -73,8 +73,5 @@
 
 	size_t pos = 0;
-	list_foreach(cdir->categories, item) {
-		category_t *cat =
-		    list_get_instance(item, category_t, cat_list);
-
+	list_foreach(cdir->categories, cat_list, category_t, cat) {
 		if (pos < buf_cnt)
 			id_buf[pos] = cat->id;
@@ -116,7 +113,5 @@
 
 	/* Verify that category does not contain this service yet. */
-	list_foreach(cat->svc_memb, item) {
-		svc_categ_t *memb = list_get_instance(item, svc_categ_t,
-		    cat_link);
+	list_foreach(cat->svc_memb, cat_link, svc_categ_t, memb) {
 		if (memb->svc == svc) {
 			return EEXIST;
@@ -154,7 +149,5 @@
 	assert(fibril_mutex_is_locked(&cdir->mutex));
 
-	list_foreach(cdir->categories, item) {
-		category_t *cat = list_get_instance(item, category_t,
-		    cat_list);
+	list_foreach(cdir->categories, cat_list, category_t, cat) {
 		if (cat->id == catid)
 			return cat;
@@ -169,7 +162,5 @@
 	assert(fibril_mutex_is_locked(&cdir->mutex));
 
-	list_foreach(cdir->categories, item) {
-		category_t *cat = list_get_instance(item, category_t,
-		    cat_list);
+	list_foreach(cdir->categories, cat_list, category_t, cat) {
 		if (str_cmp(cat->name, name) == 0)
 			return cat;
@@ -197,8 +188,5 @@
 
 	size_t pos = 0;
-	list_foreach(cat->svc_memb, item) {
-		svc_categ_t *memb =
-		    list_get_instance(item, svc_categ_t, cat_link);
-
+	list_foreach(cat->svc_memb, cat_link, svc_categ_t, memb) {
 		if (pos < buf_cnt)
 			id_buf[pos] = memb->svc->id;
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/locsrv/locsrv.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -184,7 +184,5 @@
 	assert(fibril_mutex_is_locked(&services_list_mutex));
 	
-	list_foreach(namespaces_list, item) {
-		loc_namespace_t *namespace =
-		    list_get_instance(item, loc_namespace_t, namespaces);
+	list_foreach(namespaces_list, namespaces, loc_namespace_t, namespace) {
 		if (str_cmp(namespace->name, name) == 0)
 			return namespace;
@@ -203,7 +201,5 @@
 	assert(fibril_mutex_is_locked(&services_list_mutex));
 	
-	list_foreach(namespaces_list, item) {
-		loc_namespace_t *namespace =
-		    list_get_instance(item, loc_namespace_t, namespaces);
+	list_foreach(namespaces_list, namespaces, loc_namespace_t, namespace) {
 		if (namespace->id == id)
 			return namespace;
@@ -219,7 +215,5 @@
 	assert(fibril_mutex_is_locked(&services_list_mutex));
 	
-	list_foreach(services_list, item) {
-		loc_service_t *service =
-		    list_get_instance(item, loc_service_t, services);
+	list_foreach(services_list, services, loc_service_t, service) {
 		if ((str_cmp(service->namespace->name, ns_name) == 0)
 		    && (str_cmp(service->name, name) == 0))
@@ -239,7 +233,5 @@
 	assert(fibril_mutex_is_locked(&services_list_mutex));
 	
-	list_foreach(services_list, item) {
-		loc_service_t *service =
-		    list_get_instance(item, loc_service_t, services);
+	list_foreach(services_list, services, loc_service_t, service) {
 		if (service->id == id)
 			return service;
@@ -889,9 +881,5 @@
 	fibril_mutex_lock(&callback_sess_mutex);
 	
-	list_foreach(callback_sess_list, link) {
-		cb_sess_t *cb_sess;
-		
-		cb_sess = list_get_instance(link, cb_sess_t, cb_sess_list);
-		
+	list_foreach(callback_sess_list, cb_sess_list, cb_sess_t, cb_sess) {
 		async_exch_t *exch = async_exchange_begin(cb_sess->sess);
 		async_msg_0(exch, LOC_EVENT_CAT_CHANGE);
@@ -1050,8 +1038,5 @@
 	
 	size_t pos = 0;
-	list_foreach(namespaces_list, item) {
-		loc_namespace_t *namespace =
-		    list_get_instance(item, loc_namespace_t, namespaces);
-		
+	list_foreach(namespaces_list, namespaces, loc_namespace_t, namespace) {
 		desc[pos].id = namespace->id;
 		str_cpy(desc[pos].name, LOC_NAME_MAXLEN, namespace->name);
@@ -1114,8 +1099,5 @@
 	
 	size_t pos = 0;
-	list_foreach(services_list, item) {
-		loc_service_t *service =
-		    list_get_instance(item, loc_service_t, services);
-		
+	list_foreach(services_list, services, loc_service_t, service) {
 		if (service->namespace == namespace) {
 			desc[pos].id = service->id;
Index: uspace/srv/logger/logs.c
===================================================================
--- uspace/srv/logger/logs.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/logger/logs.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -44,6 +44,5 @@
 static logger_log_t *find_log_by_name_and_parent_no_list_lock(const char *name, logger_log_t *parent)
 {
-	list_foreach(log_list, it) {
-		logger_log_t *log = list_get_instance(it, logger_log_t, link);
+	list_foreach(log_list, link, logger_log_t, log) {
 		if ((parent == log->parent) && (str_cmp(log->name, name) == 0))
 			return log;
@@ -148,6 +147,5 @@
 
 	fibril_mutex_lock(&log_list_guard);
-	list_foreach(log_list, it) {
-		logger_log_t *log = list_get_instance(it, logger_log_t, link);
+	list_foreach(log_list, link, logger_log_t, log) {
 		if (str_cmp(log->full_name, name) == 0) {
 			fibril_mutex_lock(&log->guard);
@@ -166,6 +164,5 @@
 
 	fibril_mutex_lock(&log_list_guard);
-	list_foreach(log_list, it) {
-		logger_log_t *log = list_get_instance(it, logger_log_t, link);
+	list_foreach(log_list, link, logger_log_t, log) {
 		if ((sysarg_t) log == id) {
 			fibril_mutex_lock(&log->guard);
Index: uspace/srv/net/dnsrsrv/dns_msg.c
===================================================================
--- uspace/srv/net/dnsrsrv/dns_msg.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/dnsrsrv/dns_msg.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -510,6 +510,5 @@
 	size = sizeof(dns_header_t);
 
-	list_foreach(msg->question, link) {
-		dns_question_t *q = list_get_instance(link, dns_question_t, msg);
+	list_foreach(msg->question, msg, dns_question_t, q) {
 		rc = dns_question_encode(q, NULL, 0, &q_size);
 		if (rc != EOK)
@@ -526,6 +525,5 @@
 	di = sizeof(dns_header_t);
 
-	list_foreach(msg->question, link) {
-		dns_question_t *q = list_get_instance(link, dns_question_t, msg);
+	list_foreach(msg->question, msg, dns_question_t, q) {
 		rc = dns_question_encode(q, data + di, size - di, &q_size);
 		if (rc != EOK) {
Index: uspace/srv/net/dnsrsrv/query.c
===================================================================
--- uspace/srv/net/dnsrsrv/query.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/dnsrsrv/query.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -99,7 +99,5 @@
 	}
 	
-	list_foreach(amsg->answer, link) {
-		dns_rr_t *rr = list_get_instance(link, dns_rr_t, msg);
-		
+	list_foreach(amsg->answer, msg, dns_rr_t, rr) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG, " - '%s' %u/%u, dsize %zu",
 		    rr->name, rr->rtype, rr->rclass, rr->rdata_size);
Index: uspace/srv/net/dnsrsrv/transport.c
===================================================================
--- uspace/srv/net/dnsrsrv/transport.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/dnsrsrv/transport.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -158,7 +158,5 @@
 	assert(fibril_mutex_is_locked(&treq_lock));
 
-	list_foreach(treq_list, link) {
-		trans_req_t *treq = list_get_instance(link, trans_req_t, lreq);
-
+	list_foreach(treq_list, lreq, trans_req_t, treq) {
 		if (treq->req->id == resp->id) {
 			/* Match */
Index: uspace/srv/net/ethip/atrans.c
===================================================================
--- uspace/srv/net/ethip/atrans.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/ethip/atrans.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -51,8 +51,5 @@
 static ethip_atrans_t *atrans_find(addr32_t ip_addr)
 {
-	list_foreach(atrans_list, link) {
-		ethip_atrans_t *atrans = list_get_instance(link,
-		    ethip_atrans_t, atrans_list);
-
+	list_foreach(atrans_list, atrans_list, ethip_atrans_t, atrans) {
 		if (atrans->ip_addr == ip_addr)
 			return atrans;
Index: uspace/srv/net/ethip/ethip_nic.c
===================================================================
--- uspace/srv/net/ethip/ethip_nic.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/ethip/ethip_nic.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -84,7 +84,5 @@
 		already_known = false;
 
-		list_foreach(ethip_nic_list, link) {
-			ethip_nic_t *nic = list_get_instance(link,
-			    ethip_nic_t, link);
+		list_foreach(ethip_nic_list, link, ethip_nic_t, nic) {
 			if (nic->svc_id == svcs[i]) {
 				already_known = true;
@@ -313,8 +311,6 @@
 	    (unsigned) iplink_sid);
 
-	list_foreach(ethip_nic_list, link) {
+	list_foreach(ethip_nic_list, link, ethip_nic_t, nic) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - element");
-		ethip_nic_t *nic = list_get_instance(link, ethip_nic_t, link);
-
 		if (nic->iplink_sid == iplink_sid) {
 			log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - found %p", nic);
@@ -350,8 +346,5 @@
 	size_t count = 0;
 	
-	list_foreach(nic->addr_list, link) {
-		ethip_link_addr_t *laddr = list_get_instance(link,
-		    ethip_link_addr_t, link);
-		
+	list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
 		uint16_t af = inet_addr_get(&laddr->addr, NULL, NULL);
 		if (af == AF_INET6)
@@ -371,8 +364,5 @@
 	size_t i = 0;
 	
-	list_foreach(nic->addr_list, link) {
-		ethip_link_addr_t *laddr = list_get_instance(link,
-		    ethip_link_addr_t, link);
-		
+	list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
 		addr128_t v6;
 		uint16_t af = inet_addr_get(&laddr->addr, NULL, &v6);
@@ -444,8 +434,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_find()");
 	
-	list_foreach(nic->addr_list, link) {
-		ethip_link_addr_t *laddr = list_get_instance(link,
-		    ethip_link_addr_t, link);
-		
+	list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
 		if (inet_addr_compare(addr, &laddr->addr))
 			return laddr;
Index: uspace/srv/net/inetsrv/addrobj.c
===================================================================
--- uspace/srv/net/inetsrv/addrobj.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/inetsrv/addrobj.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -115,8 +115,5 @@
 	fibril_mutex_lock(&addr_list_lock);
 	
-	list_foreach(addr_list, link) {
-		inet_addrobj_t *naddr = list_get_instance(link,
-		    inet_addrobj_t, addr_list);
-		
+	list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
 		switch (find) {
 		case iaf_net:
@@ -158,8 +155,5 @@
 	    name, ilink->svc_name);
 
-	list_foreach(addr_list, link) {
-		inet_addrobj_t *naddr = list_get_instance(link,
-		    inet_addrobj_t, addr_list);
-
+	list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
 		if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) {
 			log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: found %p",
@@ -206,8 +200,5 @@
 	fibril_mutex_lock(&addr_list_lock);
 
-	list_foreach(addr_list, link) {
-		inet_addrobj_t *naddr = list_get_instance(link,
-		    inet_addrobj_t, addr_list);
-
+	list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
 		if (naddr->id == id) {
 			fibril_mutex_unlock(&addr_list_lock);
@@ -277,8 +268,5 @@
 
 	i = 0;
-	list_foreach(addr_list, link) {
-		inet_addrobj_t *addr = list_get_instance(link,
-		    inet_addrobj_t, addr_list);
-
+	list_foreach(addr_list, addr_list, inet_addrobj_t, addr) {
 		id_list[i++] = addr->id;
 	}
Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -140,7 +140,5 @@
 		already_known = false;
 
-		list_foreach(inet_link_list, ilink_link) {
-			inet_link_t *ilink = list_get_instance(ilink_link,
-			    inet_link_t, link_list);
+		list_foreach(inet_link_list, link_list, inet_link_t, ilink) {
 			if (ilink->svc_id == svcs[i]) {
 				already_known = true;
@@ -492,8 +490,5 @@
 	fibril_mutex_lock(&inet_discovery_lock);
 
-	list_foreach(inet_link_list, elem) {
-		inet_link_t *ilink = list_get_instance(elem, inet_link_t,
-		    link_list);
-
+	list_foreach(inet_link_list, link_list, inet_link_t, ilink) {
 		if (ilink->svc_id == link_id) {
 			fibril_mutex_unlock(&inet_discovery_lock);
Index: uspace/srv/net/inetsrv/inetping.c
===================================================================
--- uspace/srv/net/inetsrv/inetping.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/inetsrv/inetping.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -82,8 +82,5 @@
 	fibril_mutex_lock(&client_list_lock);
 	
-	list_foreach(client_list, link) {
-		inetping_client_t *client = list_get_instance(link,
-		    inetping_client_t, client_list);
-		
+	list_foreach(client_list, client_list, inetping_client_t, client) {
 		if (client->ident == ident) {
 			fibril_mutex_unlock(&client_list_lock);
Index: uspace/srv/net/inetsrv/inetping6.c
===================================================================
--- uspace/srv/net/inetsrv/inetping6.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/inetsrv/inetping6.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -82,8 +82,5 @@
 	fibril_mutex_lock(&client_list_lock);
 	
-	list_foreach(client_list, link) {
-		inetping6_client_t *client = list_get_instance(link,
-		    inetping6_client_t, client_list);
-		
+	list_foreach(client_list, client_list, inetping6_client_t, client) {
 		if (client->ident == ident) {
 			fibril_mutex_unlock(&client_list_lock);
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -446,8 +446,5 @@
 	fibril_mutex_lock(&client_list_lock);
 
-	list_foreach(client_list, link) {
-		inet_client_t *client = list_get_instance(link, inet_client_t,
-		    client_list);
-
+	list_foreach(client_list, client_list, inet_client_t, client) {
 		if (client->protocol == proto) {
 			fibril_mutex_unlock(&client_list_lock);
Index: uspace/srv/net/inetsrv/ntrans.c
===================================================================
--- uspace/srv/net/inetsrv/ntrans.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/inetsrv/ntrans.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -56,8 +56,5 @@
 static inet_ntrans_t *ntrans_find(addr128_t ip_addr)
 {
-	list_foreach(ntrans_list, link) {
-		inet_ntrans_t *ntrans = list_get_instance(link,
-		    inet_ntrans_t, ntrans_list);
-
+	list_foreach(ntrans_list, ntrans_list, inet_ntrans_t, ntrans) {
 		if (addr128_compare(ntrans->ip_addr, ip_addr))
 			return ntrans;
Index: uspace/srv/net/inetsrv/reass.c
===================================================================
--- uspace/srv/net/inetsrv/reass.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/inetsrv/reass.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -129,8 +129,5 @@
 	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
 
-	list_foreach(reass_dgram_map, link) {
-		reass_dgram_t *rdg = list_get_instance(link, reass_dgram_t,
-		    map_link);
-
+	list_foreach(reass_dgram_map, map_link, reass_dgram_t, rdg) {
 		link_t *f1_link = list_first(&rdg->frags);
 		assert(f1_link != NULL);
@@ -289,6 +286,6 @@
 	size_t fragoff_limit;
 	inet_dgram_t dgram;
+	uint8_t proto;
 	reass_frag_t *frag;
-	uint8_t proto;
 
 	/*
@@ -297,9 +294,9 @@
 	 */
 	frag = NULL;
-	list_foreach(rdg->frags, link) {
-		frag = list_get_instance(link, reass_frag_t, dgram_link);
-
-		if (!frag->packet.mf)
+	list_foreach(rdg->frags, dgram_link, reass_frag_t, cfrag) {
+		if (!cfrag->packet.mf) {
+			frag = cfrag;
 			break;
+		}
 	}
 
@@ -330,20 +327,17 @@
 	size_t doffs = 0;
 
-	frag = NULL;
-	list_foreach(rdg->frags, link) {
-		frag = list_get_instance(link, reass_frag_t, dgram_link);
-
+	list_foreach(rdg->frags, dgram_link, reass_frag_t, cfrag) {
 		size_t cb, ce;
 
-		cb = max(doffs, frag->packet.offs);
-		ce = min(dgram_size, frag->packet.offs + frag->packet.size);
+		cb = max(doffs, cfrag->packet.offs);
+		ce = min(dgram_size, cfrag->packet.offs + cfrag->packet.size);
 
 		if (ce > cb) {
 			memcpy(dgram.data + cb,
-			    frag->packet.data + cb - frag->packet.offs,
+			    cfrag->packet.data + cb - cfrag->packet.offs,
 			    ce - cb);
 		}
 
-		if (!frag->packet.mf)
+		if (!cfrag->packet.mf)
 			break;
 	}
Index: uspace/srv/net/inetsrv/sroute.c
===================================================================
--- uspace/srv/net/inetsrv/sroute.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/inetsrv/sroute.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -89,5 +89,5 @@
 }
 
-/** Find address object matching address @a addr.
+/** Find static route object matching address @a addr.
  *
  * @param addr	Address
@@ -102,8 +102,5 @@
 	fibril_mutex_lock(&sroute_list_lock);
 	
-	list_foreach(sroute_list, link) {
-		inet_sroute_t *sroute = list_get_instance(link,
-		    inet_sroute_t, sroute_list);
-		
+	list_foreach(sroute_list, sroute_list, inet_sroute_t, sroute) {
 		uint8_t dest_bits;
 		uint16_t dest_af = inet_naddr_get(&sroute->dest, NULL, NULL,
@@ -147,8 +144,5 @@
 	fibril_mutex_lock(&sroute_list_lock);
 
-	list_foreach(sroute_list, link) {
-		inet_sroute_t *sroute = list_get_instance(link,
-		    inet_sroute_t, sroute_list);
-
+	list_foreach(sroute_list, sroute_list, inet_sroute_t, sroute) {
 		if (str_cmp(sroute->name, name) == 0) {
 			fibril_mutex_unlock(&sroute_list_lock);
@@ -176,8 +170,5 @@
 	fibril_mutex_lock(&sroute_list_lock);
 
-	list_foreach(sroute_list, link) {
-		inet_sroute_t *sroute = list_get_instance(link,
-		    inet_sroute_t, sroute_list);
-
+	list_foreach(sroute_list, sroute_list, inet_sroute_t, sroute) {
 		if (sroute->id == id) {
 			fibril_mutex_unlock(&sroute_list_lock);
@@ -207,8 +198,5 @@
 
 	i = 0;
-	list_foreach(sroute_list, link) {
-		inet_sroute_t *sroute = list_get_instance(link,
-		    inet_sroute_t, sroute_list);
-
+	list_foreach(sroute_list, sroute_list, inet_sroute_t, sroute) {
 		id_list[i++] = sroute->id;
 	}
Index: uspace/srv/net/tcp/conn.c
===================================================================
--- uspace/srv/net/tcp/conn.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/tcp/conn.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -360,6 +360,5 @@
 	fibril_mutex_lock(&conn_list_lock);
 	
-	list_foreach(conn_list, link) {
-		tcp_conn_t *conn = list_get_instance(link, tcp_conn_t, link);
+	list_foreach(conn_list, link, tcp_conn_t, conn) {
 		tcp_sockpair_t *csp = &conn->ident;
 		
Index: uspace/srv/net/udp/assoc.c
===================================================================
--- uspace/srv/net/udp/assoc.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/net/udp/assoc.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -419,6 +419,5 @@
 	fibril_mutex_lock(&assoc_list_lock);
 	
-	list_foreach(assoc_list, link) {
-		udp_assoc_t *assoc = list_get_instance(link, udp_assoc_t, link);
+	list_foreach(assoc_list, link, udp_assoc_t, assoc) {
 		udp_sockpair_t *asp = &assoc->ident;
 		
Index: uspace/srv/ns/service.c
===================================================================
--- uspace/srv/ns/service.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/ns/service.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -106,7 +106,5 @@
 {
 loop:
-	list_foreach(pending_conn, cur) {
-		pending_conn_t *pr = list_get_instance(cur, pending_conn_t, link);
-		
+	list_foreach(pending_conn, link, pending_conn_t, pr) {
 		ht_link_t *link = hash_table_find(&service_hash_table, &pr->service);
 		if (!link)
@@ -117,5 +115,5 @@
 		    pr->arg3, 0, IPC_FF_NONE);
 		
-		list_remove(cur);
+		list_remove(&pr->link);
 		free(pr);
 		goto loop;
Index: uspace/srv/ns/task.c
===================================================================
--- uspace/srv/ns/task.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/ns/task.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -179,7 +179,5 @@
 	
 loop:
-	list_foreach(pending_wait, cur) {
-		pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link);
-		
+	list_foreach(pending_wait, link, pending_wait_t, pr) {
 		ht_link_t *link = hash_table_find(&task_hash_table, &pr->id);
 		if (!link)
@@ -198,5 +196,5 @@
 		
 		hash_table_remove(&task_hash_table, &pr->id);
-		list_remove(cur);
+		list_remove(&pr->link);
 		free(pr);
 		goto loop;
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/vfs/vfs_ops.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -548,8 +548,5 @@
 	int found = 0;
 
-	list_foreach(mtab_list, cur) {
-		mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t,
-		    link);
-
+	list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
 		if (str_cmp(mtab_ent->mp, mp) == 0) {
 			list_remove(&mtab_ent->link);
@@ -1371,8 +1368,5 @@
 	async_answer_1(callid, EOK, mtab_size);
 
-	list_foreach(mtab_list, cur) {
-		mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t,
-		    link);
-
+	list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
 		rc = ENOTSUP;
 
Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision a60e90b77be0a223cc67fdf941b5d620622260c6)
+++ uspace/srv/vfs/vfs_register.c	(revision 08bc23d60e18d91f38bdbbfc8ee0bc0a7c796879)
@@ -260,7 +260,5 @@
 	fibril_mutex_lock(&fs_list_lock);
 	
-	list_foreach(fs_list, cur) {
-		fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
-		
+	list_foreach(fs_list, fs_link, fs_info_t, fs) {
 		if (fs->fs_handle == handle) {
 			fibril_mutex_unlock(&fs_list_lock);
@@ -305,6 +303,5 @@
 		fibril_mutex_lock(&fs_list_lock);
 	
-	list_foreach(fs_list, cur) {
-		fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
+	list_foreach(fs_list, fs_link, fs_info_t, fs) {
 		if (str_cmp(fs->vfs_info.name, name) == 0 &&
 		    instance == fs->vfs_info.instance) {
@@ -332,6 +329,5 @@
 	
 	fibril_mutex_lock(&fs_list_lock);
-	list_foreach(fs_list, cur) {
-		fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
+	list_foreach(fs_list, fs_link, fs_info_t, fs) {
 		if (fs->fs_handle == handle) { 
 			info = &fs->vfs_info;
