Index: uspace/drv/bus/usb/ehci/ehci_batch.c
===================================================================
--- uspace/drv/bus/usb/ehci/ehci_batch.c	(revision 27b0ea0a00cc0299524227524d10e0207768f6d3)
+++ uspace/drv/bus/usb/ehci/ehci_batch.c	(revision 9e5b1621f4f41683f532e53cb098ad63a69b19a0)
@@ -42,5 +42,4 @@
 #include <usb/usb.h>
 #include <usb/debug.h>
-#include <usb/host/utils/malloc32.h>
 
 #include "ehci_batch.h"
@@ -62,11 +61,5 @@
 {
 	assert(ehci_batch);
-	if (ehci_batch->tds) {
-		for (size_t i = 0; i < ehci_batch->td_count; ++i) {
-			free32(ehci_batch->tds[i]);
-		}
-		free(ehci_batch->tds);
-	}
-	free32(ehci_batch->device_buffer);
+	dma_buffer_free(&ehci_batch->dma_buffer);
 	free(ehci_batch);
 	usb_log_debug2("Batch(%p): disposed", ehci_batch);
@@ -112,49 +105,37 @@
 	const size_t size = ehci_batch->base.buffer_size;
 
-	/* Mix setup stage and data together, we have enough space */
-        if (size + setup_size > 0) {
-		/* Use one buffer for setup and data stage */
-		ehci_batch->device_buffer = malloc32(size + setup_size);
-		if (!ehci_batch->device_buffer) {
+	/* Add TD left over by the previous transfer */
+	ehci_batch->qh = ehci_endpoint_get(ehci_batch->base.ep)->qh;
+
+	/* Determine number of TDs needed */
+	ehci_batch->td_count = (size + EHCI_TD_MAX_TRANSFER - 1)
+		/ EHCI_TD_MAX_TRANSFER;
+
+	/* Control transfer need Setup and Status stage */
+	if (ehci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL) {
+		ehci_batch->td_count += 2;
+	}
+
+	const size_t tds_size = ehci_batch->td_count * sizeof(td_t);
+
+	/* Mix setup stage, data and TDs together, we have enough space */
+	if (size + setup_size + tds_size > 0) {
+		if (dma_buffer_alloc(&ehci_batch->dma_buffer, tds_size + setup_size + size)) {
 			usb_log_error("Batch %p: Failed to allocate device "
 			    "buffer", ehci_batch);
 			return ENOMEM;
 		}
+		/* Clean TDs */
+		ehci_batch->tds = ehci_batch->dma_buffer.virt;
+		memset(ehci_batch->tds, 0, tds_size);
 		/* Copy setup data */
-                memcpy(ehci_batch->device_buffer, ehci_batch->base.setup.buffer,
-		    setup_size);
+		ehci_batch->setup_buffer = ehci_batch->dma_buffer.virt + tds_size;
+                memcpy(ehci_batch->setup_buffer, ehci_batch->base.setup.buffer, setup_size);
 		/* Copy generic data */
+		ehci_batch->data_buffer = ehci_batch->setup_buffer + setup_size;
 		if (ehci_batch->base.dir != USB_DIRECTION_IN)
-			memcpy(ehci_batch->device_buffer + setup_size,
-			    ehci_batch->base.buffer, ehci_batch->base.buffer_size);
-        }
-
-	/* Add TD left over by the previous transfer */
-	ehci_batch->qh = ehci_endpoint_get(ehci_batch->base.ep)->qh;
-
-	/* Determine number of TDs needed */
-	ehci_batch->td_count = (size + EHCI_TD_MAX_TRANSFER - 1)
-		/ EHCI_TD_MAX_TRANSFER;
-
-	/* Control transfer need Setup and Status stage */
-	if (ehci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL) {
-		ehci_batch->td_count += 2;
-	}
-
-	ehci_batch->tds = calloc(ehci_batch->td_count, sizeof(td_t*));
-	if (!ehci_batch->tds) {
-		usb_log_error("Batch %p: Failed to allocate EHCI transfer "
-		    "descriptors.", ehci_batch);
-		return ENOMEM;
-	}
-
-	for (unsigned i = 0; i < ehci_batch->td_count; ++i) {
-		ehci_batch->tds[i] = malloc32(sizeof(td_t));
-		if (!ehci_batch->tds[i]) {
-			usb_log_error("Batch %p: Failed to allocate TD %d.",
-			    ehci_batch, i);
-			return ENOMEM;
-		}
-		memset(ehci_batch->tds[i], 0, sizeof(td_t));
+			memcpy(ehci_batch->data_buffer,
+			    ehci_batch->base.buffer,
+			    ehci_batch->base.buffer_size);
 	}
 
@@ -203,11 +184,10 @@
 	/* Check all TDs */
 	for (size_t i = 0; i < ehci_batch->td_count; ++i) {
-		assert(ehci_batch->tds[i] != NULL);
 		usb_log_debug("Batch %p: TD %zu: %08x:%08x:%08x.",
 		    ehci_batch, i,
-		    ehci_batch->tds[i]->status, ehci_batch->tds[i]->next,
-		    ehci_batch->tds[i]->alternate);
-
-		ehci_batch->base.error = td_error(ehci_batch->tds[i]);
+		    ehci_batch->tds[i].status, ehci_batch->tds[i].next,
+		    ehci_batch->tds[i].alternate);
+
+		ehci_batch->base.error = td_error(&ehci_batch->tds[i]);
 		if (ehci_batch->base.error == EOK) {
 			/* If the TD got all its data through, it will report
@@ -224,9 +204,9 @@
 			 */
 			ehci_batch->base.transfered_size
-			    -= td_remain_size(ehci_batch->tds[i]);
+			    -= td_remain_size(&ehci_batch->tds[i]);
 		} else {
 			usb_log_debug("Batch %p found error TD(%zu):%08x (%d).",
 			    ehci_batch, i,
-			    ehci_batch->tds[i]->status,
+			    ehci_batch->tds[i].status,
 			    ehci_batch->base.error);
 			/* Clear possible ED HALT */
@@ -238,11 +218,7 @@
 	assert(ehci_batch->base.transfered_size <= ehci_batch->base.buffer_size);
 
-	const size_t setup_size = (ehci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL)
-		? USB_SETUP_PACKET_SIZE
-		: 0;
-
 	if (ehci_batch->base.dir == USB_DIRECTION_IN)
 		memcpy(ehci_batch->base.buffer,
-		    ehci_batch->device_buffer + setup_size,
+		    ehci_batch->data_buffer,
 		    ehci_batch->base.transfered_size);
 
@@ -263,5 +239,5 @@
 {
 	assert(ehci_batch);
-	qh_set_next_td(ehci_batch->qh, ehci_batch->tds[0]);
+	qh_set_next_td(ehci_batch->qh, dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[0]));
 }
 
@@ -281,7 +257,7 @@
 	assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT);
 
-	usb_log_debug2("Batch %p: Control QH(%"PRIxn"): "
+	usb_log_debug2("Batch %p: Control QH(%p): "
 	    "%08x:%08x:%08x:%08x:%08x:%08x", ehci_batch,
-	    addr_to_phys(ehci_batch->qh),
+	    ehci_batch->qh,
 	    ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap,
 	    ehci_batch->qh->status, ehci_batch->qh->current,
@@ -293,35 +269,35 @@
 
 	int toggle = 0;
-	const char* buffer = ehci_batch->device_buffer;
 	const usb_direction_t data_dir = dir;
 	const usb_direction_t status_dir = reverse_dir[dir];
 
 	/* Setup stage */
-	td_init(ehci_batch->tds[0], ehci_batch->tds[1], USB_DIRECTION_BOTH,
-	    buffer, USB_SETUP_PACKET_SIZE, toggle, false);
+	td_init(&ehci_batch->tds[0],
+	    dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[1]),
+	    dma_buffer_phys(&ehci_batch->dma_buffer, ehci_batch->setup_buffer),
+	    USB_DIRECTION_BOTH, USB_SETUP_PACKET_SIZE, toggle, false);
 	usb_log_debug2("Batch %p: Created CONTROL SETUP TD(%"PRIxn"): "
 	    "%08x:%08x:%08x", ehci_batch,
-	    addr_to_phys(ehci_batch->tds[0]),
-	    ehci_batch->tds[0]->status, ehci_batch->tds[0]->next,
-	    ehci_batch->tds[0]->alternate);
-	buffer += USB_SETUP_PACKET_SIZE;
+	    dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[0]),
+	    ehci_batch->tds[0].status, ehci_batch->tds[0].next,
+	    ehci_batch->tds[0].alternate);
 
 	/* Data stage */
-	size_t td_current = 1;
+	unsigned td_current = 1;
 	size_t remain_size = ehci_batch->base.buffer_size;
+	uintptr_t buffer = dma_buffer_phys(&ehci_batch->dma_buffer, ehci_batch->data_buffer);
 	while (remain_size > 0) {
-		const size_t transfer_size =
-		    min(remain_size, EHCI_TD_MAX_TRANSFER);
+		const size_t transfer_size = min(remain_size, EHCI_TD_MAX_TRANSFER);
 		toggle = 1 - toggle;
 
-		td_init(ehci_batch->tds[td_current],
-		    ehci_batch->tds[td_current + 1], data_dir, buffer,
-		    transfer_size, toggle, false);
+		td_init(&ehci_batch->tds[td_current],
+		    dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current + 1]),
+		    buffer, data_dir, transfer_size, toggle, false);
 		usb_log_debug2("Batch %p: Created CONTROL DATA TD(%"PRIxn"): "
 		    "%08x:%08x:%08x", ehci_batch,
-		    addr_to_phys(ehci_batch->tds[td_current]),
-		    ehci_batch->tds[td_current]->status,
-		    ehci_batch->tds[td_current]->next,
-		    ehci_batch->tds[td_current]->alternate);
+		    dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current]),
+		    ehci_batch->tds[td_current].status,
+		    ehci_batch->tds[td_current].next,
+		    ehci_batch->tds[td_current].alternate);
 
 		buffer += transfer_size;
@@ -333,11 +309,11 @@
 	/* Status stage */
 	assert(td_current == ehci_batch->td_count - 1);
-	td_init(ehci_batch->tds[td_current], NULL, status_dir, NULL, 0, 1, true);
-	usb_log_debug2("Batch %p: Created CONTROL STATUS TD(%"PRIxn"): "
-	    "%08x:%08x:%08x", ehci_batch,
-	    addr_to_phys(ehci_batch->tds[td_current]),
-	    ehci_batch->tds[td_current]->status,
-	    ehci_batch->tds[td_current]->next,
-	    ehci_batch->tds[td_current]->alternate);
+	td_init(&ehci_batch->tds[td_current], 0, 0, status_dir, 0, 1, true);
+	usb_log_debug2("Batch %p: Created CONTROL STATUS TD %d(%"PRIxn"): "
+	    "%08x:%08x:%08x", ehci_batch, td_current,
+	    dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current]),
+	    ehci_batch->tds[td_current].status,
+	    ehci_batch->tds[td_current].next,
+	    ehci_batch->tds[td_current].alternate);
 }
 
@@ -354,7 +330,7 @@
 	assert(ehci_batch);
 
-	usb_log_debug2("Batch %p: Data QH(%"PRIxn"): "
+	usb_log_debug2("Batch %p: Data QH(%p): "
 	    "%08x:%08x:%08x:%08x:%08x:%08x", ehci_batch,
-	    addr_to_phys(ehci_batch->qh),
+	    ehci_batch->qh,
 	    ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap,
 	    ehci_batch->qh->status, ehci_batch->qh->current,
@@ -363,5 +339,5 @@
 	size_t td_current = 0;
 	size_t remain_size = ehci_batch->base.buffer_size;
-	char *buffer = ehci_batch->device_buffer;
+	uintptr_t buffer = dma_buffer_phys(&ehci_batch->dma_buffer, ehci_batch->data_buffer);
 	while (remain_size > 0) {
 		const size_t transfer_size = remain_size > EHCI_TD_MAX_TRANSFER
@@ -369,15 +345,14 @@
 
 		const bool last = (remain_size == transfer_size);
-		td_init(
-		    ehci_batch->tds[td_current],
-		    last ? NULL : ehci_batch->tds[td_current + 1],
-		    ehci_batch->base.dir, buffer, transfer_size, -1, last);
+		td_init(&ehci_batch->tds[td_current],
+		    last ? 0 : dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current + 1]),
+		    buffer, ehci_batch->base.dir, transfer_size, -1, last);
 
 		usb_log_debug2("Batch %p: DATA TD(%"PRIxn": %08x:%08x:%08x",
 		    ehci_batch,
-		    addr_to_phys(ehci_batch->tds[td_current]),
-		    ehci_batch->tds[td_current]->status,
-		    ehci_batch->tds[td_current]->next,
-		    ehci_batch->tds[td_current]->alternate);
+		    dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current]),
+		    ehci_batch->tds[td_current].status,
+		    ehci_batch->tds[td_current].next,
+		    ehci_batch->tds[td_current].alternate);
 
 		buffer += transfer_size;
