Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision e190e640f73b310ae15f7fcc3a75485568c08978)
+++ kernel/generic/src/ddi/ddi.c	(revision 21365c0a5b774932892b0dcddd2cd5917d6abd67)
@@ -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);
 }
 
