Index: uspace/lib/libc/include/ipc/devman.h
===================================================================
--- uspace/lib/libc/include/ipc/devman.h	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
+++ uspace/lib/libc/include/ipc/devman.h	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup devman
+ * @{
+ */
+ 
+#ifndef LIBC_IPC_DEVMAN_H_
+#define LIBC_IPC_DEVMAN_H_
+
+#include <ipc/ipc.h>
+
+
+typedef enum {
+	DEVMAN_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
+	DEVMAN_ADD_CHILD_DEVICE
+
+} devman_request_t;
+
+
+
+
+
+
+
+
+
+#endif
Index: uspace/lib/libc/include/ipc/services.h
===================================================================
--- uspace/lib/libc/include/ipc/services.h	(revision 85e48a90b6a7be12c7bb85fe91a9d975339d7aac)
+++ uspace/lib/libc/include/ipc/services.h	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -45,4 +45,5 @@
 	SERVICE_VFS,
 	SERVICE_DEVMAP,
+	SERVICE_DEVMAN,
 	SERVICE_FHC,
 	SERVICE_OBIO,
Index: uspace/srv/devman/Makefile
===================================================================
--- uspace/srv/devman/Makefile	(revision 85e48a90b6a7be12c7bb85fe91a9d975339d7aac)
+++ uspace/srv/devman/Makefile	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -34,5 +34,8 @@
 
 SOURCES = \
-	devman.c
+	main.c \
+	devman.c \
+	match.c \
+	util.c
 
 include ../Makefile.common
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 85e48a90b6a7be12c7bb85fe91a9d975339d7aac)
+++ uspace/srv/devman/devman.c	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -27,145 +27,17 @@
  */
 
-/**
- * @defgroup devman Device manager.
- * @brief HelenOS device manager.
+/** @addtogroup devman
  * @{
  */
 
-/** @file
- */
-
-#include <assert.h>
-#include <ipc/services.h>
-#include <ipc/ns.h>
-#include <async.h>
-#include <stdio.h>
 #include <errno.h>
-#include <bool.h>
-#include <fibril_synch.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <ctype.h>
-//#include <ipc/devman.h>
-
-#define NAME          "devman"
-
-#define DRIVER_DEFAULT_STORE  "/srv/drivers"
-#define MATCH_EXT ".ma"
-
-#define MAX_ID_LEN 256
-
-
-struct driver;
-struct match_id;
-struct match_id_list;
-struct node;
-struct dev_tree;
-
-
-typedef struct driver driver_t;
-typedef struct match_id match_id_t;
-typedef struct match_id_list match_id_list_t;
-typedef struct node node_t;
-typedef struct dev_tree dev_tree_t;
-
-
-static driver_t * create_driver();
-static inline void init_driver(driver_t *drv);
-static inline void clean_driver(driver_t *drv);
-static inline void delete_driver(driver_t *drv);
-static inline void add_driver(driver_t *drv);
-static char * get_abs_path(const char *base_path, const char *name, const char *ext);
-static bool parse_match_ids(const char *buf, match_id_list_t *ids);
-static bool read_match_ids(const char *conf_path, match_id_list_t *ids);
-static void clean_match_ids(match_id_list_t *ids);
-static inline match_id_t * create_match_id();
-static inline void delete_match_id(match_id_t *id);
-static void add_match_id(match_id_list_t *ids, match_id_t *id);
-static bool get_driver_info(const char *base_path, const char *name, driver_t *drv);
-static int lookup_available_drivers(const char *dir_path);
-static inline node_t * create_dev_node();
-static node_t * create_root_node();
-static bool init_device_tree(dev_tree_t *tree);
-static bool devman_init();
-static int get_match_score(driver_t *drv, node_t *dev);
-
-
-
-LIST_INITIALIZE(drivers_list);
-
-
-
-/** Represents device tree.
- */
-struct dev_tree {
-	node_t *root_node;
-};
-
-static dev_tree_t device_tree;
-
-/** Ids of device models used for device-to-driver matching.
- */
-struct match_id {
-	/** Pointers to next and previous ids.
-	 */
-	link_t link;
-	/** Id of device model.
-	 */
-	const char *id;
-	/** Relevancy of device-to-driver match.
-	 * The higher is the product of scores specified for the device by the bus driver and by the leaf driver,
-	 * the more suitable is the leaf driver for handling the device.
-	 */
-	unsigned int score;
-};
-
-/** List of ids for matching devices to drivers sorted
- * according to match scores in descending order.
- */
-struct match_id_list {
-	link_t ids;
-};
-
-/** Representation of device driver.
- */
-struct driver {
-	/** Pointers to previous and next drivers in a linked list */
-	link_t drivers;
-	/** Specifies whether the driver has been started.*/
-	bool running;
-	/** Phone asociated with this driver */
-	ipcarg_t phone;
-	/** Name of the device driver */
-	char *name;
-	/** Path to the driver's binary */
-	const char *binary_path;
-	/** List of device ids for device-to-driver matching.*/
-	match_id_list_t match_ids;
-	/** Pointer to the linked list of devices controlled by this driver */
-	link_t devices;
-};
-
-/** Representation of a node in the device tree.*/
-struct node {
-	/** The node of the parent device. */
-	node_t *parent;
-	/** Pointers to previous and next child devices in the linked list of parent device's node.*/
-	link_t sibling;	
-	/** List of child device nodes. */
-	link_t children;
-	/** List of device ids for device-to-driver matching.*/
-	match_id_list_t match_ids;	
-	/** Driver of this device.*/
-	driver_t *drv;	
-	/** Pointer to the previous and next device in the list of devices
-	    owned by one driver */
-	link_t driver_devices;	
-};
-
-static driver_t * create_driver() 
+
+#include "devman.h"
+#include "util.h"
+
+
+driver_t * create_driver() 
 {
 	driver_t *res = malloc(sizeof(driver_t));
@@ -176,124 +48,8 @@
 }
 
-static inline void init_driver(driver_t *drv) 
-{
-	assert(drv != NULL);	
-	
-	memset(drv, 0, sizeof(driver_t));	
-	list_initialize(&drv->match_ids.ids);
-	list_initialize(&drv->devices);
-}
-
-static inline void clean_driver(driver_t *drv) 
-{
-	assert(drv != NULL);
-	
-	free(drv->name);
-	free(drv->binary_path);
-	
-	clean_match_ids(&drv->match_ids);
-	
-	init_driver(drv);	
-}
-
-static void clean_match_ids(match_id_list_t *ids)
-{
-	link_t *link = NULL;
-	match_id_t *id;
-	
-	while(!list_empty(&ids->ids)) {
-		link = ids->ids.next;
-		list_remove(link);		
-		id = list_get_instance(link, match_id_t, link);
-		delete_match_id(id);		
-	}	
-}
-
-static inline match_id_t * create_match_id() 
-{
-	match_id_t *id = malloc(sizeof(match_id_t));
-	memset(id, 0, sizeof(match_id_t));
-	return id;	
-}
-
-static inline void delete_match_id(match_id_t *id) 
-{
-	free(id->id);
-	free(id);
-}
-
-static void add_match_id(match_id_list_t *ids, match_id_t *id) 
-{
-	match_id_t *mid = NULL;
-	link_t *link = ids->ids.next;	
-	
-	while (link != &ids->ids) {
-		mid = list_get_instance(link, match_id_t,link);
-		if (mid->score < id->score) {
-			break;
-		}	
-		link = link->next;
-	}
-	
-	list_insert_before(&id->link, link);	
-}
-
-static inline void delete_driver(driver_t *drv) 
-{
-	clean_driver(drv);
-	free(drv);
-}
-
-static inline void add_driver(driver_t *drv)
-{
-	list_prepend(&drv->drivers, &drivers_list);
-	printf(NAME": the '%s' driver was added to the list of available drivers.\n", drv->name);	
-}
-
-static char * get_abs_path(const char *base_path, const char *name, const char *ext) 
-{
-	char *res;
-	int base_len = str_size(base_path);
-	int size = base_len + str_size(name) + str_size(ext) + 3;	
-	
-	res = malloc(size);
-	
-	if (res) {
-		str_cpy(res, size, base_path);
-		if(base_path[base_len - 1] != '/') { 
-			str_append(res, size, "/");			
-		}
-		str_append(res, size, name);
-		if(ext[0] != '.') {
-			str_append(res, size, ".");
-		}
-		str_append(res, size, ext);		
-	}
-	
-	return res;
-}
-
-static inline bool skip_spaces(const char **buf) 
-{
-	while (isspace(**buf)) {
-		(*buf)++;		
-	}
-	return *buf != 0;	
-}
-
-static inline size_t get_id_len(const char *str) 
-{
-	size_t len = 0;
-	while(*str != 0 && !isspace(*str)) {
-		len++;
-		str++;
-	}
-	return len;
-}
-
-static char * read_id(const char **buf) 
+char * read_id(const char **buf) 
 {
 	char *res = NULL;
-	size_t len = get_id_len(*buf);
+	size_t len = get_nonspace_len(*buf);
 	if (len > 0) {
 		res = malloc(len + 1);
@@ -306,5 +62,5 @@
 }
 
-static bool parse_match_ids(const char *buf, match_id_list_t *ids)
+bool parse_match_ids(const char *buf, match_id_list_t *ids)
 {
 	int score = 0;
@@ -344,5 +100,5 @@
 }
 
-static bool read_match_ids(const char *conf_path, match_id_list_t *ids) 
+bool read_match_ids(const char *conf_path, match_id_list_t *ids) 
 {	
 	bool suc = false;	
@@ -392,5 +148,5 @@
 
 
-static bool get_driver_info(const char *base_path, const char *name, driver_t *drv)
+bool get_driver_info(const char *base_path, const char *name, driver_t *drv)
 {
 	assert(base_path != NULL && name != NULL && drv != NULL);
@@ -447,7 +203,8 @@
 /** Lookup drivers in the directory.
  * 
- * @param dir_path the path to the directory where we search for drivers. * 
+ * @param drivers_list the list of available drivers.
+ * @param dir_path the path to the directory where we search for drivers. 
  */ 
-static int lookup_available_drivers(const char *dir_path)
+int lookup_available_drivers(link_t *drivers_list, const char *dir_path)
 {
 	int drv_cnt = 0;
@@ -460,5 +217,5 @@
 		while ((diren = readdir(dir))) {			
 			if (get_driver_info(dir_path, diren->d_name, drv)) {
-				add_driver(drv);
+				add_driver(drivers_list, drv);
 				drv = create_driver();
 			}	
@@ -471,28 +228,5 @@
 }
 
-static inline node_t * create_dev_node()
-{
-	node_t *res = malloc(sizeof(node_t));
-	if (res != NULL) {
-		memset(res, 0, sizeof(node_t));	
-	}
-	return res;
-}
-
-static inline void init_dev_node(node_t *node, node_t *parent) 
-{
-	assert(NULL != node);
-	
-	node->parent = parent;
-	if (NULL != parent) {
-		list_append(&node->sibling, &parent->children);
-	}
-	
-	list_initialize(&node->children);
-	
-	list_initialize(&node->match_ids.ids);	
-}
-
-static node_t * create_root_node()
+node_t * create_root_node()
 {
 	node_t *node = create_dev_node();
@@ -507,63 +241,11 @@
 }
 
-static int get_match_score(driver_t *drv, node_t *dev)
-{	
-	link_t* drv_head = &drv->match_ids.ids;	
-	link_t* dev_head = &dev->match_ids.ids;
-	
-	if (list_empty(drv_head) || list_empty(dev_head)) {
-		return 0;
-	}
-	
-	link_t* drv_link = drv->match_ids.ids.next;
-	link_t* dev_link = dev->match_ids.ids.next;
-	
-	match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link);
-	match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link);
-	
-	int score_next_drv = 0;
-	int score_next_dev = 0;
-	
-	do {
-		if (0 == str_cmp(drv_id->id, dev_id->id)) { 	// we found a match	
-			// return the score of the match
-			return drv_id->score * dev_id->score;
-		}
-		
-		// compute the next score we get, if we advance in the driver's list of match ids 
-		if (drv_head != drv_link->next) {
-			score_next_drv = dev_id->score * list_get_instance(drv_link->next, match_id_t, link)->score;			
-		} else {
-			score_next_drv = 0;
-		}
-		
-		// compute the next score we get, if we advance in the device's list of match ids 
-		if (dev_head != dev_link->next) {
-			score_next_dev = drv_id->score * list_get_instance(dev_link->next, match_id_t, link)->score;			
-		} else {
-			score_next_dev = 0;
-		}
-		
-		// advance in one of the two lists, so we get the next highest score
-		if (score_next_drv > score_next_dev) {
-			drv_link = drv_link->next;
-			drv_id = list_get_instance(drv_link, match_id_t, link);
-		} else {
-			dev_link = dev_link->next;
-			dev_id = list_get_instance(dev_link, match_id_t, link);
-		}
-		
-	} while (drv_head != drv_link->next && dev_head != dev_link->next);
-	
-	return 0;
-}
-
-static driver_t * find_best_match_driver(node_t *node)
+driver_t * find_best_match_driver(link_t *drivers_list, node_t *node)
 {
 	driver_t *best_drv = NULL, *drv = NULL;
 	int best_score = 0, score = 0;
-	link_t *link = drivers_list.next;	
-	
-	while (link != &drivers_list) {
+	link_t *link = drivers_list->next;	
+	
+	while (link != drivers_list) {
 		drv = list_get_instance(link, driver_t, drivers);
 		score = get_match_score(drv, node);
@@ -577,5 +259,5 @@
 }
 
-static void attach_driver(node_t *node, driver_t *drv) 
+void attach_driver(node_t *node, driver_t *drv) 
 {
 	node->drv = drv;
@@ -583,5 +265,5 @@
 }
 
-static bool start_driver(driver_t *drv)
+bool start_driver(driver_t *drv)
 {
 	char *argv[2];
@@ -600,5 +282,5 @@
 }
 
-static bool add_device(driver_t *drv, node_t *node)
+bool add_device(driver_t *drv, node_t *node)
 {
 	// TODO
@@ -612,8 +294,8 @@
 }
 
-static bool assign_driver(node_t *node) 
+bool assign_driver(node_t *node, link_t *drivers_list) 
 {
 	// find the driver which is the most suitable for handling this device
-	driver_t *drv = find_best_match_driver(node);
+	driver_t *drv = find_best_match_driver(drivers_list, node);
 	if (NULL == drv) {
 		return false;		
@@ -634,5 +316,5 @@
 }
 
-static bool init_device_tree(dev_tree_t *tree)
+bool init_device_tree(dev_tree_t *tree, link_t *drivers_list)
 {
 	// create root node and add it to the device tree
@@ -642,69 +324,5 @@
 
 	// find suitable driver and start it
-	return assign_driver(tree->root_node);
-}
-
-/** Initialize device manager internal structures.
- */
-static bool devman_init()
-{
-	// initialize list of available drivers
-	if (0 == lookup_available_drivers(DRIVER_DEFAULT_STORE)) {
-		printf(NAME " no drivers found.");
-		return false;
-	}
-
-	// create root device node 
-	if (!init_device_tree(&device_tree)) {
-		printf(NAME " failed to initialize device tree.");
-		return false;		
-	}
-
-	return true;
-}
-
-
-/** Function for handling connections to device manager.
- *
- */
-static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	/* Select interface */
-	switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) {
-	/*case DEVMAN_DRIVER:
-		devmap_connection_driver(iid, icall);
-		break;*/
-
-	default:
-		/* No such interface */
-		ipc_answer_0(iid, ENOENT);
-	}
-}
-
-/**
- *
- */
-int main(int argc, char *argv[])
-{
-	printf(NAME ": HelenOS Device Manager\n");
-
-	if (!devman_init()) {
-		printf(NAME ": Error while initializing service\n");
-		return -1;
-	}
-
-	/*
-	// Set a handler of incomming connections
-	async_set_client_connection(devman_connection);
-
-	// Register device manager at naming service
-	ipcarg_t phonead;
-	if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0)
-		return -1;
-
-	printf(NAME ": Accepting connections\n");
-	async_manager();*/
-
-	// Never reached
-	return 0;
-}
+	return assign_driver(tree->root_node, drivers_list);
+}
+
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
+++ uspace/srv/devman/devman.h	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup devman
+ * @{
+ */
+ 
+#ifndef DEVMAN_H_
+#define DEVMAN_H_
+
+#include <assert.h>
+#include <bool.h>
+#include <dirent.h>
+#include <string.h>
+#include <adt/list.h>
+#include <ipc/ipc.h>
+
+
+#define NAME "devman"
+
+#define MATCH_EXT ".ma"
+
+struct node;
+
+typedef struct node node_t;
+
+/** Ids of device models used for device-to-driver matching.
+ */
+typedef struct match_id {
+	/** Pointers to next and previous ids.
+	 */
+	link_t link;
+	/** Id of device model.
+	 */
+	const char *id;
+	/** Relevancy of device-to-driver match.
+	 * The higher is the product of scores specified for the device by the bus driver and by the leaf driver,
+	 * the more suitable is the leaf driver for handling the device.
+	 */
+	unsigned int score;
+} match_id_t;
+
+/** List of ids for matching devices to drivers sorted
+ * according to match scores in descending order.
+ */
+typedef struct match_id_list {
+	link_t ids;
+} match_id_list_t;
+
+/** Representation of device driver.
+ */
+typedef struct driver {
+	/** Pointers to previous and next drivers in a linked list */
+	link_t drivers;
+	/** Specifies whether the driver has been started.*/
+	bool running;
+	/** Phone asociated with this driver */
+	ipcarg_t phone;
+	/** Name of the device driver */
+	char *name;
+	/** Path to the driver's binary */
+	const char *binary_path;
+	/** List of device ids for device-to-driver matching.*/
+	match_id_list_t match_ids;
+	/** Pointer to the linked list of devices controlled by this driver */
+	link_t devices;
+} driver_t;
+
+/** Representation of a node in the device tree.*/
+struct node {
+	/** The node of the parent device. */
+	node_t *parent;
+	/** Pointers to previous and next child devices in the linked list of parent device's node.*/
+	link_t sibling;	
+	/** List of child device nodes. */
+	link_t children;
+	/** List of device ids for device-to-driver matching.*/
+	match_id_list_t match_ids;	
+	/** Driver of this device.*/
+	driver_t *drv;	
+	/** Pointer to the previous and next device in the list of devices
+	    owned by one driver */
+	link_t driver_devices;	
+};
+
+/** Represents device tree.
+ */
+typedef struct dev_tree {
+	/** Root device node. */
+	node_t *root_node;
+} dev_tree_t;
+
+
+
+// Match ids and scores
+
+int get_match_score(driver_t *drv, node_t *dev);
+
+bool parse_match_ids(const char *buf, match_id_list_t *ids);
+bool read_match_ids(const char *conf_path, match_id_list_t *ids);
+char * read_id(const char **buf) ;
+void add_match_id(match_id_list_t *ids, match_id_t *id);
+
+void clean_match_ids(match_id_list_t *ids);
+
+
+static inline match_id_t * create_match_id() 
+{
+	match_id_t *id = malloc(sizeof(match_id_t));
+	memset(id, 0, sizeof(match_id_t));
+	return id;	
+}
+
+static inline void delete_match_id(match_id_t *id) 
+{
+	free(id->id);
+	free(id);
+}
+
+// Drivers
+
+driver_t * create_driver();
+bool get_driver_info(const char *base_path, const char *name, driver_t *drv);
+int lookup_available_drivers(link_t *drivers_list, const char *dir_path);
+
+driver_t * find_best_match_driver(link_t *drivers_list, node_t *node);
+bool assign_driver(node_t *node, link_t *drivers_list);
+
+void attach_driver(node_t *node, driver_t *drv); 
+bool add_device(driver_t *drv, node_t *node);
+bool start_driver(driver_t *drv);
+
+
+static inline void init_driver(driver_t *drv) 
+{
+	assert(drv != NULL);	
+	
+	memset(drv, 0, sizeof(driver_t));	
+	list_initialize(&drv->match_ids.ids);
+	list_initialize(&drv->devices);
+}
+
+static inline void clean_driver(driver_t *drv) 
+{
+	assert(drv != NULL);
+	
+	free(drv->name);
+	free(drv->binary_path);
+	
+	clean_match_ids(&drv->match_ids);
+	
+	init_driver(drv);	
+}
+
+static inline void delete_driver(driver_t *drv) 
+{
+	clean_driver(drv);
+	free(drv);
+}
+
+static inline void add_driver(link_t *drivers_list, driver_t *drv)
+{
+	list_prepend(&drv->drivers, drivers_list);
+	printf(NAME": the '%s' driver was added to the list of available drivers.\n", drv->name);	
+}
+
+
+// Device nodes
+node_t * create_root_node();
+
+static inline node_t * create_dev_node()
+{
+	node_t *res = malloc(sizeof(node_t));
+	if (res != NULL) {
+		memset(res, 0, sizeof(node_t));	
+	}
+	return res;
+}
+
+static inline void init_dev_node(node_t *node, node_t *parent) 
+{
+	assert(NULL != node);
+	
+	node->parent = parent;
+	if (NULL != parent) {
+		list_append(&node->sibling, &parent->children);
+	}
+	
+	list_initialize(&node->children);
+	
+	list_initialize(&node->match_ids.ids);	
+}
+
+
+// Device tree
+
+bool init_device_tree(dev_tree_t *tree, link_t *drivers_list);
+
+
+#endif
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
+++ uspace/srv/devman/main.c	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @defgroup devman Device manager.
+ * @brief HelenOS device manager.
+ * @{
+ */
+
+/** @file
+ */
+
+#include <assert.h>
+#include <ipc/services.h>
+#include <ipc/ns.h>
+#include <async.h>
+#include <stdio.h>
+#include <errno.h>
+#include <bool.h>
+#include <fibril_synch.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <ipc/devman.h>
+
+#include "devman.h"
+
+#define DRIVER_DEFAULT_STORE  "/srv/drivers"
+
+LIST_INITIALIZE(drivers_list);
+static dev_tree_t device_tree;
+
+
+/** Function for handling connections to device manager.
+ *
+ */
+static void devman_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	
+	/* Accept the connection */
+	ipc_answer_0(iid, EOK);
+	
+	while (1) {
+		callid = async_get_call(&call);
+		
+		switch (IPC_GET_METHOD(call)) {
+		case DEVMAN_DRIVER_REGISTER:
+			// TODO register running driver instance - remember driver's phone and lookup devices to which it has been assigned
+			break;
+		case DEVMAN_ADD_CHILD_DEVICE:
+			// TODO add new device node to the device tree
+			break;
+		default:
+			ipc_answer_0(callid, EINVAL); 
+			break;
+		}
+	}
+}
+
+/** Initialize device manager internal structures.
+ */
+static bool devman_init()
+{
+	// initialize list of available drivers
+	if (0 == lookup_available_drivers(&drivers_list, DRIVER_DEFAULT_STORE)) {
+		printf(NAME " no drivers found.");
+		return false;
+	}
+
+	// create root device node 
+	if (!init_device_tree(&device_tree, &drivers_list)) {
+		printf(NAME " failed to initialize device tree.");
+		return false;		
+	}
+
+	return true;
+}
+
+/**
+ *
+ */
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS Device Manager\n");
+
+	if (!devman_init()) {
+		printf(NAME ": Error while initializing service\n");
+		return -1;
+	}
+	
+	// Set a handler of incomming connections
+	async_set_client_connection(devman_connection);
+
+	// Register device manager at naming service
+	ipcarg_t phonead;
+	if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0)
+		return -1;
+
+	printf(NAME ": Accepting connections\n");
+	async_manager();
+
+	// Never reached
+	return 0;
+}
Index: uspace/srv/devman/match.c
===================================================================
--- uspace/srv/devman/match.c	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
+++ uspace/srv/devman/match.c	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup devman
+ * @{
+ */
+ 
+ 
+#include <string.h>
+
+#include "devman.h"
+
+
+int get_match_score(driver_t *drv, node_t *dev)
+{	
+	link_t* drv_head = &drv->match_ids.ids;	
+	link_t* dev_head = &dev->match_ids.ids;
+	
+	if (list_empty(drv_head) || list_empty(dev_head)) {
+		return 0;
+	}
+	
+	link_t* drv_link = drv->match_ids.ids.next;
+	link_t* dev_link = dev->match_ids.ids.next;
+	
+	match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link);
+	match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link);
+	
+	int score_next_drv = 0;
+	int score_next_dev = 0;
+	
+	do {
+		if (0 == str_cmp(drv_id->id, dev_id->id)) { 	// we found a match	
+			// return the score of the match
+			return drv_id->score * dev_id->score;
+		}
+		
+		// compute the next score we get, if we advance in the driver's list of match ids 
+		if (drv_head != drv_link->next) {
+			score_next_drv = dev_id->score * list_get_instance(drv_link->next, match_id_t, link)->score;			
+		} else {
+			score_next_drv = 0;
+		}
+		
+		// compute the next score we get, if we advance in the device's list of match ids 
+		if (dev_head != dev_link->next) {
+			score_next_dev = drv_id->score * list_get_instance(dev_link->next, match_id_t, link)->score;			
+		} else {
+			score_next_dev = 0;
+		}
+		
+		// advance in one of the two lists, so we get the next highest score
+		if (score_next_drv > score_next_dev) {
+			drv_link = drv_link->next;
+			drv_id = list_get_instance(drv_link, match_id_t, link);
+		} else {
+			dev_link = dev_link->next;
+			dev_id = list_get_instance(dev_link, match_id_t, link);
+		}
+		
+	} while (drv_head != drv_link->next && dev_head != dev_link->next);
+	
+	return 0;
+}
+
+void add_match_id(match_id_list_t *ids, match_id_t *id) 
+{
+	match_id_t *mid = NULL;
+	link_t *link = ids->ids.next;	
+	
+	while (link != &ids->ids) {
+		mid = list_get_instance(link, match_id_t,link);
+		if (mid->score < id->score) {
+			break;
+		}	
+		link = link->next;
+	}
+	
+	list_insert_before(&id->link, link);	
+}
+
+void clean_match_ids(match_id_list_t *ids)
+{
+	link_t *link = NULL;
+	match_id_t *id;
+	
+	while(!list_empty(&ids->ids)) {
+		link = ids->ids.next;
+		list_remove(link);		
+		id = list_get_instance(link, match_id_t, link);
+		delete_match_id(id);		
+	}	
+}
+
Index: uspace/srv/devman/util.c
===================================================================
--- uspace/srv/devman/util.c	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
+++ uspace/srv/devman/util.c	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup devman
+ * @{
+ */
+
+#include <stdlib.h>
+#include <string.h> 
+ 
+#include "util.h"
+ 
+
+char * get_abs_path(const char *base_path, const char *name, const char *ext) 
+{
+	char *res;
+	int base_len = str_size(base_path);
+	int size = base_len + str_size(name) + str_size(ext) + 3;	
+	
+	res = malloc(size);
+	
+	if (res) {
+		str_cpy(res, size, base_path);
+		if(base_path[base_len - 1] != '/') { 
+			str_append(res, size, "/");			
+		}
+		str_append(res, size, name);
+		if(ext[0] != '.') {
+			str_append(res, size, ".");
+		}
+		str_append(res, size, ext);		
+	}
+	
+	return res;
+}
Index: uspace/srv/devman/util.h
===================================================================
--- uspace/srv/devman/util.h	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
+++ uspace/srv/devman/util.h	(revision e2b9a993a065ba9a3b546b85bf86e5466f3f8d06)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup devman
+ * @{
+ */
+ 
+#ifndef DEVMAN_UTIL_H_
+#define DEVMAN_UTIL_H_
+
+#include <ctype.h>
+
+
+char * get_abs_path(const char *base_path, const char *name, const char *ext);
+
+static inline bool skip_spaces(const char **buf) 
+{
+	while (isspace(**buf)) {
+		(*buf)++;		
+	}
+	return *buf != 0;	
+}
+
+static inline size_t get_nonspace_len(const char *str) 
+{
+	size_t len = 0;
+	while(*str != 0 && !isspace(*str)) {
+		len++;
+		str++;
+	}
+	return len;
+}
+
+#endif
