Index: uspace/lib/usb/Makefile
===================================================================
--- uspace/lib/usb/Makefile	(revision c431a8313bb73785a3e293be871874d3a226fb09)
+++ uspace/lib/usb/Makefile	(revision c2020f7fee59f8604b9f025a9e1210aaa80b1529)
@@ -47,5 +47,6 @@
 	src/usb.c \
 	src/usbdrvreq.c \
-	src/usbdrv.c
+	src/usbdrv.c \
+	src/usbmem.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/usb/include/usb/usbmem.h
===================================================================
--- uspace/lib/usb/include/usb/usbmem.h	(revision c431a8313bb73785a3e293be871874d3a226fb09)
+++ uspace/lib/usb/include/usb/usbmem.h	(revision c2020f7fee59f8604b9f025a9e1210aaa80b1529)
@@ -58,5 +58,8 @@
 #include <sys/types.h>
 
-extern void * mman_malloc(size_t size);
+extern void * mman_malloc(
+		size_t size,
+		size_t alignment,
+		unsigned long max_physical_address);
 
 extern void * mman_getVA(void * addr);
Index: uspace/lib/usb/src/usbmem.c
===================================================================
--- uspace/lib/usb/src/usbmem.c	(revision c431a8313bb73785a3e293be871874d3a226fb09)
+++ uspace/lib/usb/src/usbmem.c	(revision c2020f7fee59f8604b9f025a9e1210aaa80b1529)
@@ -33,15 +33,24 @@
  */
 
-#include "usb/usbmem.h"
 #include <adt/hash_table.h>
 #include <adt/list.h>
+#include <as.h>
+#include <errno.h>
+#include <malloc.h>
+
+#include "usb/usbmem.h"
 
 #define ADDR_BUCKETS 1537
 
-hash_table_t * pa2fa_table = NULL;
-hash_table_t * fa2pa_table = NULL;
-
+//address translation tables
+static hash_table_t * pa2va_table = NULL;
+static hash_table_t * va2pa_table = NULL;
+
+/**
+ * address translation hashtable item
+ */
 typedef struct{
-	long addr;
+	unsigned long addr;
+	unsigned long translation;
 	link_t link;
 
@@ -62,4 +71,7 @@
 static void addr_remove_callback(link_t *item)
 {
+	//delete item
+	addr_node_t *addr_node = hash_table_get_instance(item, addr_node_t, link);
+	free(addr_node);
 }
 
@@ -71,39 +83,115 @@
 };
 
-
-//
-
-
-void * mman_malloc(size_t size){
+/**
+ * create node for address translation hashtable
+ * @param addr
+ * @param translation
+ * @return
+ */
+static addr_node_t * create_addr_node(void * addr, void * translation){
+	addr_node_t * node = (addr_node_t*)malloc(sizeof(addr_node_t));
+	node->addr = (unsigned long)addr;
+	node->translation = (unsigned long)translation;
+	return node;
+}
+
+/**
+ * allocate size on heap and register it`s pa<->va translation
+ *
+ * If physical address + size is 2GB or higher, nothing is allocated and NULL
+ * is returned.
+ * @param size
+ * @param alignment
+ * @return
+ */
+void * mman_malloc(
+	size_t size,
+	size_t alignment,
+	unsigned long max_physical_address)
+{
+	if (size == 0)
+		return NULL;
+	if (alignment == 0)
+		return NULL;
 	//check if tables were initialized
-	if(!pa2fa_table){
-		pa2fa_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
-		fa2pa_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
-		hash_table_create(pa2fa_table, ADDR_BUCKETS, 1,
+	if(!pa2va_table){
+		pa2va_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
+		va2pa_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
+		hash_table_create(pa2va_table, ADDR_BUCKETS, 1,
 		    &addr_devices_ops);
-		hash_table_create(fa2pa_table, ADDR_BUCKETS, 1,
+		hash_table_create(va2pa_table, ADDR_BUCKETS, 1,
 		    &addr_devices_ops);
 	}
 	//allocate
-
+	void * vaddr = memalign(alignment, size);
+	
 	//get translation
-
+	void * paddr = NULL;
+	int opResult = as_get_physical_mapping(vaddr,(uintptr_t*)&paddr);
+	if(opResult != EOK){
+		//something went wrong
+		free(vaddr);
+		return NULL;
+	}
+	if((unsigned long)paddr + size > max_physical_address){
+		//unusable address for usb
+		free(vaddr);
+		return NULL;
+	}
 	//store translation
-
-
-	return NULL;
-
-}
-
+	addr_node_t * pa2vaNode = create_addr_node(paddr,vaddr);
+	addr_node_t * va2paNode = create_addr_node(vaddr,paddr);
+
+	unsigned long keypaddr = (unsigned long)paddr;
+	unsigned long keyvaddr = (unsigned long)vaddr;
+	hash_table_insert(pa2va_table, (&keypaddr), &pa2vaNode->link);
+	hash_table_insert(va2pa_table, (&keyvaddr), &va2paNode->link);
+	//return
+	return vaddr;
+
+}
+
+/**
+ * get virtual address from physical
+ * @param addr
+ * @return translated virtual address or null
+ */
 void * mman_getVA(void * addr){
-	return NULL;
-}
-
+	unsigned long keypaddr = (unsigned long)addr;
+	link_t * link = hash_table_find(pa2va_table, &keypaddr);
+	if(!link) return NULL;
+	addr_node_t * node = hash_table_get_instance(link, addr_node_t, link);
+	return (void*)node->translation;
+}
+
+/**
+ * get physical address from virtual
+ * @param addr
+ * @return physical address or null
+ */
 void * mman_getPA(void * addr){
-	return NULL;
-}
-
-void mman_free(void * addr){
-	
+	unsigned long keyvaddr = (unsigned long)addr;
+	link_t * link = hash_table_find(va2pa_table, &keyvaddr);
+	if(!link) return NULL;
+	addr_node_t * node = hash_table_get_instance(link, addr_node_t, link);
+	return (void*)node->translation;
+}
+
+/**
+ * free the address and deregister it from pa<->va translation
+ * @param vaddr if NULL, nothing happens
+ */
+void mman_free(void * vaddr){
+	if(!vaddr)
+		return;
+	//get paddress
+	void * paddr = mman_getPA(vaddr);
+	unsigned long keypaddr = (unsigned long)paddr;
+	unsigned long keyvaddr = (unsigned long)vaddr;
+	//remove mapping
+	hash_table_remove(pa2va_table,&keypaddr, 1);
+	hash_table_remove(va2pa_table,&keyvaddr, 1);
+	//free address
+	free(vaddr);
 }
 
