Index: abi/include/ddi/arg.h
===================================================================
--- abi/include/ddi/arg.h	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ abi/include/ddi/arg.h	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -36,4 +36,6 @@
 #define ABI_DDI_ARG_H_
 
+#define DMAMEM_FLAGS_ANONYMOUS  0x01
+
 /** Structure encapsulating arguments for SYS_PHYSMEM_MAP syscall. */
 typedef struct {
Index: abi/include/syscall.h
===================================================================
--- abi/include/syscall.h	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ abi/include/syscall.h	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -85,4 +85,6 @@
 	SYS_DEVICE_ASSIGN_DEVNO,
 	SYS_PHYSMEM_MAP,
+	SYS_DMAMEM_MAP,
+	SYS_DMAMEM_UNMAP,
 	SYS_IOSPACE_ENABLE,
 	SYS_REGISTER_IRQ,
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ kernel/generic/include/ddi/ddi.h	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -55,5 +55,10 @@
 extern void ddi_parea_register(parea_t *);
 
-extern sysarg_t sys_physmem_map(sysarg_t, sysarg_t, sysarg_t, sysarg_t);
+extern sysarg_t sys_physmem_map(uintptr_t, uintptr_t, size_t, unsigned int);
+
+extern sysarg_t sys_dmamem_map(uintptr_t, size_t, unsigned int, unsigned int,
+    void *);
+extern sysarg_t sys_dmamem_unmap(uintptr_t, size_t, unsigned int);
+
 extern sysarg_t sys_iospace_enable(ddi_ioarg_t *);
 
Index: kernel/generic/include/mm/page.h
===================================================================
--- kernel/generic/include/mm/page.h	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ kernel/generic/include/mm/page.h	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -66,5 +66,6 @@
 extern uintptr_t hw_map(uintptr_t, size_t);
 
-extern sysarg_t sys_page_find_mapping(uintptr_t, uintptr_t *);
+extern int page_find_mapping(uintptr_t, void **);
+extern sysarg_t sys_page_find_mapping(uintptr_t, void *);
 
 #endif
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ kernel/generic/src/ddi/ddi.c	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -45,4 +45,5 @@
 #include <mm/frame.h>
 #include <mm/as.h>
+#include <mm/page.h>
 #include <synch/mutex.h>
 #include <syscall/copy.h>
@@ -52,4 +53,5 @@
 #include <errno.h>
 #include <trace.h>
+#include <bitops.h>
 
 /** This lock protects the parea_btree. */
@@ -87,25 +89,26 @@
 /** Map piece of physical memory into virtual address space of current task.
  *
- * @param pf    Physical address of the starting frame.
- * @param vp    Virtual address of the starting page.
+ * @param phys  Physical address of the starting frame.
+ * @param virt  Virtual address of the starting page.
  * @param pages Number of pages to map.
  * @param flags Address space area flags for the mapping.
  *
- * @return 0 on success, EPERM if the caller lacks capabilities to use this
- *         syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there
- *         is no task matching the specified ID or the physical address space
- *         is not enabled for mapping and ENOMEM if there was a problem in
- *         creating address space area.
- *
- */
-NO_TRACE static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages,
+ * @return EOK on success.
+ * @return EPERM if the caller lacks capabilities to use this syscall.
+ * @return EBADMEM if phys or virt is not page aligned.
+ * @return ENOENT if there is no task matching the specified ID or
+ *         the physical address space is not enabled for mapping.
+ * @return ENOMEM if there was a problem in creating address space area.
+ *
+ */
+NO_TRACE static int ddi_physmem_map(uintptr_t phys, uintptr_t virt, size_t pages,
     unsigned int flags)
 {
 	ASSERT(TASK);
 	
-	if ((pf % FRAME_SIZE) != 0)
+	if ((phys % FRAME_SIZE) != 0)
 		return EBADMEM;
 	
-	if ((vp % PAGE_SIZE) != 0)
+	if ((virt % PAGE_SIZE) != 0)
 		return EBADMEM;
 	
@@ -118,5 +121,5 @@
 	
 	mem_backend_data_t backend_data;
-	backend_data.base = pf;
+	backend_data.base = phys;
 	backend_data.frames = pages;
 	
@@ -129,5 +132,5 @@
 	btree_node_t *nodep;
 	parea_t *parea = (parea_t *) btree_search(&parea_btree,
-	    (btree_key_t) pf, &nodep);
+	    (btree_key_t) phys, &nodep);
 	
 	if ((parea != NULL) && (parea->frames >= pages)) {
@@ -149,5 +152,5 @@
 	
 	irq_spinlock_lock(&zones.lock, true);
-	size_t znum = find_zone(ADDR2PFN(pf), pages, 0);
+	size_t znum = find_zone(ADDR2PFN(phys), pages, 0);
 	
 	if (znum == (size_t) -1) {
@@ -182,5 +185,5 @@
 	
 map:
-	if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp,
+	if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages), virt,
 	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
 		/*
@@ -253,6 +256,6 @@
 /** Wrapper for SYS_PHYSMEM_MAP syscall.
  *
- * @param phys_base Physical base address to map
- * @param virt_base Destination virtual address
+ * @param phys  Physical base address to map
+ * @param virt  Destination virtual address
  * @param pages Number of pages
  * @param flags Flags of newly mapped pages
@@ -261,10 +264,10 @@
  *
  */
-sysarg_t sys_physmem_map(sysarg_t phys_base, sysarg_t virt_base,
-    sysarg_t pages, sysarg_t flags)
-{
-	return (sysarg_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base,
-	    FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE),
-	    (size_t) pages, (int) flags);
+sysarg_t sys_physmem_map(uintptr_t phys, uintptr_t virt,
+    size_t pages, unsigned int flags)
+{
+	return (sysarg_t)
+	    ddi_physmem_map(ALIGN_DOWN(phys, FRAME_SIZE),
+	    ALIGN_DOWN(virt, PAGE_SIZE), pages, flags);
 }
 
@@ -287,4 +290,74 @@
 }
 
+NO_TRACE static int dmamem_map(uintptr_t virt, size_t size,
+    unsigned int map_flags, unsigned int flags, void **phys)
+{
+	ASSERT(TASK);
+	
+	if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0) {
+		// TODO: implement locking of non-anonymous mapping
+		return page_find_mapping(virt, phys);
+	} else {
+		// TODO: implement locking
+		
+		if ((virt % PAGE_SIZE) != 0)
+			return EBADMEM;
+		
+		size_t pages = SIZE2FRAMES(size);
+		uint8_t order;
+		
+		/* We need the 2^order >= pages */
+		if (pages == 1)
+			order = 0;
+		else
+			order = fnzb(pages - 1) + 1;
+		
+		*phys = frame_alloc_noreserve(order, 0);
+		if (*phys == NULL)
+			return ENOMEM;
+		
+		mem_backend_data_t backend_data;
+		backend_data.base = (uintptr_t) *phys;
+		backend_data.frames = pages;
+		
+		if (!as_area_create(TASK->as, map_flags, size, virt,
+		    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
+			frame_free_noreserve((uintptr_t) *phys);
+			return ENOMEM;
+		}
+		
+		return EOK;
+	}
+}
+
+NO_TRACE static int dmamem_unmap(uintptr_t virt, size_t size,
+    unsigned int flags)
+{
+	// TODO: implement unlocking & unmap
+	return EOK;
+}
+
+sysarg_t sys_dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
+    unsigned int flags, void *phys_ptr)
+{
+	void *phys;
+	int rc = dmamem_map(virt, size, map_flags, flags, &phys);
+	if (rc != EOK)
+		return rc;
+	
+	rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));
+	if (rc != EOK) {
+		dmamem_unmap(virt, size, flags);
+		return rc;
+	}
+	
+	return EOK;
+}
+
+sysarg_t sys_dmamem_unmap(uintptr_t virt, size_t size, unsigned int flags)
+{
+	return dmamem_unmap(virt, size, flags);
+}
+
 /** @}
  */
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ kernel/generic/src/syscall/syscall.c	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -176,4 +176,6 @@
 	(syshandler_t) sys_device_assign_devno,
 	(syshandler_t) sys_physmem_map,
+	(syshandler_t) sys_dmamem_map,
+	(syshandler_t) sys_dmamem_unmap,
 	(syshandler_t) sys_iospace_enable,
 	(syshandler_t) sys_register_irq,
Index: uspace/lib/c/generic/as.c
===================================================================
--- uspace/lib/c/generic/as.c	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ uspace/lib/c/generic/as.c	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -117,26 +117,15 @@
 /** Find mapping to physical address.
  *
- * @param address Virtual address in question (virtual).
- * @param[out] frame Frame address (physical).
- * @return Error code.
- * @retval EOK No error, @p frame holds the translation.
- * @retval ENOENT Mapping not found.
+ * @param      virt Virtual address to find mapping for.
+ * @param[out] phys Physical adress.
+ *
+ * @return EOK on no error.
+ * @retval ENOENT if no mapping was found.
+ *
  */
-int as_get_physical_mapping(const void *address, uintptr_t *frame)
+int as_get_physical_mapping(const void *virt, uintptr_t *phys)
 {
-	uintptr_t tmp_frame;
-	uintptr_t virt = (uintptr_t) address;
-	
-	int rc = (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING,
-	    (sysarg_t) virt, (sysarg_t) &tmp_frame);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	if (frame != NULL) {
-		*frame = tmp_frame;
-	}
-	
-	return EOK;
+	return (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING, (sysarg_t) virt,
+	    (sysarg_t) phys);
 }
 
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ uspace/lib/c/generic/ddi.c	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -33,4 +33,7 @@
  */
 
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
 #include <sys/types.h>
 #include <abi/ddi/arg.h>
@@ -57,6 +60,6 @@
  * Caller of this function must have the CAP_MEM_MANAGER capability.
  *
- * @param pf    Physical address of the starting frame.
- * @param vp    Virtual address of the starting page.
+ * @param phys  Physical address of the starting frame.
+ * @param virt  Virtual address of the starting page.
  * @param pages Number of pages to map.
  * @param flags Flags for the new address space area.
@@ -69,33 +72,39 @@
  *
  */
-int physmem_map(void *pf, void *vp, size_t pages, unsigned int flags)
+int physmem_map(void *phys, void *virt, size_t pages, unsigned int flags)
 {
-	return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp,
-	    pages, flags);
+	return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) phys,
+	    (sysarg_t) virt, pages, flags);
 }
 
-int dmamem_map(dmamem_t *dmamem, size_t pages, unsigned int map_flags,
-    unsigned int dma_flags)
+int dmamem_map(void *virt, size_t size, unsigned int map_flags,
+    unsigned int flags, void **phys)
 {
-	// FIXME TODO
-	return -1;
+	return (int) __SYSCALL5(SYS_DMAMEM_MAP, (sysarg_t) virt,
+	    (sysarg_t) size, (sysarg_t) map_flags, (sysarg_t) flags,
+	    (sysarg_t) phys);
 }
 
-int dmamem_unmap(dmamem_t *dmamem)
+int dmamem_map_anonymous(size_t size, unsigned int map_flags,
+    unsigned int flags, void **phys, void **virt)
 {
-	// FIXME TODO
-	return -1;
+	*virt = as_get_mappable_page(size);
+	if (*virt == NULL)
+		return ENOMEM;
+	
+	return dmamem_map(*virt, size, map_flags,
+	    flags | DMAMEM_FLAGS_ANONYMOUS, phys);
 }
 
-int dmamem_lock(void *virt, void **phys, size_t pages)
+int dmamem_unmap(void *virt, size_t size, unsigned int flags)
 {
-	// FIXME TODO
-	return -1;
+	return __SYSCALL3(SYS_DMAMEM_UNMAP, (sysarg_t) virt, (sysarg_t) size,
+	    (sysarg_t) flags);
 }
 
-int dmamem_unlock(void *virt, size_t pages)
+int dmamem_unmap_anonymous(void *virt)
 {
-	// FIXME TODO
-	return -1;
+	return __SYSCALL3(SYS_DMAMEM_UNMAP, (sysarg_t) virt, 0,
+	    DMAMEM_FLAGS_ANONYMOUS);
 }
 
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ uspace/lib/c/include/ddi.h	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -40,26 +40,17 @@
 #include <task.h>
 
-typedef struct {
-	/** Physical memory */
-	void *phys;
-	
-	/** Virtual memory */
-	void *virt;
-	
-	/** Size in pages */
-	size_t size;
-	
-	/** Mapping flags */
-	unsigned int flags;
-} dmamem_t;
+extern int device_assign_devno(void);
 
-extern int device_assign_devno(void);
 extern int physmem_map(void *, void *, size_t, unsigned int);
-extern int dmamem_map(dmamem_t *, size_t, unsigned int, unsigned int);
-extern int dmamem_unmap(dmamem_t *);
-extern int dmamem_lock(void *, void **, size_t);
-extern int dmamem_unlock(void *, size_t);
+
+extern int dmamem_map(void *, size_t, unsigned int, unsigned int, void **);
+extern int dmamem_map_anonymous(size_t, unsigned int, unsigned int, void **,
+    void **);
+extern int dmamem_unmap(void *, size_t, unsigned int);
+extern int dmamem_unmap_anonymous(void *);
+
 extern int iospace_enable(task_id_t, void *, unsigned long);
 extern int pio_enable(void *, size_t, void **);
+
 extern int register_irq(int, int, int, irq_code_t *);
 extern int unregister_irq(int, int);
Index: uspace/lib/nic/include/nic.h
===================================================================
--- uspace/lib/nic/include/nic.h	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ uspace/lib/nic/include/nic.h	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -275,6 +275,6 @@
 
 /* Packet DMA lock */
-extern void *nic_dma_lock_packet(packet_t *);
-extern int nic_dma_unlock_packet(packet_t *);
+extern int nic_dma_lock_packet(packet_t *, size_t, void **);
+extern int nic_dma_unlock_packet(packet_t *, size_t);
 
 #endif // __NIC_H__
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision e2718e1b78508a9325b6029d6febbdd49eb373cb)
+++ uspace/lib/nic/src/nic_driver.c	(revision c6ae4c22299e63b14110ce5d5b471aa67f9861c9)
@@ -46,5 +46,5 @@
 #include <ipc/irc.h>
 #include <sysinfo.h>
-
+#include <as.h>
 #include <devman.h>
 #include <ddf/interrupt.h>
@@ -1334,12 +1334,7 @@
  * @return physical address of packet
  */
-void *nic_dma_lock_packet(packet_t *packet)
-{
-	void *phys_addr;
-	int rc = dmamem_lock(packet, &phys_addr, 1);
-	if (rc != EOK)
-		return NULL;
-	
-	return phys_addr;
+int nic_dma_lock_packet(packet_t *packet, size_t size, void **phys)
+{
+	return dmamem_map(packet, SIZE2PAGES(size), 0, 0, phys);
 }
 
@@ -1348,7 +1343,7 @@
  * @param packet
  */
-int nic_dma_unlock_packet(packet_t *packet)
-{
-	return dmamem_unlock(packet, 1);
+int nic_dma_unlock_packet(packet_t *packet, size_t size)
+{
+	return dmamem_unmap(packet, size, 0);
 }
 
