Index: uspace/lib/libc/generic/devmap.c
===================================================================
--- uspace/lib/libc/generic/devmap.c	(revision 0da4e41be5a0b7a29e97e1f87816593416d3db04)
+++ uspace/lib/libc/generic/devmap.c	(revision 4491338ddbe464a577387f85db0bc04a0e10dad3)
@@ -35,4 +35,6 @@
 #include <async.h>
 #include <errno.h>
+#include <malloc.h>
+#include <bool.h>
 
 static int devmap_phone_driver = -1;
@@ -105,6 +107,5 @@
 	aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
 	
-	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
-	
+	ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
@@ -126,9 +127,10 @@
 /** Register new device.
  *
- * @param name   Device name.
- * @param handle Output: Handle to the created instance of device.
+ * @param namespace Namespace name.
+ * @param fqdn      Fully qualified device name.
+ * @param handle    Output: Handle to the created instance of device.
  *
  */
-int devmap_device_register(const char *name, dev_handle_t *handle)
+int devmap_device_register(const char *fqdn, dev_handle_t *handle)
 {
 	int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
@@ -143,6 +145,5 @@
 	    &answer);
 	
-	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
-	
+	ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
@@ -167,5 +168,5 @@
 }
 
-int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
+int devmap_device_get_handle(const char *fqdn, dev_handle_t *handle, unsigned int flags)
 {
 	int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
@@ -180,6 +181,5 @@
 	    &answer);
 	
-	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
-	
+	ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
@@ -202,4 +202,55 @@
 	
 	return retval;
+}
+
+int devmap_namespace_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
+	
+	if (phone < 0)
+		return phone;
+	
+	async_serialize_start();
+	
+	ipc_call_t answer;
+	aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
+	    &answer);
+	
+	ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
+		async_serialize_end();
+		return retval;
+	}
+	
+	async_wait_for(req, &retval);
+	
+	async_serialize_end();
+	
+	if (retval != EOK) {
+		if (handle != NULL)
+			*handle = (dev_handle_t) -1;
+		return retval;
+	}
+	
+	if (handle != NULL)
+		*handle = (dev_handle_t) IPC_GET_ARG1(answer);
+	
+	return retval;
+}
+
+devmap_handle_type_t devmap_handle_probe(dev_handle_t handle)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return phone;
+	
+	ipcarg_t type;
+	int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type);
+	if (retval != EOK)
+		return DEV_HANDLE_NONE;
+	
+	return (devmap_handle_type_t) type;
 }
 
@@ -227,5 +278,5 @@
 	
 	ipcarg_t null_id;
-	int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
+	int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id);
 	if (retval != EOK)
 		return -1;
@@ -241,16 +292,11 @@
 		return;
 	
-	async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
-}
-
-ipcarg_t devmap_device_get_count(void)
-{
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return 0;
-	
+	async_req_1_0(phone, DEVMAP_NULL_DESTROY, (ipcarg_t) null_id);
+}
+
+static size_t devmap_count_namespaces_internal(int phone)
+{
 	ipcarg_t count;
-	int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
+	int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count);
 	if (retval != EOK)
 		return 0;
@@ -259,31 +305,135 @@
 }
 
-ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
-{
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return 0;
-	
-	async_serialize_start();
-	
-	ipc_call_t answer;
-	aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
-	
-	ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t));
-	
-	if (retval != EOK) {
-		async_wait_for(req, NULL);
-		async_serialize_end();
-		return 0;
-	}
-	
-	async_wait_for(req, &retval);
-	
-	async_serialize_end();
-	
+static size_t devmap_count_devices_internal(int phone, dev_handle_t ns_handle)
+{
+	ipcarg_t count;
+	int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count);
 	if (retval != EOK)
 		return 0;
 	
-	return IPC_GET_ARG1(answer);
-}
+	return count;
+}
+
+size_t devmap_count_namespaces(void)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return 0;
+	
+	return devmap_count_namespaces_internal(phone);
+}
+
+size_t devmap_count_devices(dev_handle_t ns_handle)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return 0;
+	
+	return devmap_count_devices_internal(phone, ns_handle);
+}
+
+size_t devmap_get_namespaces(dev_desc_t **data)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return 0;
+	
+	/* Loop until namespaces read succesful */
+	while (true) {
+		size_t count = devmap_count_namespaces_internal(phone);
+		if (count == 0)
+			return 0;
+		
+		dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
+		if (devs == NULL)
+			return 0;
+		
+		async_serialize_start();
+		
+		ipc_call_t answer;
+		aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer);
+		
+		int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
+		if (rc == EOVERFLOW) {
+			/*
+			 * Number of namespaces has changed since
+			 * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT
+			 */
+			async_serialize_end();
+			free(devs);
+			continue;
+		}
+		
+		if (rc != EOK) {
+			async_wait_for(req, NULL);
+			async_serialize_end();
+			free(devs);
+			return 0;
+		}
+		
+		ipcarg_t retval;
+		async_wait_for(req, &retval);
+		async_serialize_end();
+		
+		if (retval != EOK)
+			return 0;
+		
+		*data = devs;
+		return count;
+	}
+}
+
+size_t devmap_get_devices(dev_handle_t ns_handle, dev_desc_t **data)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return 0;
+	
+	/* Loop until namespaces read succesful */
+	while (true) {
+		size_t count = devmap_count_devices_internal(phone, ns_handle);
+		if (count == 0)
+			return 0;
+		
+		dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
+		if (devs == NULL)
+			return 0;
+		
+		async_serialize_start();
+		
+		ipc_call_t answer;
+		aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer);
+		
+		int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
+		if (rc == EOVERFLOW) {
+			/*
+			 * Number of devices has changed since
+			 * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT
+			 */
+			async_serialize_end();
+			free(devs);
+			continue;
+		}
+		
+		if (rc != EOK) {
+			async_wait_for(req, NULL);
+			async_serialize_end();
+			free(devs);
+			return 0;
+		}
+		
+		ipcarg_t retval;
+		async_wait_for(req, &retval);
+		async_serialize_end();
+		
+		if (retval != EOK)
+			return 0;
+		
+		*data = devs;
+		return count;
+	}
+}
