Index: uspace/app/hrctl/hrctl.c
===================================================================
--- uspace/app/hrctl/hrctl.c	(revision 680e8c87feb0239e956482146d9d455038b8c571)
+++ uspace/app/hrctl/hrctl.c	(revision 68e357eabc38844f16a69c9fd002cdfc4f785db0)
@@ -82,26 +82,17 @@
 }
 
-static errno_t get_dev_svc_ids(int argc, char **argv, int optind, int dev_no,
-    service_id_t **rdevs)
+static errno_t fill_config_devs(int argc, char **argv, int optind,
+    hr_config_t *cfg)
 {
 	errno_t rc;
-	int i;
-	size_t k;
-	service_id_t *devs;
-
-	devs = calloc(dev_no, sizeof(service_id_t));
-	if (devs == NULL)
-		return ENOMEM;
-
-	for (i = optind, k = 0; i < argc; i++, k++) {
-		rc = loc_service_get_id(argv[i], &devs[k], 0);
+	size_t i;
+
+	for (i = 0; i < cfg->dev_no; i++) {
+		rc = loc_service_get_id(argv[optind++], &cfg->devs[i], 0);
 		if (rc != EOK) {
 			printf("hrctl: error resolving device \"%s\"\n", argv[i]);
-			free(devs);
 			return EINVAL;
 		}
 	}
-
-	*rdevs = devs;
 
 	return EOK;
@@ -111,15 +102,16 @@
 {
 	errno_t rc;
-	int retval, c, dev_no;
+	int retval, c;
 	bool create, assemble;
-	char *name = NULL;
-	service_id_t *devs = NULL;
 	hr_t *hr;
-	hr_config_t hr_config;
-	hr_level_t level;
+	hr_config_t *cfg;
+
+	cfg = calloc(1, sizeof(hr_config_t));
+	if (cfg == NULL)
+		return 1;
 
 	retval = 0;
-	level = hr_l_empty;
-	dev_no = 0;
+	cfg->level = hr_l_empty;
+	cfg->dev_no = 0;
 	create = assemble = false;
 
@@ -143,44 +135,56 @@
 			return 0;
 		case 'a':
-			name = optarg;
+			if (str_size(optarg) > 31) {
+				printf("hrctl: device name longer than 31 bytes\n");
+				return 1;
+			}
+			str_cpy(cfg->devname, 32, optarg);
 			assemble = true;
 			break;
 		case 'c':
-			name = optarg;
+			if (str_size(optarg) > 31) {
+				printf("hrctl: device name longer than 31 bytes\n");
+				return 1;
+			}
+			str_cpy(cfg->devname, 32, optarg);
 			create = true;
 			break;
 		case 'l':
-			if (level != hr_l_empty)
+			if (cfg->level != hr_l_empty)
 				goto bad;
 			if (str_cmp(optarg, "linear") == 0)
-				level = hr_l_linear;
+				cfg->level = hr_l_linear;
 			else
-				level = strtol(optarg, NULL, 10);
+				cfg->level = strtol(optarg, NULL, 10);
 			break;
 		case '0':
-			if (level != hr_l_empty)
-				goto bad;
-			level = hr_l_0;
+			if (cfg->level != hr_l_empty)
+				goto bad;
+			cfg->level = hr_l_0;
 			break;
 		case '1':
-			if (level != hr_l_empty)
-				goto bad;
-			level = hr_l_1;
+			if (cfg->level != hr_l_empty)
+				goto bad;
+			cfg->level = hr_l_1;
 			break;
 		case '5':
-			if (level != hr_l_empty)
-				goto bad;
-			level = hr_l_5;
+			if (cfg->level != hr_l_empty)
+				goto bad;
+			cfg->level = hr_l_5;
 			break;
 		case 'L':
-			if (level != hr_l_empty)
-				goto bad;
-			level = hr_l_linear;
+			if (cfg->level != hr_l_empty)
+				goto bad;
+			cfg->level = hr_l_linear;
 			break;
 		case 'n':
-			dev_no = strtol(optarg, NULL, 10);
-			if (dev_no + optind != argc)
-				goto bad;
-			rc = get_dev_svc_ids(argc, argv, optind, dev_no, &devs);
+			cfg->dev_no = strtol(optarg, NULL, 10);
+			if ((int) cfg->dev_no + optind != argc)
+				goto bad;
+			if (cfg->dev_no > HR_MAXDEVS) {
+				printf("hrctl: too many devices\n");
+				return 1;
+			}
+			rc = fill_config_devs(argc, argv, optind, cfg);
 			if (rc != EOK)
 				return 1;
@@ -191,15 +195,9 @@
 	if ((create && assemble) ||
 	    (!create && !assemble) ||
-	    (create && level == hr_l_empty) ||
-	    (assemble && level != hr_l_empty) ||
-	    (dev_no == 0)) {
-		free(devs);
+	    (create && cfg->level == hr_l_empty) ||
+	    (assemble && cfg->level != hr_l_empty) ||
+	    (cfg->dev_no == 0)) {
 		goto bad;
 	}
-
-	hr_config.level = level;
-	hr_config.dev_no = dev_no;
-	hr_config.name = name;
-	hr_config.devs = devs;
 
 	rc = hr_sess_init(&hr);
@@ -211,5 +209,5 @@
 
 	if (create) {
-		rc = hr_create(hr, &hr_config);
+		rc = hr_create(hr, cfg);
 		printf("hrctl: hr_create() rc: %s\n", str_error(rc));
 	} else if (assemble) {
@@ -218,8 +216,9 @@
 
 end:
-	free(devs);
+	free(cfg);
 	hr_sess_destroy(hr);
 	return retval;
 bad:
+	free(cfg);
 	printf("hrctl: bad usage, try hrctl --help\n");
 	return 1;
Index: uspace/lib/device/include/hr.h
===================================================================
--- uspace/lib/device/include/hr.h	(revision 680e8c87feb0239e956482146d9d455038b8c571)
+++ uspace/lib/device/include/hr.h	(revision 68e357eabc38844f16a69c9fd002cdfc4f785db0)
@@ -41,4 +41,7 @@
 #include <loc.h>
 
+/* for now */
+#define HR_MAXDEVS 4
+
 typedef struct hr {
 	async_sess_t *sess;
@@ -54,6 +57,6 @@
 
 typedef struct hr_config {
-	char *name;
-	service_id_t *devs;
+	char devname[32];
+	service_id_t devs[HR_MAXDEVS];
 	size_t dev_no;
 	hr_level_t level;
Index: uspace/lib/device/src/hr.c
===================================================================
--- uspace/lib/device/src/hr.c	(revision 680e8c87feb0239e956482146d9d455038b8c571)
+++ uspace/lib/device/src/hr.c	(revision 68e357eabc38844f16a69c9fd002cdfc4f785db0)
@@ -94,20 +94,10 @@
 
 	exch = async_exchange_begin(hr->sess);
-	if (exch == NULL) {
+	if (exch == NULL)
 		return EINVAL;
-	}
 
-	req = async_send_1(exch, HR_CREATE, hr_config->level, NULL);
+	req = async_send_0(exch, HR_CREATE, NULL);
 
-	rc = async_data_write_start(exch, hr_config->name,
-	    str_size(hr_config->name));
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return rc;
-	}
-
-	rc = async_data_write_start(exch, hr_config->devs,
-	    sizeof(service_id_t) * hr_config->dev_no);
+	rc = async_data_write_start(exch, hr_config, sizeof(hr_config_t));
 	if (rc != EOK) {
 		async_exchange_end(exch);
Index: uspace/srv/bd/hr/hr.c
===================================================================
--- uspace/srv/bd/hr/hr.c	(revision 680e8c87feb0239e956482146d9d455038b8c571)
+++ uspace/srv/bd/hr/hr.c	(revision 68e357eabc38844f16a69c9fd002cdfc4f785db0)
@@ -46,4 +46,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <str.h>
 #include <str_error.h>
 
@@ -64,41 +65,45 @@
 	errno_t rc;
 	size_t size;
-	hr_config_t *hr_config;
-
-	hr_config = calloc(1, sizeof(hr_config_t));
-	if (hr_config == NULL) {
+	hr_config_t *cfg;
+	hr_volume_t *new_volume;
+	ipc_call_t call;
+
+	if (!async_data_write_receive(&call, &size)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(hr_config_t)) {
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	cfg = calloc(1, sizeof(hr_config_t));
+	if (cfg == NULL) {
+		async_answer_0(&call, ENOMEM);
 		async_answer_0(icall, ENOMEM);
 		return;
 	}
 
-	hr_config->level = ipc_get_arg1(icall);
-
-	rc = async_data_write_accept((void **) &hr_config->name, true, 0, 0, 0,
-	    NULL);
-	if (rc != EOK) {
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	rc = async_data_write_accept((void **) &hr_config->devs, false,
-	    sizeof(service_id_t), 0, 0, &size);
-	if (rc != EOK) {
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	hr_config->dev_no = size / sizeof(service_id_t);
-
-	hr_volume_t *new_volume = calloc(1, sizeof(hr_volume_t));
+	rc = async_data_write_finalize(&call, cfg, size);
+	if (rc != EOK) {
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+	}
+
+	new_volume = calloc(1, sizeof(hr_volume_t));
 	if (new_volume == NULL) {
 		rc = ENOMEM;
 		goto end;
 	}
-	new_volume->devname = hr_config->name;
-	new_volume->level = hr_config->level;
-	new_volume->dev_no = hr_config->dev_no;
-	new_volume->devs = hr_config->devs;
-
-	switch (hr_config->level) {
+
+	str_cpy(new_volume->devname, 32, cfg->devname);
+	memcpy(new_volume->devs, cfg->devs, sizeof(service_id_t) * HR_MAXDEVS);
+	new_volume->level = cfg->level;
+	new_volume->dev_no = cfg->dev_no;
+
+	switch (new_volume->level) {
 	case hr_l_1:
 		new_volume->hr_ops.create = hr_raid1_create;
@@ -115,6 +120,7 @@
 
 	rc = new_volume->hr_ops.create(new_volume);
-	if (rc != EOK)
+	if (rc != EOK) {
 		goto end;
+	}
 
 	fibril_mutex_lock(&hr_volumes_lock);
@@ -126,5 +132,5 @@
 
 end:
-	free(hr_config);
+	free(cfg);
 	async_answer_0(icall, rc);
 }
Index: uspace/srv/bd/hr/var.h
===================================================================
--- uspace/srv/bd/hr/var.h	(revision 680e8c87feb0239e956482146d9d455038b8c571)
+++ uspace/srv/bd/hr/var.h	(revision 68e357eabc38844f16a69c9fd002cdfc4f785db0)
@@ -53,6 +53,6 @@
 	bd_srvs_t hr_bds;
 	link_t lvolumes;
-	char *devname;
-	service_id_t *devs;
+	char devname[32];
+	service_id_t devs[HR_MAXDEVS];
 	uint64_t nblocks;
 	size_t bsize;
