Index: uspace/app/hrctl/hrctl.c
===================================================================
--- uspace/app/hrctl/hrctl.c	(revision 2b8901bea57b835487c649506b7d6acc099dd9b3)
+++ uspace/app/hrctl/hrctl.c	(revision c99737458ece83464a11711065db030e166971c0)
@@ -359,8 +359,8 @@
 
 	if (create) {
-		rc = hr_create(hr, cfg);
+		rc = hr_create(hr, cfg, false);
 		printf("hrctl: hr_create() rc: %s\n", str_error(rc));
 	} else if (assemble) {
-		rc = hr_assemble(hr, cfg);
+		rc = hr_create(hr, cfg, true);
 		printf("hrctl: hr_assemble() rc: %s\n", str_error(rc));
 	}
Index: uspace/lib/device/include/hr.h
===================================================================
--- uspace/lib/device/include/hr.h	(revision 2b8901bea57b835487c649506b7d6acc099dd9b3)
+++ uspace/lib/device/include/hr.h	(revision c99737458ece83464a11711065db030e166971c0)
@@ -82,6 +82,5 @@
 extern void hr_sess_destroy(hr_t *);
 
-extern errno_t hr_create(hr_t *, hr_config_t *);
-extern errno_t hr_assemble(hr_t *, hr_config_t *);
+extern errno_t hr_create(hr_t *, hr_config_t *, bool);
 extern errno_t hr_stop(const char *);
 extern errno_t hr_print_status(void);
Index: uspace/lib/device/src/hr.c
===================================================================
--- uspace/lib/device/src/hr.c	(revision 2b8901bea57b835487c649506b7d6acc099dd9b3)
+++ uspace/lib/device/src/hr.c	(revision c99737458ece83464a11711065db030e166971c0)
@@ -87,5 +87,5 @@
 }
 
-errno_t hr_create(hr_t *hr, hr_config_t *hr_config)
+errno_t hr_create(hr_t *hr, hr_config_t *hr_config, bool assemble)
 {
 	errno_t rc, retval;
@@ -97,32 +97,5 @@
 		return EINVAL;
 
-	req = async_send_0(exch, HR_CREATE, NULL);
-
-	rc = async_data_write_start(exch, hr_config, sizeof(hr_config_t));
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return rc;
-	}
-
-	async_exchange_end(exch);
-	async_wait_for(req, &retval);
-	if (retval != EOK)
-		return retval;
-
-	return EOK;
-}
-
-errno_t hr_assemble(hr_t *hr, hr_config_t *hr_config)
-{
-	errno_t rc, retval;
-	async_exch_t *exch;
-	aid_t req;
-
-	exch = async_exchange_begin(hr->sess);
-	if (exch == NULL)
-		return EINVAL;
-
-	req = async_send_0(exch, HR_ASSEMBLE, NULL);
+	req = async_send_0(exch, assemble ? HR_ASSEMBLE : HR_CREATE, NULL);
 
 	rc = async_data_write_start(exch, hr_config, sizeof(hr_config_t));
Index: uspace/srv/bd/hr/hr.c
===================================================================
--- uspace/srv/bd/hr/hr.c	(revision 2b8901bea57b835487c649506b7d6acc099dd9b3)
+++ uspace/srv/bd/hr/hr.c	(revision c99737458ece83464a11711065db030e166971c0)
@@ -98,5 +98,5 @@
 }
 
-static void hr_create_srv(ipc_call_t *icall)
+static void hr_create_srv(ipc_call_t *icall, bool assemble)
 {
 	log_msg(LOG_DEFAULT, LVL_NOTE, "hr_create_srv()");
@@ -147,4 +147,11 @@
 	new_volume->dev_no = cfg->dev_no;
 
+	if (assemble) {
+		if (cfg->level != hr_l_empty)
+			log_msg(LOG_DEFAULT, LVL_WARN,
+			    "level manually set when assembling, ingoring");
+		new_volume->level = hr_l_empty;
+	}
+
 	rc = hr_init_devs(new_volume);
 	if (rc != EOK) {
@@ -152,4 +159,15 @@
 		async_answer_0(icall, rc);
 		return;
+	}
+
+	if (assemble) {
+		/* just bsize needed for reading metadata later */
+		rc = hr_check_devs(new_volume, NULL, &new_volume->bsize);
+		if (rc != EOK)
+			goto error;
+
+		rc = hr_get_vol_from_meta(cfg, new_volume);
+		if (rc != EOK)
+			goto error;
 	}
 
@@ -178,11 +196,13 @@
 	}
 
-	new_volume->hr_ops.init(new_volume);
-	if (rc != EOK)
-		goto error;
-
-	rc = hr_write_meta_to_vol(new_volume);
-	if (rc != EOK)
-		goto error;
+	if (!assemble) {
+		new_volume->hr_ops.init(new_volume);
+		if (rc != EOK)
+			goto error;
+
+		rc = hr_write_meta_to_vol(new_volume);
+		if (rc != EOK)
+			goto error;
+	}
 
 	rc = new_volume->hr_ops.create(new_volume);
@@ -194,116 +214,13 @@
 	fibril_mutex_unlock(&hr_volumes_lock);
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "created volume \"%s\" (%" PRIun ")",
-	    new_volume->devname, new_volume->svc_id);
-
-	free(cfg);
-	async_answer_0(icall, rc);
-	return;
-error:
-	free(cfg);
-	hr_fini_devs(new_volume);
-	async_answer_0(icall, rc);
-}
-
-static void hr_assemble_srv(ipc_call_t *icall)
-{
-	log_msg(LOG_DEFAULT, LVL_NOTE, "hr_assemble_srv()");
-
-	errno_t rc;
-	size_t i, size;
-	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;
-	}
-
-	rc = async_data_write_finalize(&call, cfg, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	new_volume = calloc(1, sizeof(hr_volume_t));
-	if (new_volume == NULL) {
-		free(cfg);
-		async_answer_0(icall, ENOMEM);
-		return;
-	}
-
-	str_cpy(new_volume->devname, 32, cfg->devname);
-	for (i = 0; i < cfg->dev_no; i++)
-		new_volume->extents[i].svc_id = cfg->devs[i];
-	new_volume->dev_no = cfg->dev_no;
-
-	if (cfg->level != hr_l_empty)
-		log_msg(LOG_DEFAULT, LVL_WARN,
-		    "level manually set when assembling, ingoring");
-
-	new_volume->level = hr_l_empty;
-
-	rc = hr_init_devs(new_volume);
-	if (rc != EOK) {
-		free(cfg);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	/* just bsize needed for reading metadata later */
-	rc = hr_check_devs(new_volume, NULL, &new_volume->bsize);
-	if (rc != EOK)
-		goto error;
-
-	rc = hr_get_vol_from_meta(cfg, new_volume);
-	if (rc != EOK)
-		goto error;
-
-	switch (new_volume->level) {
-	case hr_l_1:
-		new_volume->hr_ops.create = hr_raid1_create;
-		break;
-	case hr_l_0:
-		new_volume->hr_ops.create = hr_raid0_create;
-		break;
-	case hr_l_4:
-		new_volume->hr_ops.create = hr_raid4_create;
-		break;
-	case hr_l_5:
-		new_volume->hr_ops.create = hr_raid5_create;
-		break;
-	default:
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "level %d not implemented yet", new_volume->level);
-		rc = EINVAL;
-		goto error;
-	}
-
-	rc = new_volume->hr_ops.create(new_volume);
-	if (rc != EOK)
-		goto error;
-
-	fibril_mutex_lock(&hr_volumes_lock);
-	list_append(&new_volume->lvolumes, &hr_volumes);
-	fibril_mutex_unlock(&hr_volumes_lock);
-
-	log_msg(LOG_DEFAULT, LVL_NOTE, "assembled volume \"%s\" (%" PRIun ")",
-	    new_volume->devname, new_volume->svc_id);
+	if (assemble) {
+		log_msg(LOG_DEFAULT, LVL_NOTE,
+		    "assembled volume \"%s\" (%" PRIun ")",
+		    new_volume->devname, new_volume->svc_id);
+	} else {
+		log_msg(LOG_DEFAULT, LVL_NOTE,
+		    "created volume \"%s\" (%" PRIun ")",
+		    new_volume->devname, new_volume->svc_id);
+	}
 
 	free(cfg);
@@ -424,8 +341,8 @@
 		switch (method) {
 		case HR_CREATE:
-			hr_create_srv(&call);
+			hr_create_srv(&call, false);
 			break;
 		case HR_ASSEMBLE:
-			hr_assemble_srv(&call);
+			hr_create_srv(&call, true);
 			break;
 		case HR_STOP:
