Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/lib/c/generic/loc.c	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -291,4 +291,47 @@
 }
 
+/** Get service name.
+ *
+ * Provided ID of a service, return its name.
+ *
+ * @param svc_id	Service ID
+ * @param name		Place to store pointer to new string. Caller should
+ *			free it using free().
+ * @return		EOK on success or negative error code
+ */
+int loc_service_get_name(service_id_t svc_id, char **name)
+{
+	async_exch_t *exch;
+	char name_buf[LOC_NAME_MAXLEN + 1];
+	
+	*name = NULL;
+	memset(name_buf, 0, LOC_NAME_MAXLEN + 1);
+	exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, LOC_SERVICE_GET_NAME, svc_id, &answer);
+	int rc = async_data_read_start(exch, name_buf, LOC_NAME_MAXLEN);
+	
+	loc_exchange_end(exch);
+	
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return rc;
+	}
+	
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+	
+	if (retval != EOK)
+		return retval;
+	
+	*name = str_dup(name_buf);
+	if (*name == NULL)
+		return ENOMEM;
+	
+	return EOK;
+}
+
+
 int loc_namespace_get_id(const char *name, service_id_t *handle,
     unsigned int flags)
Index: uspace/lib/c/include/ipc/loc.h
===================================================================
--- uspace/lib/c/include/ipc/loc.h	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/lib/c/include/ipc/loc.h	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -55,4 +55,5 @@
 	LOC_SERVICE_UNREGISTER,
 	LOC_SERVICE_GET_ID,
+	LOC_SERVICE_GET_NAME,
 	LOC_NAMESPACE_GET_ID,
 	LOC_CATEGORY_GET_ID,
Index: uspace/lib/c/include/loc.h
===================================================================
--- uspace/lib/c/include/loc.h	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/lib/c/include/loc.h	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -52,8 +52,10 @@
 extern int loc_service_get_id(const char *, service_id_t *,
     unsigned int);
+extern int loc_service_get_name(service_id_t, char **);
 extern int loc_namespace_get_id(const char *, service_id_t *,
     unsigned int);
 extern int loc_category_get_id(const char *, category_id_t *,
     unsigned int);
+extern int loc_category_get_name(category_id_t, char **);
 extern int loc_category_get_svcs(category_id_t, category_id_t **, size_t *);
 extern loc_object_type_t loc_id_probe(service_id_t);
Index: uspace/srv/hid/input/ctl/kbdev.c
===================================================================
--- uspace/srv/hid/input/ctl/kbdev.c	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/srv/hid/input/ctl/kbdev.c	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -98,14 +98,10 @@
 	async_exch_t *exch;
 	kbdev_t *kbdev;
-	char *svc_name;
 	int rc;
 
-	if (asprintf(&svc_name, "devname%" PRIun, kdev->service_id) > 0)
-		svc_name = (char *) "unknown";
-
-	sess = loc_service_connect(EXCHANGE_SERIALIZE, kdev->service_id, 0);
+	sess = loc_service_connect(EXCHANGE_SERIALIZE, kdev->svc_id, 0);
 	if (sess == NULL) {
 		printf("%s: Failed starting session with '%s.'\n", NAME,
-		    svc_name);
+		    kdev->svc_name);
 		return -1;
 	}
@@ -114,5 +110,5 @@
 	if (kbdev == NULL) {
 		printf("%s: Failed allocating device structure for '%s'.\n",
-		    NAME, svc_name);
+		    NAME, kdev->svc_name);
 		return -1;
 	}
@@ -123,5 +119,5 @@
 	if (exch == NULL) {
 		printf("%s: Failed starting exchange with '%s'.\n", NAME,
-		    svc_name);
+		    kdev->svc_name);
 		kbdev_destroy(kbdev);
 		return -1;
@@ -131,5 +127,5 @@
 	if (rc != EOK) {
 		printf("%s: Failed creating callback connection from '%s'.\n",
-		    NAME, svc_name);
+		    NAME, kdev->svc_name);
 		async_exchange_end(exch);
 		kbdev_destroy(kbdev);
Index: uspace/srv/hid/input/generic/input.c
===================================================================
--- uspace/srv/hid/input/generic/input.c	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/srv/hid/input/generic/input.c	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -276,5 +276,5 @@
 	kdev->port_ops = port;
 	kdev->ctl_ops = ctl;
-	kdev->service_id = 0;
+	kdev->svc_id = 0;
 	
 	/* Initialize port driver. */
@@ -304,5 +304,5 @@
 	mdev->port_ops = port;
 	mdev->proto_ops = proto;
-	mdev->service_id = 0;
+	mdev->svc_id = 0;
 	
 	/* Initialize port driver. */
@@ -328,5 +328,5 @@
  *
  */
-static int kbd_add_kbdev(service_id_t service_id)
+static int kbd_add_kbdev(service_id_t service_id, kbd_dev_t **kdevp)
 {
 	kbd_dev_t *kdev = kbd_dev_new();
@@ -334,8 +334,14 @@
 		return -1;
 	
-	kdev->service_id = service_id;
+	kdev->svc_id = service_id;
 	kdev->port_ops = NULL;
 	kdev->ctl_ops = &kbdev_ctl;
 	
+	int rc = loc_service_get_name(service_id, &kdev->svc_name);
+	if (rc != EOK) {
+		kdev->svc_name = NULL;
+		goto fail;
+	}
+	
 	/* Initialize controller driver. */
 	if ((*kdev->ctl_ops->init)(kdev) != 0) {
@@ -344,7 +350,10 @@
 	
 	list_append(&kdev->kbd_devs, &kbd_devs);
+	*kdevp = kdev;
 	return EOK;
 	
 fail:
+	if (kdev->svc_name != NULL)
+		free(kdev->svc_name);
 	free(kdev);
 	return -1;
@@ -356,5 +365,5 @@
  *
  */
-static int mouse_add_mousedev(service_id_t service_id)
+static int mouse_add_mousedev(service_id_t service_id, mouse_dev_t **mdevp)
 {
 	mouse_dev_t *mdev = mouse_dev_new();
@@ -362,8 +371,14 @@
 		return -1;
 	
-	mdev->service_id = service_id;
+	mdev->svc_id = service_id;
 	mdev->port_ops = NULL;
 	mdev->proto_ops = &mousedev_proto;
 	
+	int rc = loc_service_get_name(service_id, &mdev->svc_name);
+	if (rc != EOK) {
+		mdev->svc_name = NULL;
+		goto fail;
+	}
+	
 	/* Initialize controller driver. */
 	if ((*mdev->proto_ops->init)(mdev) != 0) {
@@ -372,4 +387,5 @@
 	
 	list_append(&mdev->mouse_devs, &mouse_devs);
+	*mdevp = mdev;
 	return EOK;
 	
@@ -494,5 +510,4 @@
 	size_t count, i;
 	bool already_known;
-	const char *dev_name = "todo";
 	int rc;
 	
@@ -529,5 +544,5 @@
 				kbd_dev_t *kdev = list_get_instance(kdev_link,
 				    kbd_dev_t, kbd_devs);
-				if (kdev->service_id == svcs[i]) {
+				if (kdev->svc_id == svcs[i]) {
 					already_known = true;
 					break;
@@ -536,7 +551,8 @@
 
 			if (!already_known) {
-				if (kbd_add_kbdev(svcs[i]) == EOK) {
+				kbd_dev_t *kdev;
+				if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
 					printf("%s: Connected keyboard device '%s'\n",
-					    NAME, dev_name);
+					    NAME, kdev->svc_name);
 				}
 			}
@@ -562,5 +578,5 @@
 				mouse_dev_t *mdev = list_get_instance(mdev_link,
 				    mouse_dev_t, mouse_devs);
-				if (mdev->service_id == svcs[i]) {
+				if (mdev->svc_id == svcs[i]) {
 					already_known = true;
 					break;
@@ -569,7 +585,8 @@
 
 			if (!already_known) {
-				if (mouse_add_mousedev(svcs[i]) == EOK) {
+				mouse_dev_t *mdev;
+				if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
 					printf("%s: Connected mouse device '%s'\n",
-					    NAME, dev_name);
+					    NAME, mdev->svc_name);
 				}
 			}
Index: uspace/srv/hid/input/include/kbd.h
===================================================================
--- uspace/srv/hid/input/include/kbd.h	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/srv/hid/input/include/kbd.h	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -51,5 +51,8 @@
 
 	/** Service ID (only for kbdev devices) */
-	service_id_t service_id;
+	service_id_t svc_id;
+
+	/** Device service name (only for kbdev devices) */
+	char *svc_name;
 
 	/** Port ops */
Index: uspace/srv/hid/input/include/mouse.h
===================================================================
--- uspace/srv/hid/input/include/mouse.h	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/srv/hid/input/include/mouse.h	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -49,5 +49,8 @@
 	
 	/** Service ID (only for mousedev devices) */
-	service_id_t service_id;
+	service_id_t svc_id;
+	
+	/** Device service name (only for mousedev devices) */
+	char *svc_name;
 	
 	/** Port ops */
Index: uspace/srv/hid/input/proto/mousedev.c
===================================================================
--- uspace/srv/hid/input/proto/mousedev.c	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/srv/hid/input/proto/mousedev.c	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -117,13 +117,9 @@
 static int mousedev_proto_init(mouse_dev_t *mdev)
 {
-	char *svc_name;
-	
-	if (asprintf(&svc_name, "devname%" PRIun, mdev->service_id) > 0)
-		svc_name = (char *) "unknown";
-	
 	async_sess_t *sess = loc_service_connect(EXCHANGE_SERIALIZE,
-	    mdev->service_id, 0);
+	    mdev->svc_id, 0);
 	if (sess == NULL) {
-		printf("%s: Failed starting session with '%s'\n", NAME, svc_name);
+		printf("%s: Failed starting session with '%s'\n", NAME,
+		    mdev->svc_name);
 		return -1;
 	}
@@ -132,5 +128,5 @@
 	if (mousedev == NULL) {
 		printf("%s: Failed allocating device structure for '%s'.\n",
-		    NAME, svc_name);
+		    NAME, mdev->svc_name);
 		return -1;
 	}
@@ -141,5 +137,5 @@
 	if (exch == NULL) {
 		printf("%s: Failed starting exchange with '%s'.\n", NAME,
-		    svc_name);
+		    mdev->svc_name);
 		mousedev_destroy(mousedev);
 		return -1;
@@ -151,5 +147,5 @@
 	if (rc != EOK) {
 		printf("%s: Failed creating callback connection from '%s'.\n",
-		    NAME, svc_name);
+		    NAME, mdev->svc_name);
 		mousedev_destroy(mousedev);
 		return -1;
Index: uspace/srv/loc/loc.c
===================================================================
--- uspace/srv/loc/loc.c	(revision 6d605e69652806366168cf5466d2498cf2f28dbf)
+++ uspace/srv/loc/loc.c	(revision cce8a8318e65105693f8390140c8d7327f39cac6)
@@ -44,4 +44,5 @@
 #include <bool.h>
 #include <fibril_synch.h>
+#include <macros.h>
 #include <stdlib.h>
 #include <str.h>
@@ -532,4 +533,44 @@
 }
 
+static void loc_service_get_name(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	size_t size;
+	size_t act_size;
+	loc_service_t *svc;
+	
+	if (!async_data_read_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+	
+	fibril_mutex_lock(&services_list_mutex);
+	
+	svc = loc_service_find_id(IPC_GET_ARG1(*icall));
+	if (svc == NULL) {
+		fibril_mutex_unlock(&services_list_mutex);
+		async_answer_0(callid, ENOENT);
+		async_answer_0(iid, ENOENT);
+		return;
+	}
+	
+	act_size = str_size(svc->name);
+	if (act_size > size) {
+		fibril_mutex_unlock(&services_list_mutex);
+		async_answer_0(callid, EOVERFLOW);
+		async_answer_0(iid, EOVERFLOW);
+		return;
+	}
+	
+	sysarg_t retval = async_data_read_finalize(callid, svc->name,
+	    min(size, act_size));
+	
+	fibril_mutex_unlock(&services_list_mutex);
+	
+	async_answer_0(iid, retval);
+}
+
+
 /** Connect client to the service.
  *
@@ -1197,4 +1238,7 @@
 			loc_service_get_id(callid, &call);
 			break;
+		case LOC_SERVICE_GET_NAME:
+			loc_service_get_name(callid, &call);
+			break;
 		case LOC_NAMESPACE_GET_ID:
 			loc_namespace_get_id(callid, &call);
