Index: arch/amd64/include/pm.h
===================================================================
--- arch/amd64/include/pm.h	(revision 9fa16b204b1d07e1406cbdc9803f00547dcadfa8)
+++ arch/amd64/include/pm.h	(revision 73e9b49f68fcee880d656c3073aeba64b022fbfc)
@@ -69,4 +69,6 @@
 #define TSS_BASIC_SIZE	104
 #define TSS_IOMAP_SIZE	(16*1024+1)	/* 16K for bitmap + 1 terminating byte for convenience */
+
+#define IO_PORTS	(64*1024)
 
 #ifndef __ASM__
Index: arch/amd64/src/ddi/ddi.c
===================================================================
--- arch/amd64/src/ddi/ddi.c	(revision 9fa16b204b1d07e1406cbdc9803f00547dcadfa8)
+++ arch/amd64/src/ddi/ddi.c	(revision 73e9b49f68fcee880d656c3073aeba64b022fbfc)
@@ -31,4 +31,8 @@
 #include <arch/types.h>
 #include <typedefs.h>
+#include <adt/bitmap.h>
+#include <mm/slab.h>
+#include <arch/pm.h>
+#include <errno.h>
 
 /** Enable I/O space range for task.
@@ -44,4 +48,45 @@
 int ddi_enable_iospace_arch(task_t *task, __address ioaddr, size_t size)
 {
+	count_t bits;
+
+	bits = ioaddr + size;
+	if (bits > IO_PORTS)
+		return ENOENT;
+
+	if (task->arch.iomap.bits < bits) {
+		bitmap_t oldiomap;
+		__u8 *newmap;
+	
+		/*
+		 * The I/O permission bitmap is too small and needs to be grown.
+		 */
+		
+		newmap = (__u8 *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
+		if (!newmap)
+			return ENOMEM;
+		
+		bitmap_initialize(&oldiomap, task->arch.iomap.map, task->arch.iomap.bits);
+		bitmap_initialize(&task->arch.iomap, newmap, bits);
+
+		/*
+		 * Mark the new range inaccessible.
+		 */
+		bitmap_set_range(&task->arch.iomap, oldiomap.bits, bits - oldiomap.bits);
+
+		/*
+		 * In case there really existed smaller iomap,
+		 * copy its contents and deallocate it.
+		 */		
+		if (oldiomap.bits) {
+			bitmap_copy(&task->arch.iomap, &oldiomap, task->arch.iomap.bits);
+			free(oldiomap.map);
+		}
+	}
+
+	/*
+	 * Enable the range and we are done.
+	 */
+	bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
+
 	return 0;
 }
Index: arch/ia32/include/pm.h
===================================================================
--- arch/ia32/include/pm.h	(revision 9fa16b204b1d07e1406cbdc9803f00547dcadfa8)
+++ arch/ia32/include/pm.h	(revision 73e9b49f68fcee880d656c3073aeba64b022fbfc)
@@ -58,4 +58,6 @@
 #define TSS_BASIC_SIZE	104
 #define TSS_IOMAP_SIZE	(16*1024+1)	/* 16K for bitmap + 1 terminating byte for convenience */
+
+#define IO_PORTS	(64*1024)
 
 #ifndef __ASM__
Index: arch/ia32/src/ddi/ddi.c
===================================================================
--- arch/ia32/src/ddi/ddi.c	(revision 9fa16b204b1d07e1406cbdc9803f00547dcadfa8)
+++ arch/ia32/src/ddi/ddi.c	(revision 73e9b49f68fcee880d656c3073aeba64b022fbfc)
@@ -31,4 +31,8 @@
 #include <arch/types.h>
 #include <typedefs.h>
+#include <adt/bitmap.h>
+#include <mm/slab.h>
+#include <arch/pm.h>
+#include <errno.h>
 
 /** Enable I/O space range for task.
@@ -44,4 +48,45 @@
 int ddi_enable_iospace_arch(task_t *task, __address ioaddr, size_t size)
 {
+	count_t bits;
+
+	bits = ioaddr + size;
+	if (bits > IO_PORTS)
+		return ENOENT;
+
+	if (task->arch.iomap.bits < bits) {
+		bitmap_t oldiomap;
+		__u8 *newmap;
+	
+		/*
+		 * The I/O permission bitmap is too small and needs to be grown.
+		 */
+		
+		newmap = (__u8 *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
+		if (!newmap)
+			return ENOMEM;
+		
+		bitmap_initialize(&oldiomap, task->arch.iomap.map, task->arch.iomap.bits);
+		bitmap_initialize(&task->arch.iomap, newmap, bits);
+
+		/*
+		 * Mark the new range inaccessible.
+		 */
+		bitmap_set_range(&task->arch.iomap, oldiomap.bits, bits - oldiomap.bits);
+
+		/*
+		 * In case there really existed smaller iomap,
+		 * copy its contents and deallocate it.
+		 */		
+		if (oldiomap.bits) {
+			bitmap_copy(&task->arch.iomap, &oldiomap, task->arch.iomap.bits);
+			free(oldiomap.map);
+		}
+	}
+
+	/*
+	 * Enable the range and we are done.
+	 */
+	bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
+
 	return 0;
 }
