Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision d345ce2f2396010ea2fd5ad90e85202da83d5197)
+++ uspace/lib/usbdev/src/pipes.c	(revision 5ef3afdf4e5aa4f84ed956962e5facd43397a2aa)
@@ -83,10 +83,9 @@
 
 	/* Only control writes make sense without buffer */
-	if ((t->dir != USB_DIRECTION_OUT || !t->is_control)
-	    && (t->req.base == NULL || t->req.size == 0))
+	if ((t->dir != USB_DIRECTION_OUT || !t->is_control) && t->req.size == 0)
 		return EINVAL;
 
 	/* Nonzero size requires buffer */
-	if (t->req.base == NULL && t->req.size != 0)
+	if (!dma_buffer_is_set(&t->req.buffer) && t->req.size != 0)
 		return EINVAL;
 
@@ -119,11 +118,14 @@
 /**
  * Setup the transfer request inside transfer according to dma buffer provided.
+ *
+ * TODO: The buffer could have been allocated as a more strict one. Currently,
+ * we assume that the policy is just the requested one.
  */
 static void setup_dma_buffer(transfer_t *t, void *base, void *ptr, size_t size)
 {
-	t->req.base = base;
+	t->req.buffer.virt = base;
+	t->req.buffer.policy = t->pipe->desc.transfer_buffer_policy;
 	t->req.offset = ptr - base;
 	t->req.size = size;
-	t->req.buffer_policy = t->pipe->desc.transfer_buffer_policy;
 }
 
@@ -133,4 +135,9 @@
 static errno_t transfer_wrap_dma(transfer_t *t, void *buf, size_t size)
 {
+	if (size == 0) {
+		setup_dma_buffer(t, NULL, NULL, 0);
+		return transfer_common(t);
+	}
+
 	void *dma_buf = usb_pipe_alloc_buffer(t->pipe, size);
 	setup_dma_buffer(t, dma_buf, dma_buf, size);
@@ -364,4 +371,5 @@
 	.direction = USB_DIRECTION_BOTH,
 	.max_transfer_size = CTRL_PIPE_MIN_PACKET_SIZE,
+	.transfer_buffer_policy = DMA_POLICY_STRICT,
 };
 
