Index: uspace/lib/dispcfg/include/dispcfg.h
===================================================================
--- uspace/lib/dispcfg/include/dispcfg.h	(revision b3eeae586ec8b5fd5a43327f136f78e7ef242102)
+++ uspace/lib/dispcfg/include/dispcfg.h	(revision c0757e1f444227a4a7447e0004af74bd7026104d)
@@ -51,4 +51,7 @@
 extern errno_t dispcfg_dev_assign(dispcfg_t *, sysarg_t, sysarg_t);
 extern errno_t dispcfg_dev_unassign(dispcfg_t *, sysarg_t);
+extern errno_t dispcfg_get_asgn_dev_list(dispcfg_t *, sysarg_t,
+    dispcfg_dev_list_t **);
+extern void dispcfg_free_dev_list(dispcfg_dev_list_t *);
 
 #endif
Index: uspace/lib/dispcfg/include/dispcfg_srv.h
===================================================================
--- uspace/lib/dispcfg/include/dispcfg_srv.h	(revision b3eeae586ec8b5fd5a43327f136f78e7ef242102)
+++ uspace/lib/dispcfg/include/dispcfg_srv.h	(revision c0757e1f444227a4a7447e0004af74bd7026104d)
@@ -56,4 +56,5 @@
 	errno_t (*dev_assign)(void *, sysarg_t, sysarg_t);
 	errno_t (*dev_unassign)(void *, sysarg_t);
+	errno_t (*get_asgn_dev_list)(void *, sysarg_t, dispcfg_dev_list_t **);
 	errno_t (*get_event)(void *, dispcfg_ev_t *);
 };
Index: uspace/lib/dispcfg/include/ipc/dispcfg.h
===================================================================
--- uspace/lib/dispcfg/include/ipc/dispcfg.h	(revision b3eeae586ec8b5fd5a43327f136f78e7ef242102)
+++ uspace/lib/dispcfg/include/ipc/dispcfg.h	(revision c0757e1f444227a4a7447e0004af74bd7026104d)
@@ -46,4 +46,5 @@
 	DISPCFG_DEV_ASSIGN,
 	DISPCFG_DEV_UNASSIGN,
+	DISPCFG_GET_ASGN_DEV_LIST,
 	DISPCFG_GET_EVENT,
 } dispcfg_request_t;
Index: uspace/lib/dispcfg/include/types/dispcfg.h
===================================================================
--- uspace/lib/dispcfg/include/types/dispcfg.h	(revision b3eeae586ec8b5fd5a43327f136f78e7ef242102)
+++ uspace/lib/dispcfg/include/types/dispcfg.h	(revision c0757e1f444227a4a7447e0004af74bd7026104d)
@@ -85,4 +85,12 @@
 } dispcfg_seat_info_t;
 
+/** Assigned device list */
+typedef struct {
+	/** Number of devices */
+	size_t ndevs;
+	/** ID for each device */
+	sysarg_t *devs;
+} dispcfg_dev_list_t;
+
 #endif
 
Index: uspace/lib/dispcfg/src/dispcfg.c
===================================================================
--- uspace/lib/dispcfg/src/dispcfg.c	(revision b3eeae586ec8b5fd5a43327f136f78e7ef242102)
+++ uspace/lib/dispcfg/src/dispcfg.c	(revision c0757e1f444227a4a7447e0004af74bd7026104d)
@@ -206,5 +206,5 @@
 /** Free seat list.
  *
- * @param list Display configuration list
+ * @param list Seat list
  */
 void dispcfg_free_seat_list(dispcfg_seat_list_t *list)
@@ -277,5 +277,5 @@
 /** Free seat information.
  *
- * @param info Display configuration information
+ * @param info Seat information
  */
 void dispcfg_free_seat_info(dispcfg_seat_info_t *info)
@@ -378,4 +378,73 @@
 	async_exchange_end(exch);
 	return rc;
+}
+
+/** Get list of devices assigned to a seat.
+ *
+ * @param dispcfg Display configuration
+ * @param seat_id Seat ID
+ * @param rlist Place to store pointer to new device list structure
+ * @return EOK on success or an error code
+ */
+errno_t dispcfg_get_asgn_dev_list(dispcfg_t *dispcfg, sysarg_t seat_id,
+    dispcfg_dev_list_t **rlist)
+{
+	async_exch_t *exch;
+	aid_t req;
+	ipc_call_t answer;
+	dispcfg_dev_list_t *list;
+	sysarg_t ndevs;
+	sysarg_t *devs;
+	errno_t rc;
+
+	exch = async_exchange_begin(dispcfg->sess);
+	req = async_send_1(exch, DISPCFG_GET_ASGN_DEV_LIST, seat_id, &answer);
+
+	/* Receive device list length */
+	rc = async_data_read_start(exch, &ndevs, sizeof (ndevs));
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		async_wait_for(req, &rc);
+		return rc;
+	}
+
+	devs = calloc(ndevs, sizeof(sysarg_t));
+	if (devs == NULL) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return ENOMEM;
+	}
+
+	/* Receive device list */
+	rc = async_data_read_start(exch, devs, ndevs * sizeof (sysarg_t));
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
+	async_wait_for(req, &rc);
+	if (rc != EOK)
+		return rc;
+
+	list = calloc(1, sizeof(dispcfg_dev_list_t));
+	if (list == NULL)
+		return ENOMEM;
+
+	list->ndevs = ndevs;
+	list->devs = devs;
+	*rlist = list;
+	return EOK;
+}
+
+/** Free device list.
+ *
+ * @param list Device list
+ */
+void dispcfg_free_dev_list(dispcfg_dev_list_t *list)
+{
+	free(list->devs);
+	free(list);
 }
 
Index: uspace/lib/dispcfg/src/dispcfg_srv.c
===================================================================
--- uspace/lib/dispcfg/src/dispcfg_srv.c	(revision b3eeae586ec8b5fd5a43327f136f78e7ef242102)
+++ uspace/lib/dispcfg/src/dispcfg_srv.c	(revision c0757e1f444227a4a7447e0004af74bd7026104d)
@@ -293,4 +293,77 @@
 }
 
+static void dispcfg_get_asgn_dev_list_srv(dispcfg_srv_t *srv, ipc_call_t *icall)
+{
+	sysarg_t seat_id;
+	ipc_call_t call;
+	dispcfg_dev_list_t *list = NULL;
+	size_t size;
+	errno_t rc;
+
+	seat_id = ipc_get_arg1(icall);
+
+	if (srv->ops->get_asgn_dev_list == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	rc = srv->ops->get_asgn_dev_list(srv->arg, seat_id, &list);
+	if (rc != EOK) {
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	/* Send list size */
+
+	if (!async_data_read_receive(&call, &size)) {
+		dispcfg_free_dev_list(list);
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(list->ndevs)) {
+		dispcfg_free_dev_list(list);
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = async_data_read_finalize(&call, &list->ndevs, size);
+	if (rc != EOK) {
+		dispcfg_free_dev_list(list);
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	/* Send device list */
+
+	if (!async_data_read_receive(&call, &size)) {
+		dispcfg_free_dev_list(list);
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if (size != list->ndevs * sizeof(sysarg_t)) {
+		dispcfg_free_dev_list(list);
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = async_data_read_finalize(&call, list->devs, size);
+	if (rc != EOK) {
+		dispcfg_free_dev_list(list);
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	async_answer_0(icall, EOK);
+	dispcfg_free_dev_list(list);
+}
+
 static void dispcfg_get_event_srv(dispcfg_srv_t *srv, ipc_call_t *icall)
 {
@@ -372,4 +445,7 @@
 		case DISPCFG_DEV_UNASSIGN:
 			dispcfg_dev_unassign_srv(srv, &call);
+			break;
+		case DISPCFG_GET_ASGN_DEV_LIST:
+			dispcfg_get_asgn_dev_list_srv(srv, &call);
 			break;
 		case DISPCFG_GET_EVENT:
Index: uspace/lib/dispcfg/test/dispcfg.c
===================================================================
--- uspace/lib/dispcfg/test/dispcfg.c	(revision b3eeae586ec8b5fd5a43327f136f78e7ef242102)
+++ uspace/lib/dispcfg/test/dispcfg.c	(revision c0757e1f444227a4a7447e0004af74bd7026104d)
@@ -52,4 +52,5 @@
 static errno_t test_dev_assign(void *, sysarg_t, sysarg_t);
 static errno_t test_dev_unassign(void *, sysarg_t);
+static errno_t test_get_asgn_dev_list(void *, sysarg_t, dispcfg_dev_list_t **);
 static errno_t test_get_event(void *, dispcfg_ev_t *);
 
@@ -64,4 +65,5 @@
 	.dev_assign = test_dev_assign,
 	.dev_unassign = test_dev_unassign,
+	.get_asgn_dev_list = test_get_asgn_dev_list,
 	.get_event = test_get_event
 };
@@ -102,4 +104,8 @@
 	bool dev_unassign_called;
 	sysarg_t dev_unassign_svc_id;
+
+	bool get_asgn_dev_list_called;
+	sysarg_t get_asgn_dev_list_seat_id;
+	dispcfg_dev_list_t *get_asgn_dev_list_rlist;
 
 	bool get_event_called;
@@ -604,4 +610,90 @@
 }
 
+/** dispcfg_get_asgn_dev_list() with server returning error response works */
+PCUT_TEST(get_asgn_dev_list_failure)
+{
+	errno_t rc;
+	service_id_t sid;
+	dispcfg_t *dispcfg = NULL;
+	dispcfg_dev_list_t *list;
+	sysarg_t seat_id;
+	test_response_t resp;
+
+	async_set_fallback_port_handler(test_dispcfg_conn, &resp);
+
+	// FIXME This causes this test to be non-reentrant!
+	rc = loc_server_register(test_dispcfg_server);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = loc_service_register(test_dispcfg_svc, &sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = dispcfg_open(test_dispcfg_svc, NULL, NULL, &dispcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(dispcfg);
+
+	resp.rc = ENOMEM;
+	resp.get_asgn_dev_list_called = false;
+	seat_id = 42;
+
+	rc = dispcfg_get_asgn_dev_list(dispcfg, seat_id, &list);
+	PCUT_ASSERT_TRUE(resp.get_asgn_dev_list_called);
+	PCUT_ASSERT_INT_EQUALS(seat_id, resp.get_asgn_dev_list_seat_id);
+	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
+
+	dispcfg_close(dispcfg);
+	rc = loc_service_unregister(sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+}
+
+/** dispcfg_get_asgn_dev_list() with server returning success response works */
+PCUT_TEST(get_asgn_dev_list_success)
+{
+	errno_t rc;
+	service_id_t sid;
+	dispcfg_t *dispcfg = NULL;
+	dispcfg_dev_list_t *list;
+	sysarg_t seat_id;
+	test_response_t resp;
+
+	async_set_fallback_port_handler(test_dispcfg_conn, &resp);
+
+	// FIXME This causes this test to be non-reentrant!
+	rc = loc_server_register(test_dispcfg_server);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = loc_service_register(test_dispcfg_svc, &sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = dispcfg_open(test_dispcfg_svc, NULL, NULL, &dispcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(dispcfg);
+
+	resp.rc = EOK;
+	resp.get_asgn_dev_list_called = false;
+	resp.get_asgn_dev_list_rlist = calloc(1, sizeof(dispcfg_dev_list_t));
+	PCUT_ASSERT_NOT_NULL(resp.get_asgn_dev_list_rlist);
+	resp.get_asgn_dev_list_rlist->ndevs = 2;
+	resp.get_asgn_dev_list_rlist->devs = calloc(2, sizeof(sysarg_t));
+	PCUT_ASSERT_NOT_NULL(resp.get_asgn_dev_list_rlist->devs);
+	resp.get_asgn_dev_list_rlist->devs[0] = 11;
+	resp.get_asgn_dev_list_rlist->devs[1] = 12;
+	seat_id = 42;
+
+	rc = dispcfg_get_asgn_dev_list(dispcfg, seat_id, &list);
+	PCUT_ASSERT_TRUE(resp.get_asgn_dev_list_called);
+	PCUT_ASSERT_INT_EQUALS(seat_id, resp.get_asgn_dev_list_seat_id);
+	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
+
+	PCUT_ASSERT_INT_EQUALS(2, list->ndevs);
+	PCUT_ASSERT_INT_EQUALS(11, list->devs[0]);
+	PCUT_ASSERT_INT_EQUALS(12, list->devs[1]);
+
+	dispcfg_free_dev_list(list);
+	dispcfg_close(dispcfg);
+	rc = loc_service_unregister(sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+}
+
 /** Window added event can be delivered from server to client callback function */
 PCUT_TEST(seat_added_deliver)
@@ -808,4 +900,19 @@
 }
 
+static errno_t test_get_asgn_dev_list(void *arg, sysarg_t seat_id,
+    dispcfg_dev_list_t **rlist)
+{
+	test_response_t *resp = (test_response_t *) arg;
+
+	resp->get_asgn_dev_list_called = true;
+	resp->get_asgn_dev_list_seat_id = seat_id;
+
+	if (resp->rc != EOK)
+		return resp->rc;
+
+	*rlist = resp->get_asgn_dev_list_rlist;
+	return EOK;
+}
+
 static errno_t test_get_event(void *arg, dispcfg_ev_t *event)
 {
