Index: kernel/arch/abs32le/src/ddi/ddi.c
===================================================================
--- kernel/arch/abs32le/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/abs32le/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -46,4 +46,12 @@
 }
 
+/** Disable I/O space range for task.
+ *
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
 /** @}
  */
Index: kernel/arch/amd64/src/ddi/ddi.c
===================================================================
--- kernel/arch/amd64/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/amd64/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -51,8 +51,8 @@
  *
  * @param task   Task.
- * @param ioaddr Startign I/O space address.
+ * @param ioaddr Starting I/O space address.
  * @param size   Size of the enabled I/O range.
  *
- * @return 0 on success or an error code from errno.h.
+ * @return EOK on success or an error code from errno.h.
  *
  */
@@ -106,4 +106,40 @@
 	task->arch.iomapver++;
 	
+	return EOK;
+}
+
+/** Disable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task   Task.
+ * @param ioaddr Starting I/O space address.
+ * @param size   Size of the enabled I/O range.
+ *
+ * @return EOK on success or an error code from errno.h.
+ *
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	size_t elements = ioaddr + size;
+	if (elements > IO_PORTS)
+		return ENOENT;
+	
+	if (ioaddr >= task->arch.iomap.elements)
+		return EINVAL;	
+
+	if (task->arch.iomap.elements < elements)
+		size -= elements - task->arch.iomap.elements;
+
+	/*
+	 * Disable the range.
+	 */
+	bitmap_set_range(&task->arch.iomap, (size_t) ioaddr, size);
+	
+	/*
+	 * Increment I/O Permission bitmap generation counter.
+	 */
+	task->arch.iomapver++;
+	
 	return 0;
 }
Index: kernel/arch/arm32/src/ddi/ddi.c
===================================================================
--- kernel/arch/arm32/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/arm32/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -53,4 +53,19 @@
 }
 
+/** Disable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task Task.
+ * @param ioaddr Startign I/O space address.
+ * @param size Size of the disabled I/O range.
+ *
+ * @return 0 on success or an error code from errno.h.
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
 /** @}
  */
Index: kernel/arch/ia32/src/ddi/ddi.c
===================================================================
--- kernel/arch/ia32/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/ia32/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -51,5 +51,5 @@
  *
  * @param task   Task.
- * @param ioaddr Startign I/O space address.
+ * @param ioaddr Starting I/O space address.
  * @param size   Size of the enabled I/O range.
  *
@@ -109,4 +109,41 @@
 }
 
+/** Disable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task   Task.
+ * @param ioaddr Starting I/O space address.
+ * @param size   Size of the enabled I/O range.
+ *
+ * @return EOK on success or an error code from errno.h.
+ *
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	size_t elements = ioaddr + size;
+	if (elements > IO_PORTS)
+		return ENOENT;
+	
+	if (ioaddr >= task->arch.iomap.elements)
+		return EINVAL;	
+
+	if (task->arch.iomap.elements < elements)
+		size -= elements - task->arch.iomap.elements;
+
+	/*
+	 * Disable the range.
+	 */
+	bitmap_set_range(&task->arch.iomap, (size_t) ioaddr, size);
+	
+	/*
+	 * Increment I/O Permission bitmap generation counter.
+	 */
+	task->arch.iomapver++;
+	
+	return 0;
+}
+
+
 /** Install I/O Permission bitmap.
  *
Index: kernel/arch/ia64/src/ddi/ddi.c
===================================================================
--- kernel/arch/ia64/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/ia64/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -47,9 +47,9 @@
  * Interrupts are disabled and task is locked.
  *
- * @param task		Task.
- * @param ioaddr	Starting I/O space address.
- * @param size		Size of the enabled I/O range.
+ * @param task	 Task.
+ * @param ioaddr Starting I/O space address.
+ * @param size	 Size of the enabled I/O range.
  *
- * @return 0 on success or an error code from errno.h.
+ * @return EOK on success or an error code from errno.h.
  */
 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
@@ -72,5 +72,27 @@
 	bitmap_set_range(task->arch.iomap, iopage, size / 4);
 	
-	return 0;
+	return EOK;
+}
+
+/** Disable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task	 Task.
+ * @param ioaddr Starting I/O space address.
+ * @param size	 Size of the disabled I/O range.
+ *
+ * @return EOK on success or an error code from errno.h.
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	if (!task->arch.iomap)
+		return EINVAL;
+
+	uintptr_t iopage = ioaddr / PORTS_PER_PAGE;
+	size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE);
+	bitmap_clear_range(task->arch.iomap, iopage, size / 4);
+	
+	return EOK;
 }
 
Index: kernel/arch/mips32/src/ddi/ddi.c
===================================================================
--- kernel/arch/mips32/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/mips32/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -44,7 +44,7 @@
  * Interrupts are disabled and task is locked.
  *
- * @param task Task.
- * @param ioaddr Startign I/O space address.
- * @param size Size of the enabled I/O range.
+ * @param task   Task.
+ * @param ioaddr Startinig I/O space address.
+ * @param size   Size of the enabled I/O range.
  *
  * @return 0 on success or an error code from errno.h.
@@ -55,4 +55,19 @@
 }
 
+/** Disable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task   Task.
+ * @param ioaddr Starting I/O space address.
+ * @param size   Size of the disabled I/O range.
+ *
+ * @return 0 on success or an error code from errno.h.
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
 /** @}
  */
Index: kernel/arch/ppc32/src/ddi/ddi.c
===================================================================
--- kernel/arch/ppc32/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/ppc32/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -41,7 +41,7 @@
  * Interrupts are disabled and task is locked.
  *
- * @param task Task.
- * @param ioaddr Startign I/O space address.
- * @param size Size of the enabled I/O range.
+ * @param task   Task.
+ * @param ioaddr Starting I/O space address.
+ * @param size   Size of the enabled I/O range.
  *
  * @return 0 on success or an error code from errno.h.
@@ -53,4 +53,20 @@
 }
 
+/** Disable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task   Task.
+ * @param ioaddr Starting I/O space address.
+ * @param size   Size of the disabled I/O range.
+ *
+ * @return 0 on success or an error code from errno.h.
+ *
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
 /** @}
  */
Index: kernel/arch/sparc32/src/ddi/ddi.c
===================================================================
--- kernel/arch/sparc32/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/sparc32/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -46,4 +46,12 @@
 }
 
+/** Disable I/O space range for task.
+ *
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
 /** @}
  */
Index: kernel/arch/sparc64/src/ddi/ddi.c
===================================================================
--- kernel/arch/sparc64/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/arch/sparc64/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -41,9 +41,9 @@
  * Interrupts are disabled and task is locked.
  *
- * @param task Task.
+ * @param task   Task.
  * @param ioaddr Starting I/O space address.
- * @param size Size of the enabled I/O range.
+ * @param size   Size of the enabled I/O range.
  *
- * @return 0 on success or an error code from errno.h.
+ * @return EOK on success or an error code from errno.h.
  */
 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
@@ -52,4 +52,19 @@
 }
 
+/** Disable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task   Task.
+ * @param ioaddr Starting I/O space address.
+ * @param size   Size of the disabled I/O range.
+ *
+ * @return EOK on success or an error code from errno.h.
+ */
+int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
 /** @}
  */
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/generic/include/ddi/ddi.h	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -70,4 +70,5 @@
  */
 extern int ddi_iospace_enable_arch(task_t *, uintptr_t, size_t);
+extern int ddi_iospace_disable_arch(task_t *, uintptr_t, size_t);
 
 #endif
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ kernel/generic/src/ddi/ddi.c	(revision 8cd680c007c2a69075a82a05402c553e68bbac00)
@@ -211,6 +211,7 @@
 NO_TRACE static int physmem_unmap(uintptr_t virt)
 {
-	// TODO: implement unmap
-	return EOK;
+	ASSERT(TASK);
+
+	return as_area_destroy(TASK->as, virt);
 }
 
@@ -255,7 +256,7 @@
 /** Enable range of I/O space for task.
  *
- * @param id Task ID of the destination task.
+ * @param id     Task ID of the destination task.
  * @param ioaddr Starting I/O address.
- * @param size Size of the enabled I/O space..
+ * @param size   Size of the enabled I/O space.
  *
  * @return 0 on success, EPERM if the caller lacks capabilities to use this
@@ -290,4 +291,45 @@
 	int rc = ddi_iospace_enable_arch(task, ioaddr, size);
 	irq_spinlock_unlock(&task->lock, true);
+
+	return rc;
+}
+
+/** Disable range of I/O space for task.
+ *
+ * @param id     Task ID of the destination task.
+ * @param ioaddr Starting I/O address.
+ * @param size   Size of the enabled I/O space.
+ *
+ * @return 0 on success, EPERM if the caller lacks capabilities to use this
+ *           syscall, ENOENT if there is no task matching the specified ID.
+ *
+ */
+NO_TRACE static int iospace_disable(task_id_t id, uintptr_t ioaddr, size_t size)
+{
+	/*
+	 * Make sure the caller is authorised to make this syscall.
+	 */
+	cap_t caps = cap_get(TASK);
+	if (!(caps & CAP_IO_MANAGER))
+		return EPERM;
+	
+	irq_spinlock_lock(&tasks_lock, true);
+	
+	task_t *task = task_find_by_id(id);
+	
+	if ((!task) || (!container_check(CONTAINER, task->container))) {
+		/*
+		 * There is no task with the specified ID
+		 * or the task belongs to a different security
+		 * context.
+		 */
+		irq_spinlock_unlock(&tasks_lock, true);
+		return ENOENT;
+	}
+	
+	/* Lock the task and release the lock protecting tasks_btree. */
+	irq_spinlock_exchange(&tasks_lock, &task->lock);
+	int rc = ddi_iospace_disable_arch(task, ioaddr, size);
+	irq_spinlock_unlock(&task->lock, true);
 	
 	return rc;
@@ -314,6 +356,11 @@
 sysarg_t sys_iospace_disable(ddi_ioarg_t *uspace_io_arg)
 {
-	// TODO: implement
-	return ENOTSUP;
+	ddi_ioarg_t arg;
+	int rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
+	if (rc != 0)
+		return (sysarg_t) rc;
+
+	return (sysarg_t) iospace_disable((task_id_t) arg.task_id,
+	    (uintptr_t) arg.ioaddr, (size_t) arg.size);
 }
 
