Index: uspace/drv/bus/usb/xhci/endpoint.c
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.c	(revision 708d8fcd39276a71e62f9b40a631eab1814b52d7)
+++ uspace/drv/bus/usb/xhci/endpoint.c	(revision f92f6b18d7397c30335816ae68fd361da3a72401)
@@ -314,9 +314,5 @@
 	}
 
-	if (xhci_ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
-		for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i) {
-			dma_buffer_free(&xhci_ep->isoch->transfers[i].data);
-		}
-	}
+	isoch_fini(xhci_ep);
 }
 
Index: uspace/drv/bus/usb/xhci/isoch.c
===================================================================
--- uspace/drv/bus/usb/xhci/isoch.c	(revision 708d8fcd39276a71e62f9b40a631eab1814b52d7)
+++ uspace/drv/bus/usb/xhci/isoch.c	(revision f92f6b18d7397c30335816ae68fd361da3a72401)
@@ -35,4 +35,5 @@
 
 #include <str_error.h>
+#include <macros.h>
 
 #include "endpoint.h"
@@ -56,5 +57,17 @@
 		? desc->companion.bytes_per_interval
 		: ep->base.max_transfer_size;
-	/* Technically there could be superspeed plus too. */
+
+	const xhci_hc_t *hc = bus_to_xhci_bus(ep->base.device->bus)->hc;
+
+	/*
+	 * We shall cover at least twice the IST period, otherwise we will get
+	 * an over/underrun every time.
+	 */
+	isoch->buffer_count = (2 * hc->ist) / ep->interval;
+
+	/* 2 buffers are the very minimum. */
+	isoch->buffer_count = max(2, isoch->buffer_count);
+
+	usb_log_error("[isoch] isoch setup with %zu buffers", isoch->buffer_count);
 }
 
@@ -66,5 +79,5 @@
 	isoch->dequeue = isoch->enqueue = isoch->hw_enqueue = 0;
 
-	for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i) {
+	for (size_t i = 0; i < isoch->buffer_count; ++i) {
 		isoch->transfers[i].state = ISOCH_EMPTY;
 	}
@@ -85,6 +98,9 @@
 	}
 
-	for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i)
-		dma_buffer_free(&isoch->transfers[i].data);
+	if (isoch->transfers) {
+		for (size_t i = 0; i < isoch->buffer_count; ++i)
+			dma_buffer_free(&isoch->transfers[i].data);
+		free(isoch->transfers);
+	}
 }
 
@@ -100,9 +116,12 @@
 		return ENOMEM;
 
-	for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i) {
+	isoch->transfers = calloc(isoch->buffer_count, sizeof(xhci_isoch_transfer_t));
+	if(!isoch->transfers)
+		goto err;
+ 
+	for (size_t i = 0; i < isoch->buffer_count; ++i) {
 		xhci_isoch_transfer_t *transfer = &isoch->transfers[i];
 		if (dma_buffer_alloc(&transfer->data, isoch->max_size)) {
-			isoch_fini(ep);
-			return ENOMEM;
+			goto err;
 		}
 	}
@@ -113,4 +132,7 @@
 
 	return EOK;
+err:
+	isoch_fini(ep);
+	return ENOMEM;
 }
 
@@ -151,5 +173,5 @@
 		 * buffers */
 		it->mfindex = XHCI_REG_RD(hc->rt_regs, XHCI_RT_MFINDEX) + 1
-		       + XHCI_ISOCH_BUFFER_COUNT * ep->interval
+		       + isoch->buffer_count * ep->interval
 		       + hc->ist;
 
@@ -207,5 +229,5 @@
 	 * TODO: The "size" of the clock is too low. We have to scale it a bit
 	 * to ensure correct scheduling of transfers, that are
-	 * XHCI_ISOCH_BUFFER_COUNT * interval away from now.
+	 * buffer_count * interval away from now.
 	 * Maximum interval is 8 seconds, which means we need a size of 
 	 * 16 seconds. The size of MFIINDEX is 2 seconds only.
@@ -268,5 +290,5 @@
 			}
 
-			isoch->hw_enqueue = (isoch->hw_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
+			isoch->hw_enqueue = (isoch->hw_enqueue + 1) % isoch->buffer_count;
 			break;
 
@@ -279,5 +301,5 @@
 			it->size = 0;
 
-			isoch->hw_enqueue = (isoch->hw_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
+			isoch->hw_enqueue = (isoch->hw_enqueue + 1) % isoch->buffer_count;
 			break;
 		}
@@ -353,5 +375,5 @@
 			/* fallthrough */
 		case WINDOW_INSIDE:
-			isoch->enqueue = (isoch->enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
+			isoch->enqueue = (isoch->enqueue + 1) % isoch->buffer_count;
 			isoch->last_mfindex = it->mfindex;
 
@@ -417,5 +439,5 @@
 	}
 
-	isoch->enqueue = (isoch->enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
+	isoch->enqueue = (isoch->enqueue + 1) % isoch->buffer_count;
 
 	/* Withdraw results from previous transfers. */
@@ -423,5 +445,5 @@
 	xhci_isoch_transfer_t *res = &isoch->transfers[isoch->dequeue];
 	while (res->state == ISOCH_COMPLETE) {
-		isoch->dequeue = (isoch->dequeue + 1) % XHCI_ISOCH_BUFFER_COUNT;
+		isoch->dequeue = (isoch->dequeue + 1) % isoch->buffer_count;
 
 		res->state = ISOCH_EMPTY;
@@ -487,5 +509,5 @@
 	}
 
-	isoch->dequeue = (isoch->dequeue + 1) % XHCI_ISOCH_BUFFER_COUNT;
+	isoch->dequeue = (isoch->dequeue + 1) % isoch->buffer_count;
 
 	/* Withdraw results from previous transfer. */
@@ -543,5 +565,5 @@
 	 * which one it is.
 	 */
-	for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i) {
+	for (size_t i = 0; i < isoch->buffer_count; ++i) {
 		xhci_isoch_transfer_t * const it = &isoch->transfers[i];
 
Index: uspace/drv/bus/usb/xhci/isoch.h
===================================================================
--- uspace/drv/bus/usb/xhci/isoch.h	(revision 708d8fcd39276a71e62f9b40a631eab1814b52d7)
+++ uspace/drv/bus/usb/xhci/isoch.h	(revision f92f6b18d7397c30335816ae68fd361da3a72401)
@@ -87,7 +87,9 @@
 	uint32_t last_mfindex;
 
+	/** The number of transfer buffers allocated */
+	size_t buffer_count;
+
 	/** Isochronous scheduled transfers with respective buffers */
-	#define XHCI_ISOCH_BUFFER_COUNT 4
-	xhci_isoch_transfer_t transfers[XHCI_ISOCH_BUFFER_COUNT];
+	xhci_isoch_transfer_t *transfers;
 
 	/**
Index: uspace/drv/bus/usb/xhci/main.c
===================================================================
--- uspace/drv/bus/usb/xhci/main.c	(revision 708d8fcd39276a71e62f9b40a631eab1814b52d7)
+++ uspace/drv/bus/usb/xhci/main.c	(revision f92f6b18d7397c30335816ae68fd361da3a72401)
@@ -115,5 +115,5 @@
 {
 	log_init(NAME);
-	logctl_set_log_level(NAME, LVL_DEBUG2);
+	logctl_set_log_level(NAME, LVL_NOTE);
 	return hc_driver_main(&xhci_driver);
 }
