Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 97532207cccbbd72946d811fe8224a29ebdbdb70)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision 74d6e90077988a0b7d055819ba72db1778bf9bc5)
@@ -104,4 +104,35 @@
 } async_transaction_t;
 
+static void async_transaction_destroy(async_transaction_t *trans)
+{
+	if (trans == NULL) {
+		return;
+	}
+
+	if (trans->setup_packet != NULL) {
+		free(trans->setup_packet);
+	}
+	if (trans->buffer != NULL) {
+		free(trans->buffer);
+	}
+
+	free(trans);
+}
+
+static async_transaction_t *async_transaction_create(ipc_callid_t caller)
+{
+	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
+	if (trans == NULL) {
+		return NULL;
+	}
+
+	trans->caller = caller;
+	trans->buffer = NULL;
+	trans->setup_packet = NULL;
+	trans->size = 0;
+
+	return trans;
+}
+
 void remote_usbhc_get_address(device_t *device, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
@@ -136,5 +167,5 @@
 	if (trans->buffer == NULL) {
 		ipc_answer_0(callid, EINVAL);
-		free(trans);
+		async_transaction_destroy(trans);
 		return;
 	}
@@ -144,4 +175,5 @@
 	if (!async_data_read_receive(&cid, &accepted_size)) {
 		ipc_answer_0(callid, EINVAL);
+		async_transaction_destroy(trans);
 		return;
 	}
@@ -154,6 +186,5 @@
 	ipc_answer_1(callid, EOK, accepted_size);
 
-	free(trans->buffer);
-	free(trans);
+	async_transaction_destroy(trans);
 }
 
@@ -248,8 +279,7 @@
 	async_transaction_t *trans = (async_transaction_t *)arg;
 
-	// FIXME - answer according to outcome
 	ipc_answer_0(trans->caller, outcome);
 
-	free(trans);
+	async_transaction_destroy(trans);
 }
 
@@ -259,8 +289,12 @@
 	async_transaction_t *trans = (async_transaction_t *)arg;
 
-	// FIXME - answer according to outcome
-	ipc_answer_1(trans->caller, outcome, (sysarg_t)trans);
+	if (outcome != USB_OUTCOME_OK) {
+		ipc_answer_0(trans->caller, outcome);
+		async_transaction_destroy(trans);
+		return;
+	}
 
 	trans->size = actual_size;
+	ipc_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans);
 }
 
@@ -300,19 +334,22 @@
 	}
 
-	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
-	trans->caller = callid;
-	trans->buffer = buffer;
-	trans->setup_packet = NULL;
-	trans->size = len;
-
-	int rc = transfer_func(device, target, buffer, len,
-	    callback_out, trans);
-
-	if (rc != EOK) {
-		ipc_answer_0(callid, rc);
+	async_transaction_t *trans = async_transaction_create(callid);
+	if (trans == NULL) {
 		if (buffer != NULL) {
 			free(buffer);
 		}
-		free(trans);
+		ipc_answer_0(callid, ENOMEM);
+		return;
+	}
+
+	trans->buffer = buffer;
+	trans->size = len;
+
+	int rc = transfer_func(device, target, buffer, len,
+	    callback_out, trans);
+
+	if (rc != EOK) {
+		ipc_answer_0(callid, rc);
+		async_transaction_destroy(trans);
 	}
 }
@@ -340,8 +377,10 @@
 	};
 
-	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
-	trans->caller = callid;
+	async_transaction_t *trans = async_transaction_create(callid);
+	if (trans == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		return;
+	}
 	trans->buffer = malloc(len);
-	trans->setup_packet = NULL;
 	trans->size = len;
 
@@ -351,6 +390,5 @@
 	if (rc != EOK) {
 		ipc_answer_0(callid, rc);
-		free(trans->buffer);
-		free(trans);
+		async_transaction_destroy(trans);
 	}
 }
@@ -396,9 +434,9 @@
 	};
 
-	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
-	trans->caller = callid;
-	trans->buffer = NULL;
-	trans->setup_packet = NULL;
-	trans->size = 0;
+	async_transaction_t *trans = async_transaction_create(callid);
+	if (trans == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		return;
+	}
 
 	int rc;
@@ -419,7 +457,6 @@
 	if (rc != EOK) {
 		ipc_answer_0(callid, rc);
-		free(trans);
-	}
-	return;
+		async_transaction_destroy(trans);
+	}
 }
 
@@ -537,11 +574,16 @@
 	    1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len);
 	if (rc != EOK) {
+		ipc_answer_0(callid, rc);
 		free(setup_packet);
-		ipc_answer_0(callid, rc);
-		return;
-	}
-
-	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
-	trans->caller = callid;
+		return;
+	}
+
+	async_transaction_t *trans = async_transaction_create(callid);
+	if (trans == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		free(setup_packet);
+		free(data_buffer);
+		return;
+	}
 	trans->setup_packet = setup_packet;
 	trans->buffer = data_buffer;
@@ -555,7 +597,5 @@
 	if (rc != EOK) {
 		ipc_answer_0(callid, rc);
-		free(setup_packet);
-		free(data_buffer);
-		free(trans);
+		async_transaction_destroy(trans);
 	}
 }
@@ -591,9 +631,18 @@
 	}
 
-	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
-	trans->caller = callid;
+	async_transaction_t *trans = async_transaction_create(callid);
+	if (trans == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		free(setup_packet);
+		return;
+	}
 	trans->setup_packet = setup_packet;
+	trans->size = data_len;
 	trans->buffer = malloc(data_len);
-	trans->size = data_len;
+	if (trans->buffer == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		async_transaction_destroy(trans);
+		return;
+	}
 
 	rc = usb_iface->control_read(device, target,
@@ -604,7 +653,5 @@
 	if (rc != EOK) {
 		ipc_answer_0(callid, rc);
-		free(setup_packet);
-		free(trans->buffer);
-		free(trans);
+		async_transaction_destroy(trans);
 	}
 }
