Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/devman/devman.c	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -794,7 +794,4 @@
 	case EOK:
 		dev->state = DEVICE_USABLE;
-		exch = async_exchange_begin(drv->sess);
-		async_msg_1(exch, DRIVER_DEV_ADDED, dev->handle);
-		async_exchange_end(exch);
 		break;
 	case ENOENT:
@@ -803,4 +800,5 @@
 	default:
 		dev->state = DEVICE_INVALID;
+		break;
 	}
 	
Index: uspace/srv/loc/loc.c
===================================================================
--- uspace/srv/loc/loc.c	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/loc/loc.c	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -56,4 +56,10 @@
 #define NULL_SERVICES  256
 
+/** Callback session */
+typedef struct {
+	link_t cb_sess_list;
+	async_sess_t *sess;
+} cb_sess_t;
+
 LIST_INITIALIZE(services_list);
 LIST_INITIALIZE(namespaces_list);
@@ -86,5 +92,5 @@
 
 static FIBRIL_MUTEX_INITIALIZE(callback_sess_mutex);
-static async_sess_t *callback_sess = NULL;
+static LIST_INITIALIZE(callback_sess_list);
 
 service_id_t loc_create_id(void)
@@ -608,4 +614,5 @@
 	size_t act_size;
 	loc_service_t *svc;
+	char *fqn;
 	
 	if (!async_data_read_receive(&callid, &size)) {
@@ -625,6 +632,14 @@
 	}
 	
-	act_size = str_size(svc->name);
+	if (asprintf(&fqn, "%s/%s", svc->namespace->name, svc->name) < 0) {
+		fibril_mutex_unlock(&services_list_mutex);
+		async_answer_0(callid, ENOMEM);
+		async_answer_0(iid, ENOMEM);
+		return;
+	}
+	
+	act_size = str_size(fqn);
 	if (act_size > size) {
+		free(fqn);
 		fibril_mutex_unlock(&services_list_mutex);
 		async_answer_0(callid, EOVERFLOW);
@@ -633,6 +648,7 @@
 	}
 	
-	sysarg_t retval = async_data_read_finalize(callid, svc->name,
+	sysarg_t retval = async_data_read_finalize(callid, fqn,
 	    min(size, act_size));
+	free(fqn);
 	
 	fibril_mutex_unlock(&services_list_mutex);
@@ -790,13 +806,17 @@
 }
 
-/** Find ID for category specified by name.
- *
- * On success, answer will contain EOK int retval and service ID in arg1.
+/** Create callback connection.
+ *
+ * Create callback connection which will be used to send category change
+ * events.
+ *
+ * On success, answer will contain EOK int retval.
  * On failure, error code will be sent in retval.
- *
  */
 static void loc_callback_create(ipc_callid_t iid, ipc_call_t *icall)
 {
-	async_sess_t *cb_sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	cb_sess_t *cb_sess;
+	
+	cb_sess = calloc(1, sizeof(cb_sess_t));
 	if (cb_sess == NULL) {
 		async_answer_0(iid, ENOMEM);
@@ -804,12 +824,16 @@
 	}
 	
+	async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (sess == NULL) {
+		free(cb_sess);
+		async_answer_0(iid, ENOMEM);
+		return;
+	}
+	
+	cb_sess->sess = sess;
+	link_initialize(&cb_sess->cb_sess_list);
+	
 	fibril_mutex_lock(&callback_sess_mutex);
-	if (callback_sess != NULL) {
-		fibril_mutex_unlock(&callback_sess_mutex);
-		async_answer_0(iid, EEXIST);
-		return;
-	}
-	
-	callback_sess = cb_sess;
+	list_append(&cb_sess->cb_sess_list, &callback_sess_list);
 	fibril_mutex_unlock(&callback_sess_mutex);
 	
@@ -820,11 +844,15 @@
 {
 	fibril_mutex_lock(&callback_sess_mutex);
-
-	if (callback_sess != NULL) {
-		async_exch_t *exch = async_exchange_begin(callback_sess);
+	
+	list_foreach(callback_sess_list, link) {
+		cb_sess_t *cb_sess;
+		
+		cb_sess = list_get_instance(link, cb_sess_t, cb_sess_list);
+		
+		async_exch_t *exch = async_exchange_begin(cb_sess->sess);
 		async_msg_0(exch, LOC_EVENT_CAT_CHANGE);
 		async_exchange_end(exch);
 	}
-
+	
 	fibril_mutex_unlock(&callback_sess_mutex);
 }
Index: uspace/srv/net/cfg/e1k.nic
===================================================================
--- uspace/srv/net/cfg/e1k.nic	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/cfg/e1k.nic	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -3,5 +3,5 @@
 NAME=e1k
 
-HWPATH=/hw/pci0/00:03.0/port0
+HWPATH=devices/\hw\pci0\00:03.0\port0
 NIL=eth
 IL=ip
Index: uspace/srv/net/cfg/lo.nic
===================================================================
--- uspace/srv/net/cfg/lo.nic	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/cfg/lo.nic	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -3,5 +3,5 @@
 NAME=lo
 
-HWPATH=/virt/lo/port0
+HWPATH=devices/\virt\lo\port0
 NIL=nildummy
 IL=ip
Index: uspace/srv/net/cfg/ne2k.nic
===================================================================
--- uspace/srv/net/cfg/ne2k.nic	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/cfg/ne2k.nic	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -3,5 +3,5 @@
 NAME=ne2k
 
-HWPATH=/hw/pci0/00:01.0/ne2k/port0
+HWPATH=devices/\hw\pci0\00:01.0\ne2k\port0
 NIL=eth
 IL=ip
Index: uspace/srv/net/net/Makefile
===================================================================
--- uspace/srv/net/net/Makefile	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/net/Makefile	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -31,5 +31,6 @@
 ROOT_PATH = $(USPACE_PREFIX)/..
 LIBS = $(LIBNET_PREFIX)/libnet.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBNIC_PREFIX)/include \
+    -I$(LIBDRV_PREFIX)/include
 
 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/net/net.c	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -41,5 +41,4 @@
 #include <stdio.h>
 #include <str.h>
-#include <devman.h>
 #include <str_error.h>
 #include <ns.h>
@@ -56,4 +55,6 @@
 #include <adt/measured_strings.h>
 #include <adt/module_map.h>
+#include <loc.h>
+#include <nic.h>
 #include <nil_remote.h>
 #include <net_interface.h>
@@ -73,4 +74,5 @@
 GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t);
 DEVICE_MAP_IMPLEMENT(netifs, netif_t);
+LIST_INITIALIZE(netif_list);
 
 /** Add the configured setting to the configuration map.
@@ -287,10 +289,12 @@
  *
  */
-static int init_device(netif_t *netif, devman_handle_t handle)
+static int init_device(netif_t *netif, service_id_t sid)
 {
 	printf("%s: Initializing device '%s'\n", NAME, netif->name);
 	
-	netif->handle = handle;
-	netif->sess = devman_device_connect(EXCHANGE_SERIALIZE, netif->handle,
+	link_initialize(&netif->netif_list);
+	
+	netif->sid = sid;
+	netif->sess = loc_service_connect(EXCHANGE_SERIALIZE, netif->sid,
 	    IPC_FLAG_BLOCKING);
 	if (netif->sess == NULL) {
@@ -337,5 +341,5 @@
 		    strtol((const char *) setting->value, NULL, 10) : 0;
 		rc = nil_device_req(netif->nil->sess, netif->id,
-		    netif->handle, mtu);
+		    netif->sid, mtu);
 		if (rc != EOK) {
 			printf("%s: Unable to start network interface layer\n",
@@ -363,18 +367,30 @@
 	
 	printf("%s: Activating device '%s'\n", NAME, netif->name);
+	list_append(&netif->netif_list, &netif_list);
 	return nic_set_state(netif->sess, NIC_STATE_ACTIVE);
 }
 
-static int net_port_ready(devman_handle_t handle)
-{
-	char hwpath[MAX_PATH_LENGTH];
-	int rc = devman_fun_get_path(handle, hwpath, MAX_PATH_LENGTH);
-	if (rc != EOK)
+static int net_nic_ready(service_id_t sid)
+{
+	int rc;
+	char *hwpath;
+	
+	rc = loc_service_get_name(sid, &hwpath);
+	if (rc != EOK) {
+		printf("%s: Failed getting name of service '%u'\n",
+		    NAME, (unsigned) sid);
 		return EINVAL;
+	}
 	
 	int index = char_map_find(&net_globals.netif_hwpaths,
 	    (uint8_t *) hwpath, 0);
-	if (index == CHAR_MAP_NULL)
+	
+	if (index == CHAR_MAP_NULL) {
+		printf("%s: Service '%s' not found in map.\n", NAME, hwpath);
+		free(hwpath);
 		return ENOENT;
+	}
+	
+	free(hwpath);
 	
 	netif_t *netif = netifs_get_index(&net_globals.netifs, index);
@@ -382,5 +398,5 @@
 		return ENOENT;
 	
-	rc = init_device(netif, handle);
+	rc = init_device(netif, sid);
 	if (rc != EOK)
 		return rc;
@@ -391,21 +407,4 @@
 	
 	netif->il->usage++;
-	
-	return EOK;
-}
-
-static int net_driver_ready_local(devman_handle_t handle)
-{
-	devman_handle_t *funs;
-	size_t count;
-	int rc = devman_dev_get_functions(handle, &funs, &count);
-	if (rc != EOK)
-		return rc;
-	
-	for (size_t i = 0; i < count; i++) {
-		rc = net_port_ready(funs[i]);
-		if (rc != EOK)
-			return rc;
-	}
 	
 	return EOK;
@@ -479,8 +478,4 @@
 		net_free_devices(strings, count);
 		return rc;
-	case NET_NET_DRIVER_READY:
-		rc = net_driver_ready_local(IPC_GET_ARG1(*call));
-		*answer_count = 0;
-		return rc;
 	default:
 		return ENOTSUP;
@@ -528,4 +523,68 @@
 		answer_call(callid, res, &answer, count);
 	}
+}
+
+static int nic_check_new(void)
+{
+	category_id_t nic_cat;
+	service_id_t *svcs;
+	size_t count, i;
+	bool already_known;
+	int rc;
+
+	rc = loc_category_get_id(DEVICE_CATEGORY_NIC, &nic_cat, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Failed resolving category '%s'.\n", NAME,
+		    DEVICE_CATEGORY_NIC);
+		return ENOENT;
+	}
+
+	rc = loc_category_get_svcs(nic_cat, &svcs, &count);
+	if (rc != EOK) {
+		printf("%s: Failed getting list of NIC devices.\n", NAME);
+		return EIO;
+	}
+
+	for (i = 0; i < count; i++) {
+		already_known = false;
+
+		list_foreach(netif_list, link) {
+			netif_t *netif = list_get_instance(link, netif_t, netif_list);
+			if (netif->sid == svcs[i]) {
+				already_known = true;
+				break;
+			}
+		}
+
+		if (!already_known) {
+			rc = net_nic_ready(svcs[i]);
+			if (rc != EOK) {
+				printf("%s: Failed adding NIC device #%u.\n",
+				    NAME, (unsigned) svcs[i]);
+			}
+		}
+	}
+
+	free(svcs);
+	return EOK;
+}
+
+static void cat_change_cb(void)
+{
+	(void) nic_check_new();
+}
+
+static int net_start_nic_discovery(void)
+{
+	int rc;
+
+	rc = loc_register_cat_change_cb(cat_change_cb);
+	if (rc != EOK) {
+		printf("%s: Failed registering callback for device discovery (%d).\n",
+		    NAME, rc);
+		return rc;
+	}
+
+	return nic_check_new();
 }
 
@@ -573,5 +632,5 @@
 				continue;
 			
-			netif->handle = -1;
+			netif->sid = -1;
 			netif->sess = NULL;
 			
@@ -697,4 +756,11 @@
 	}
 	
+	rc = net_start_nic_discovery();
+	if (rc != EOK) {
+		printf("%s: Error starting NIC discovery\n", NAME);
+		pm_destroy();
+		return rc;
+	}
+	
 	task_retval(0);
 	async_manager();
Index: uspace/srv/net/net/net.h
===================================================================
--- uspace/srv/net/net/net.h	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/net/net.h	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -35,4 +35,5 @@
 #define NET_NET_H_
 
+#include <ipc/loc.h>
 #include <net/device.h>
 #include <adt/char_map.h>
@@ -41,5 +42,4 @@
 #include <adt/module_map.h>
 #include <net/packet.h>
-#include <devman.h>
 
 #define NAME  "net"
@@ -96,9 +96,11 @@
 	
 	/** Serving network interface driver module index. */
-	devman_handle_t handle;  /**< Handle for devman */
+	service_id_t sid;  /**< Service ID */
 	async_sess_t *sess;      /**< Driver session. */
 	
 	module_t *nil;  /**< Serving link layer module index. */
 	module_t *il;   /**< Serving internet layer module index. */
+	
+	link_t netif_list;
 } netif_t;
 
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/nil/eth/eth.c	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -48,4 +48,5 @@
 #include <ipc/net.h>
 #include <ipc/services.h>
+#include <loc.h>
 #include <net/modules.h>
 #include <net_checksum.h>
@@ -226,5 +227,5 @@
  *
  * @param[in] device_id New device identifier.
- * @param[in] handle    Device driver handle.
+ * @param[in] sid       NIC service ID.
  * @param[in] mtu       Device maximum transmission unit.
  *
@@ -234,5 +235,5 @@
  *
  */
-static int eth_device_message(nic_device_id_t device_id, devman_handle_t handle,
+static int eth_device_message(nic_device_id_t device_id, service_id_t sid,
     size_t mtu)
 {
@@ -259,5 +260,5 @@
 	device = eth_devices_find(&eth_globals.devices, device_id);
 	if (device) {
-		if (device->handle != handle) {
+		if (device->sid != sid) {
 			printf("Device %d already exists\n", device->device_id);
 			fibril_rwlock_write_unlock(&eth_globals.devices_lock);
@@ -298,5 +299,5 @@
 
 	device->device_id = device_id;
-	device->handle = handle;
+	device->sid = sid;
 	device->flags = 0;
 	if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags)))
@@ -335,5 +336,5 @@
 	
 	/* Bind the device driver */
-	device->sess = devman_device_connect(EXCHANGE_SERIALIZE, handle,
+	device->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid,
 	    IPC_FLAG_BLOCKING);
 	if (device->sess == NULL) {
@@ -362,7 +363,7 @@
 	}
 	
-	printf("%s: Device registered (id: %d, handle: %zu: mtu: %zu, "
+	printf("%s: Device registered (id: %d, sid: %zu: mtu: %zu, "
 	    "mac: " PRIMAC ", flags: 0x%x)\n", NAME,
-	    device->device_id, device->handle, device->mtu,
+	    device->device_id, device->sid, device->mtu,
 	    ARGSMAC(device->addr.address), device->flags);
 
Index: uspace/srv/net/nil/eth/eth.h
===================================================================
--- uspace/srv/net/nil/eth/eth.h	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/nil/eth/eth.h	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -41,8 +41,8 @@
 #include <async.h>
 #include <fibril_synch.h>
+#include <ipc/loc.h>
 #include <ipc/services.h>
 #include <net/device.h>
 #include <adt/measured_strings.h>
-#include <devman.h>
 
 /** Ethernet address length. */
@@ -224,5 +224,5 @@
 	nic_device_id_t device_id;
 	/** Device handle */
-	devman_handle_t handle;
+	service_id_t sid;
 	/** Driver session. */
 	async_sess_t *sess;
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -53,6 +53,6 @@
 #include <packet_remote.h>
 #include <packet_client.h>
-#include <devman.h>
 #include <device/nic.h>
+#include <loc.h>
 #include <nil_skel.h>
 #include "nildummy.h"
@@ -115,5 +115,5 @@
  */
 static int nildummy_device_message(nic_device_id_t device_id,
-    devman_handle_t handle, size_t mtu)
+    service_id_t sid, size_t mtu)
 {
 	fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
@@ -123,5 +123,5 @@
 	    nildummy_devices_find(&nildummy_globals.devices, device_id);
 	if (device) {
-		if (device->handle != handle) {
+		if (device->sid != sid) {
 			printf("Device %d exists, handles do not match\n",
 			    device->device_id);
@@ -158,5 +158,5 @@
 	
 	device->device_id = device_id;
-	device->handle = handle;
+	device->sid = sid;
 	if (mtu > 0)
 		device->mtu = mtu;
@@ -165,5 +165,5 @@
 	
 	/* Bind the device driver */
-	device->sess = devman_device_connect(EXCHANGE_SERIALIZE, handle,
+	device->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid,
 	    IPC_FLAG_BLOCKING);
 	if (device->sess == NULL) {
Index: uspace/srv/net/nil/nildummy/nildummy.h
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.h	(revision 1bc35b5107055e337dd8c8f42e37c47db3ecb6f5)
+++ uspace/srv/net/nil/nildummy/nildummy.h	(revision e98fe28c081678acdcefa54690b3b8497e38e0fc)
@@ -41,6 +41,6 @@
 #include <async.h>
 #include <fibril_synch.h>
+#include <ipc/loc.h>
 #include <ipc/services.h>
-#include <ipc/devman.h>
 #include <net/device.h>
 
@@ -78,6 +78,6 @@
 	/** Device identifier. */
 	nic_device_id_t device_id;
-	/** Device driver handle. */
-	devman_handle_t handle;
+	/** Device service ID. */
+	service_id_t sid;
 	/** Driver session. */
 	async_sess_t *sess;
