Index: kernel/generic/src/cap/cap.c
===================================================================
--- kernel/generic/src/cap/cap.c	(revision 48bcf4941bbfdcd0432cdae89d208c3fd44aecf5)
+++ kernel/generic/src/cap/cap.c	(revision 68f46712429fd2645b41fba94e5e2913e9ec3be0)
@@ -33,4 +33,43 @@
  */
 
+/*
+ * HelenOS capabilities are task-local names for references to kernel objects.
+ * Kernel objects are reference-counted wrappers for a select group of objects
+ * allocated in and by the kernel that can be made accessible to userspace in a
+ * controlled way via integer handles.
+ *
+ * A kernel object (kobject_t) encapsulates one of the following raw objects:
+ *
+ * - IPC phone
+ * - IRQ object
+ *
+ * A capability (cap_t) is either free, allocated or published. Free
+ * capabilities can be allocated, which reserves the capability handle in the
+ * task-local capability space. Allocated capabilities can be published, which
+ * associates them with an existing kernel object. Userspace can only access
+ * published capabilities.
+ *
+ * A published capability may get unpublished, which disassociates it from the
+ * underlying kernel object and puts it back into the allocated state. An
+ * allocated capability can be freed to become available for future use.
+ *
+ * There is a 1:1 correspondence between a kernel object (kobject_t) and the
+ * actual raw object it encapsulates. A kernel object (kobject_t) may have
+ * multiple references, either implicit from one or more capabilities (cap_t),
+ * even from capabilities in different tasks, or explicit as a result of
+ * creating a new reference from a capability handle using kobject_get(), or
+ * creating a new reference from an already existing reference by
+ * kobject_add_ref() or as a result of unpublishing a capability and
+ * disassociating it from its kobject_t using cap_unpublish().
+ *
+ * As kernel objects are reference-counted, they get automatically destroyed
+ * when their last reference is dropped in kobject_put(). The idea is that
+ * whenever a kernel object is inserted into some sort of a container (e.g. a
+ * list or hash table), its reference count should be incremented via
+ * kobject_get() or kobject_add_ref(). When the kernel object is removed from
+ * the container, the reference count should go down via a call to
+ * kobject_put().
+ */
+
 #include <cap/cap.h>
 #include <proc/task.h>
@@ -42,4 +81,9 @@
 static kobject_t *cap_unpublish_locked(task_t *, cap_handle_t, kobject_type_t);
 
+/** Initialize capability and associate it with its handle
+ *
+ * @param cap     Address of the capability.
+ * @param handle  Capability handle.
+ */
 void cap_initialize(cap_t *cap, cap_handle_t handle)
 {
@@ -49,4 +93,8 @@
 }
 
+/** Allocate the capability info structure
+ *
+ * @param task  Task for which to allocate the info structure.
+ */
 void caps_task_alloc(task_t *task)
 {
@@ -55,4 +103,8 @@
 }
 
+/** Initialize the capability info structure
+ *
+ * @param task  Task for which to initialize the info structure.
+ */
 void caps_task_init(task_t *task)
 {
@@ -66,4 +118,8 @@
 }
 
+/** Deallocate the capability info structure
+ *
+ * @param task  Task from which to deallocate the info structure.
+ */
 void caps_task_free(task_t *task)
 {
@@ -72,4 +128,15 @@
 }
 
+/** Invoke callback function on task's capabilites of given type
+ *
+ * @param task  Task where the invocation should take place.
+ * @param type  Kernel object type of the task's capabilities that will be
+ *              subject to the callback invocation.
+ * @param cb    Callback function.
+ * @param arg   Argument for the callback function.
+ *
+ * @return True if the callback was called on all matching capabilities.
+ * @return False if the callback was applied only partially.
+ */
 bool caps_apply_to_kobject_type(task_t *task, kobject_type_t type,
     bool (*cb)(cap_t *, void *), void *arg)
@@ -89,4 +156,13 @@
 }
 
+/** Get capability using capability handle
+ *
+ * @param task    Task whose capability to get.
+ * @param handle  Capability handle of the desired capability.
+ * @param state   State in which the capability must be.
+ *
+ * @return Address of the desired capability if it exists and its state matches.
+ * @return NULL if no such capability exists or it's in a different state.
+ */
 static cap_t *cap_get(task_t *task, cap_handle_t handle, cap_state_t state)
 {
@@ -100,4 +176,11 @@
 }
 
+/** Allocate new capability
+ *
+ * @param task  Task for which to allocate the new capability.
+ *
+ * @return New capability handle on success.
+ * @return Negative error code in case of error.
+ */
 cap_handle_t cap_alloc(task_t *task)
 {
@@ -125,4 +208,14 @@
 }
 
+/** Publish allocated capability
+ *
+ * The kernel object is moved into the capability. In other words, its reference
+ * is handed over to the capability. Once published, userspace can access and
+ * manipulate the capability.
+ *
+ * @param task    Task in which to publish the capability.
+ * @param handle  Capability handle.
+ * @param kobj    Kernel object.
+ */
 void
 cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj)
@@ -156,4 +249,17 @@
 	return kobj;
 }
+
+/** Unpublish published capability
+ *
+ * The kernel object is moved out of the capability. In other words, the
+ * capability's reference to the objects is handed over to the kernel object
+ * pointer returned by this function. Once unpublished, the capability does not
+ * refer to any kernel object anymore.
+ *
+ * @param task    Task in which to unpublish the capability.
+ * @param handle  Capability handle.
+ * @param type    Kernel object type of the object associated with the
+ *                capability.
+ */
 kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type)
 {
@@ -166,4 +272,9 @@
 }
 
+/** Free allocated capability
+ *
+ * @param task    Task in which to free the capability.
+ * @param handle  Capability handle.
+ */
 void cap_free(task_t *task, cap_handle_t handle)
 {
@@ -177,4 +288,11 @@
 }
 
+/** Initialize kernel object
+ *
+ * @param kobj  Kernel object to initialize.
+ * @param type  Type of the kernel object.
+ * @param raw   Raw pointer to the encapsulated object.
+ * @param ops   Pointer to kernel object operations for the respective type.
+ */
 void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw,
     kobject_ops_t *ops)
@@ -186,4 +304,14 @@
 }
 
+/** Get new reference to kernel object from capability
+ *
+ * @param task    Task from which to get the reference.
+ * @param handle  Capability handle.
+ * @param type    Kernel object type of the object associated with the
+ *                capability referenced by handle.
+ *
+ * @return Kernel object with incremented reference count on success.
+ * @return NULL if there is no matching capability or kernel object.
+ */
 kobject_t *
 kobject_get(struct task *task, cap_handle_t handle, kobject_type_t type)
@@ -204,4 +332,20 @@
 }
 
+/** Record new reference
+ *
+ * @param kobj  Kernel object from which the new reference is created.
+ */
+void kobject_add_ref(kobject_t *kobj)
+{
+	atomic_inc(&kobj->refcnt);
+}
+
+/** Drop reference to kernel object
+ *
+ * The encapsulated object and the kobject_t wrapper are both destroyed when the
+ * last reference is dropped.
+ *
+ * @param kobj  Kernel object whose reference to drop.
+ */
 void kobject_put(kobject_t *kobj)
 {
