Index: uspace/drv/bus/usb/xhci/bus.c
===================================================================
--- uspace/drv/bus/usb/xhci/bus.c	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/drv/bus/usb/xhci/bus.c	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -68,6 +68,20 @@
 	ep->max_streams = desc->usb3.max_streams;
 	ep->max_burst = desc->usb3.max_burst;
-	// TODO add this property to usb_endpoint_desc_t and fetch it from ss companion desc
-	ep->mult = 0;
+	ep->mult = desc->usb3.mult;
+
+	if (ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
+		if (ep->base.device->speed <= USB_SPEED_HIGH) {
+			ep->isoch_max_size = desc->max_packet_size * (desc->packets + 1);
+		}
+		else if (ep->base.device->speed == USB_SPEED_SUPER) {
+			ep->isoch_max_size = desc->usb3.bytes_per_interval;
+		}
+		/* Technically there could be superspeed plus too. */
+
+		/* Allocate and setup isochronous-specific structures. */
+		ep->isoch_enqueue = 0;
+		ep->isoch_dequeue = XHCI_ISOCH_BUFFER_COUNT - 1;
+		ep->isoch_started = false;
+	}
 
 	return xhci_endpoint_alloc_transfer_ds(ep);
Index: uspace/drv/bus/usb/xhci/endpoint.c
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.c	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/drv/bus/usb/xhci/endpoint.c	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -193,4 +193,28 @@
 }
 
+static int xhci_isoch_alloc_transfers(xhci_endpoint_t *xhci_ep) {
+	int i = 0;
+	int err = EOK;
+	while (i < XHCI_ISOCH_BUFFER_COUNT) {
+		xhci_isoch_transfer_t *transfer = xhci_ep->isoch_transfers[i];
+		if (dma_buffer_alloc(&transfer->data, xhci_ep->isoch_max_size)) {
+			err = ENOMEM;
+			break;
+		}
+		transfer->size = 0;
+		++i;
+	}
+
+	if (err) {
+		--i;
+		while(i >= 0) {
+			dma_buffer_free(&xhci_ep->isoch_transfers[i]->data);
+			--i;
+		}
+	}
+
+	return err;
+}
+
 int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *xhci_ep)
 {
@@ -203,4 +227,11 @@
 	if ((err = xhci_trb_ring_init(&xhci_ep->ring))) {
 		return err;
+	}
+
+	if (xhci_ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
+		if((err = xhci_isoch_alloc_transfers(xhci_ep))) {
+			xhci_trb_ring_fini(&xhci_ep->ring);
+			return err;
+		}
 	}
 
@@ -289,5 +320,7 @@
 	XHCI_EP_TR_DPTR_SET(*ctx, ep->ring.dequeue);
 	XHCI_EP_DCS_SET(*ctx, 1);
-	// TODO: max ESIT payload
+
+	XHCI_EP_MAX_ESIT_PAYLOAD_LO_SET(*ctx, ep->isoch_max_size & 0xFFFF);
+	XHCI_EP_MAX_ESIT_PAYLOAD_HI_SET(*ctx, (ep->isoch_max_size >> 16) & 0xFF);
 }
 
Index: uspace/drv/bus/usb/xhci/hw_struct/context.h
===================================================================
--- uspace/drv/bus/usb/xhci/hw_struct/context.h	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/drv/bus/usb/xhci/hw_struct/context.h	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -76,4 +76,6 @@
 #define XHCI_EP_MAX_ESIT_PAYLOAD_LO_SET(ctx, val) \
 	xhci_dword_set_bits(&(ctx).data3, val, 31, 16)
+#define XHCI_EP_MAX_ESIT_PAYLOAD_HI_SET(ctx, val) \
+	xhci_dword_set_bits(&(ctx).data[0], val, 31, 24)
 #define XHCI_EP_INTERVAL_SET(ctx, val) \
 	xhci_dword_set_bits(&(ctx).data[0], val, 23, 16)
@@ -102,5 +104,6 @@
 #define XHCI_EP_TR_DPTR(ctx)            XHCI_QWORD_EXTRACT((ctx).data2, 63,  4)
 
-#define XHCI_EP_MAX_ESIT_PAYLOAD_LO(ctx) XHCI_DWORD_EXTRACT((ctx).data3, 31,  16)
+#define XHCI_EP_MAX_ESIT_PAYLOAD_LO(ctx) XHCI_DWORD_EXTRACT((ctx).data3, 31, 16)
+#define XHCI_EP_MAX_ESIT_PAYLOAD_HI(ctx) XHCI_DWORD_EXTRACT((ctx).data[0], 31, 24)
 
 } __attribute__((packed)) xhci_ep_ctx_t;
Index: uspace/drv/bus/usb/xhci/transfers.c
===================================================================
--- uspace/drv/bus/usb/xhci/transfers.c	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/drv/bus/usb/xhci/transfers.c	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -287,8 +287,8 @@
 	isoch_transfer->size = transfer->batch.buffer_size;
 	if (isoch_transfer->size > 0) {
-		memcpy(isoch_transfer->data_virt, transfer->batch.buffer, isoch_transfer->size);
-	}
-
-	trb.parameter = isoch_transfer->data_phys;
+		memcpy(isoch_transfer->data.virt, transfer->batch.buffer, isoch_transfer->size);
+	}
+
+	trb.parameter = isoch_transfer->data.phys;
 
 	xhci_trb_ring_t *ring = get_ring(hc, transfer);
@@ -341,5 +341,5 @@
 	if (transfer->batch.buffer_size <= isoch_transfer->size) {
 		if (transfer->batch.buffer_size > 0) {
-			memcpy(transfer->batch.buffer, isoch_transfer->data_virt, transfer->batch.buffer_size);
+			memcpy(transfer->batch.buffer, isoch_transfer->data.virt, transfer->batch.buffer_size);
 		}
 		if (transfer->batch.buffer_size < isoch_transfer->size) {
@@ -349,5 +349,5 @@
 	}
 	else {
-		memcpy(transfer->batch.buffer, isoch_transfer->data_virt, isoch_transfer->size);
+		memcpy(transfer->batch.buffer, isoch_transfer->data.virt, isoch_transfer->size);
 		transfer->batch.transfered_size = isoch_transfer->size;
 	}
@@ -357,5 +357,5 @@
 	xhci_trb_clean(&trb);
 
-	trb.parameter = isoch_transfer->data_phys;
+	trb.parameter = isoch_transfer->data.phys;
 	isoch_transfer->size = xhci_ep->isoch_max_size;
 
Index: uspace/drv/bus/usb/xhci/transfers.h
===================================================================
--- uspace/drv/bus/usb/xhci/transfers.h	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/drv/bus/usb/xhci/transfers.h	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -58,8 +58,6 @@
 	/* Used buffer size */
 	uint64_t size;
-	/* Pointer to data in virt memory */
-	void *data_virt;
-	/* Physical address of the buffer */
-	uintptr_t data_phys;
+	/* Buffer with data */
+	dma_buffer_t data;
 	/* Physical address of enqueued TRB */
 	uintptr_t interrupt_trb_phys;
Index: uspace/lib/drv/include/usb_iface.h
===================================================================
--- uspace/lib/drv/include/usb_iface.h	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/lib/drv/include/usb_iface.h	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -126,4 +126,6 @@
 		unsigned max_burst;
 		unsigned max_streams;
+		unsigned mult;
+		unsigned bytes_per_interval;
 	} usb3;
 } usb_endpoint_desc_t;
Index: uspace/lib/usb/include/usb/descriptor.h
===================================================================
--- uspace/lib/usb/include/usb/descriptor.h	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/lib/usb/include/usb/descriptor.h	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -240,11 +240,14 @@
 	 * For bulk endpoints, this field contains the amount of streams
 	 * supported by the endpoint.
-	 * For isochronous endpoints, this field contains either maximum
-	 * number of packets supported within a service interval, or
-	 * whether an isochronous endpoint companion descriptor follows.
+	 * For isochronous endpoints, this field contains maximum
+	 * number of packets supported within a service interval.
+	 * Warning: the values returned by macros may not make any sense
+	 * for specific endpoint types.
 	 */
 	uint8_t attributes;
 #define SS_COMPANION_MAX_STREAMS(attributes) \
 	(attributes & 0x1f)
+#define SS_COMPANION_MULT(attributes) \
+	(attributes & 0x3)
 	/** The total number of bytes this endpoint will transfer
 	 * every service interval (SI).
Index: uspace/lib/usbdev/include/usb/dev/pipes.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/pipes.h	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/lib/usbdev/include/usb/dev/pipes.h	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -97,5 +97,5 @@
 
 int usb_pipe_initialize(usb_pipe_t *, usb_endpoint_t, usb_transfer_type_t,
-    size_t, usb_direction_t, unsigned, unsigned, unsigned, usb_dev_session_t *);
+    size_t, usb_direction_t, unsigned, unsigned, unsigned, unsigned, unsigned, usb_dev_session_t *);
 int usb_pipe_initialize_default_control(usb_pipe_t *, usb_dev_session_t *);
 
Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/lib/usbdev/src/pipes.c	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -255,7 +255,8 @@
     usb_transfer_type_t transfer_type, size_t max_packet_size,
     usb_direction_t direction, unsigned packets,
-    unsigned max_burst, unsigned max_streams, usb_dev_session_t *bus_session)
-{
-	// FIXME refactor this function
+    unsigned max_burst, unsigned max_streams, unsigned bytes_per_interval,
+	unsigned mult, usb_dev_session_t *bus_session)
+{
+	// FIXME: refactor this function PLEASE
 	assert(pipe);
 
@@ -267,4 +268,6 @@
 	pipe->desc.usb3.max_burst = max_burst;
 	pipe->desc.usb3.max_streams = max_streams;
+	pipe->desc.usb3.mult = mult;
+	pipe->desc.usb3.bytes_per_interval = bytes_per_interval;
 	pipe->auto_reset_halt = false;
 	pipe->bus_session = bus_session;
@@ -284,5 +287,5 @@
 
 	const int rc = usb_pipe_initialize(pipe, 0, USB_TRANSFER_CONTROL,
-	    CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, 0, 0, bus_session);
+	    CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, 0, 0, 0, 0, bus_session);
 
 	pipe->auto_reset_halt = true;
Index: uspace/lib/usbdev/src/pipesinit.c
===================================================================
--- uspace/lib/usbdev/src/pipesinit.c	(revision d308687300a22e8f243cc258f82dfe687aa82cfa)
+++ uspace/lib/usbdev/src/pipesinit.c	(revision 6b433a80b98bf4490e3bfe28af7af8fe99fc86ab)
@@ -210,9 +210,15 @@
 	unsigned max_burst = 0;
 	unsigned max_streams = 0;
+	unsigned bytes_per_interval = 0;
+	unsigned mult = 0;
 	if(companion_desc) {
 		max_burst = companion_desc->max_burst;
 		max_streams = SS_COMPANION_MAX_STREAMS(companion_desc->attributes);
-	}
-
+		bytes_per_interval = companion_desc->bytes_per_interval;
+		mult = SS_COMPANION_MULT(companion_desc->attributes);
+	}
+
+	// FIXME: USB2 packets and USB3 max_burst are probably the same thing
+	// See 4.14.2.1.1 of XHCI specification -> possibly refactor into one somehow-named field
 	int rc = usb_pipe_initialize(&ep_mapping->pipe,
 	    ep_no, description.transfer_type,
@@ -221,5 +227,5 @@
 	    description.direction, ED_MPS_TRANS_OPPORTUNITIES_GET(
 	        uint16_usb2host(endpoint_desc->max_packet_size)),
-	    max_burst, max_streams, bus_session);
+	    max_burst, max_streams, bytes_per_interval, mult, bus_session);
 	if (rc != EOK) {
 		return rc;
