Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision 239eea4167f0ebbd6c42050e2c252fd03a7f3c08)
+++ uspace/lib/usbdev/src/pipes.c	(revision 2f762a7c6e72f686c37eb21ceb35942d89b918e5)
@@ -68,6 +68,4 @@
 	usb_direction_t dir;
 	bool is_control;	// Only for checking purposes
-	void *buffer;
-	size_t buffer_size;
 
 	usbhc_iface_transfer_request_t req;
@@ -81,49 +79,4 @@
 static errno_t transfer_common(transfer_t *t)
 {
-	async_exch_t *exch = async_exchange_begin(t->pipe->bus_session);
-	if (!exch)
-		return ENOMEM;
-
-	t->req.dir = t->dir;
-	t->req.endpoint = t->pipe->desc.endpoint_no;
-
-	/* We support only aligned buffers for now. */
-	t->req.base = t->buffer;
-	t->req.offset = 0;
-	t->req.size = t->buffer_size;
-
-	const errno_t rc = usbhc_transfer(exch, &t->req, &t->transferred_size);
-
-	async_exchange_end(exch);
-
-	if (rc == ESTALL)
-		clear_self_endpoint_halt(t->pipe);
-
-	return rc;
-}
-
-/**
- * Compatibility wrapper for reads/writes without preallocated buffer.
- */
-static errno_t transfer_wrap_dma(transfer_t *t)
-{
-	void *orig_buffer = t->buffer;
-	t->buffer = usb_pipe_alloc_buffer(t->pipe, t->buffer_size);
-
-	if (t->dir == USB_DIRECTION_OUT)
-		memcpy(t->buffer, orig_buffer, t->buffer_size);
-
-	const errno_t err = transfer_common(t);
-
-	if (!err && t->dir == USB_DIRECTION_IN)
-		memcpy(orig_buffer, t->buffer, t->transferred_size);
-
-	usb_pipe_free_buffer(t->pipe, t->buffer);
-	t->buffer = orig_buffer;
-	return err;
-}
-
-static errno_t transfer_check(const transfer_t *t)
-{
 	if (!t->pipe)
 		return EBADMEM;
@@ -131,9 +84,9 @@
 	/* Only control writes make sense without buffer */
 	if ((t->dir != USB_DIRECTION_OUT || !t->is_control)
-	    && (t->buffer == NULL || t->buffer_size == 0))
+	    && (t->req.base == NULL || t->req.size == 0))
 		return EINVAL;
 
 	/* Nonzero size requires buffer */
-	if (t->buffer == NULL && t->buffer_size != 0)
+	if (t->req.base == NULL && t->req.size != 0)
 		return EINVAL;
 
@@ -147,5 +100,50 @@
 		return EBADF;
 
-	return EOK;
+	async_exch_t *exch = async_exchange_begin(t->pipe->bus_session);
+	if (!exch)
+		return ENOMEM;
+
+	t->req.dir = t->dir;
+	t->req.endpoint = t->pipe->desc.endpoint_no;
+
+	const errno_t rc = usbhc_transfer(exch, &t->req, &t->transferred_size);
+
+	async_exchange_end(exch);
+
+	if (rc == ESTALL)
+		clear_self_endpoint_halt(t->pipe);
+
+	return rc;
+}
+
+/**
+ * Setup the transfer request inside transfer according to dma buffer provided.
+ */
+static void setup_dma_buffer(transfer_t *t, void *base, void *ptr, size_t size)
+{
+	t->req.base = base;
+	t->req.offset = ptr - base;
+	t->req.size = size;
+	t->req.buffer_policy = t->pipe->desc.transfer_buffer_policy;
+}
+
+/**
+ * Compatibility wrapper for reads/writes without preallocated buffer.
+ */
+static errno_t transfer_wrap_dma(transfer_t *t, void *buf, size_t size)
+{
+	void *dma_buf = usb_pipe_alloc_buffer(t->pipe, size);
+	setup_dma_buffer(t, dma_buf, dma_buf, size);
+
+	if (t->dir == USB_DIRECTION_OUT)
+		memcpy(dma_buf, buf, size);
+
+	const errno_t err = transfer_common(t);
+
+	if (!err && t->dir == USB_DIRECTION_IN)
+		memcpy(buf, dma_buf, t->transferred_size);
+
+	usb_pipe_free_buffer(t->pipe, dma_buf);
+	return err;
 }
 
@@ -181,15 +179,10 @@
 		.dir = USB_DIRECTION_IN,
 		.is_control = true,
-		.buffer = buffer,
-		.buffer_size = buffer_size
-	};
-
-	if ((err = transfer_check(&transfer)))
-		return err;
+	};
 
 	if ((err = prepare_control(&transfer, setup_buffer, setup_buffer_size)))
 		return err;
 
-	if ((err = transfer_wrap_dma(&transfer)))
+	if ((err = transfer_wrap_dma(&transfer, buffer, buffer_size)))
 		return err;
 
@@ -221,15 +214,10 @@
 		.dir = USB_DIRECTION_OUT,
 		.is_control = true,
-		.buffer = (void *) buffer,
-		.buffer_size = buffer_size
-	};
-
-	if ((err = transfer_check(&transfer)))
-		return err;
+	};
 
 	if ((err = prepare_control(&transfer, setup_buffer, setup_buffer_size)))
 		return err;
 
-	return transfer_wrap_dma(&transfer);
+	return transfer_wrap_dma(&transfer, (void *) buffer, buffer_size);
 }
 
@@ -273,12 +261,7 @@
 		.pipe = pipe,
 		.dir = USB_DIRECTION_IN,
-		.buffer = buffer,
-		.buffer_size = size,
-	};
-
-	if ((err = transfer_check(&transfer)))
-		return err;
-
-	if ((err = transfer_wrap_dma(&transfer)))
+	};
+
+	if ((err = transfer_wrap_dma(&transfer, buffer, size)))
 		return err;
 
@@ -299,19 +282,10 @@
 {
 	assert(pipe);
-	errno_t err;
 	transfer_t transfer = {
 		.pipe = pipe,
 		.dir = USB_DIRECTION_OUT,
-		.buffer = (void *) buffer,
-		.buffer_size = size
-	};
-
-	if ((err = transfer_check(&transfer)))
-		return err;
-
-	if ((err = transfer_wrap_dma(&transfer)))
-		return err;
-
-	return EOK;
+	};
+
+	return transfer_wrap_dma(&transfer, (void *) buffer, size);
 }
 
@@ -326,5 +300,5 @@
  * @return Error code.
  */
-errno_t usb_pipe_read_dma(usb_pipe_t *pipe, void *buffer, size_t size,
+errno_t usb_pipe_read_dma(usb_pipe_t *pipe, void *base, void *ptr, size_t size,
     size_t *size_transferred)
 {
@@ -334,10 +308,7 @@
 		.pipe = pipe,
 		.dir = USB_DIRECTION_IN,
-		.buffer = buffer,
-		.buffer_size = size
-	};
-
-	if ((err = transfer_check(&transfer)))
-		return err;
+	};
+
+	setup_dma_buffer(&transfer, base, ptr, size);
 
 	if ((err = transfer_common(&transfer)))
@@ -359,22 +330,15 @@
  * @return Error code.
  */
-errno_t usb_pipe_write_dma(usb_pipe_t *pipe, void *buffer, size_t size)
-{
-	assert(pipe);
-	errno_t err;
+errno_t usb_pipe_write_dma(usb_pipe_t *pipe, void *base, void* ptr,  size_t size)
+{
+	assert(pipe);
 	transfer_t transfer = {
 		.pipe = pipe,
 		.dir = USB_DIRECTION_OUT,
-		.buffer = buffer,
-		.buffer_size = size
-	};
-
-	if ((err = transfer_check(&transfer)))
-		return err;
-
-	if ((err = transfer_common(&transfer)))
-		return err;
-
-	return EOK;
+	};
+
+	setup_dma_buffer(&transfer, base, ptr, size);
+
+	return transfer_common(&transfer);
 }
 
