Index: uspace/drv/bus/usb/xhci/Makefile
===================================================================
--- uspace/drv/bus/usb/xhci/Makefile	(revision 8cbc1670cebee160051351b4e0e6348c39e97c1c)
+++ uspace/drv/bus/usb/xhci/Makefile	(revision b19131c5be03b6e707aa8ef10e4edfec19f0a4d6)
@@ -45,4 +45,5 @@
 	debug.c \
 	trb_ring.c \
+	scratchpad.c \
 	main.c
 
Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision 8cbc1670cebee160051351b4e0e6348c39e97c1c)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision b19131c5be03b6e707aa8ef10e4edfec19f0a4d6)
@@ -41,4 +41,5 @@
 #include "hc.h"
 #include "hw_struct/trb.h"
+#include "scratchpad.h"
 
 static const irq_cmd_t irq_commands[] = {
@@ -206,8 +207,10 @@
 		goto err_cmd_ring;
 
-	// TODO: Allocate scratchpad buffers
-
-	return EOK;
-
+	if ((err = xhci_scratchpad_alloc(hc)))
+		goto err_scratchpad;
+
+	return EOK;
+
+err_scratchpad:
 	xhci_event_ring_fini(&hc->event_ring);
 err_cmd_ring:
@@ -434,4 +437,5 @@
 	xhci_trb_ring_fini(&hc->command_ring);
 	xhci_event_ring_fini(&hc->event_ring);
+	xhci_scratchpad_free(hc);
 	pio_disable(hc->base, RNGSZ(hc->mmio_range));
 	usb_log_info("HC(%p): Finalized.", hc);
Index: uspace/drv/bus/usb/xhci/scratchpad.c
===================================================================
--- uspace/drv/bus/usb/xhci/scratchpad.c	(revision b19131c5be03b6e707aa8ef10e4edfec19f0a4d6)
+++ uspace/drv/bus/usb/xhci/scratchpad.c	(revision b19131c5be03b6e707aa8ef10e4edfec19f0a4d6)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbxhci
+ * @{
+ */
+/** @file
+ * Scratchpad buffer array bookkeeping.
+ */
+
+#include <errno.h>
+#include <usb/debug.h>
+#include <usb/host/utils/malloc32.h>
+#include "hc.h"
+#include "hw_struct/regs.h"
+#include "scratchpad.h"
+
+static inline unsigned xhci_scratchpad_count(xhci_hc_t *hc)
+{
+	unsigned lo, hi;
+
+	lo = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_SPBUF_LO);
+	hi = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_SPBUF_HI);
+
+	return (hi << 5) | lo;
+}
+
+int xhci_scratchpad_alloc(xhci_hc_t *hc)
+{
+	unsigned num_bufs, allocated;
+	xhci_scratchpad_t *buf_array;
+
+	num_bufs = xhci_scratchpad_count(hc);
+
+	if (!num_bufs)
+		return EOK;
+
+	buf_array = malloc32(num_bufs * sizeof(xhci_scratchpad_t));
+	if (!buf_array)
+		return ENOMEM;
+
+	hc->dcbaa[0] = (xhci_device_ctx_t *) buf_array;
+
+	allocated = 0;
+	for (unsigned i = 0; i < num_bufs; ++i) {
+		buf_array[i].sp_ptr = (uint64_t) malloc32(PAGE_SIZE);
+
+		if (buf_array[i].sp_ptr)
+			++allocated;
+		else
+			goto err_page_alloc;
+
+		memset((void *) buf_array[i].sp_ptr, 0, PAGE_SIZE);
+	}
+
+	usb_log_debug2("Allocated %d scratchpad buffers.", num_bufs);
+
+	return EOK;
+
+err_page_alloc:
+	for (unsigned i = 0; i < allocated; ++i)
+		free32((void *) buf_array[i].sp_ptr);
+
+	return ENOMEM;
+}
+
+void xhci_scratchpad_free(xhci_hc_t *hc)
+{
+	unsigned num_bufs;
+	xhci_scratchpad_t *buf_array;
+
+	num_bufs = xhci_scratchpad_count(hc);
+	if(!num_bufs)
+		return;
+
+	buf_array = (xhci_scratchpad_t *) hc->dcbaa[0];
+
+	for (unsigned i = 0; i < num_bufs; ++i)
+		free32((void *) buf_array[i].sp_ptr);
+	free32(buf_array);
+
+	hc->dcbaa[0] = NULL;
+	return;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/xhci/scratchpad.h
===================================================================
--- uspace/drv/bus/usb/xhci/scratchpad.h	(revision b19131c5be03b6e707aa8ef10e4edfec19f0a4d6)
+++ uspace/drv/bus/usb/xhci/scratchpad.h	(revision b19131c5be03b6e707aa8ef10e4edfec19f0a4d6)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbxhci
+ * @{
+ */
+/** @file
+ * Scratchpad buffers are PAGE_SIZE sized page boundary aligned buffers
+ * that are free to use by the xHC.
+ *
+ * This file provides means of allocation and deallocation of these
+ * buffers.
+ */
+
+#ifndef XHCI_SCRATCHPAD_H
+#define XHCI_SCRATCHPAD_H
+
+typedef struct xhci_scratchpad {
+	uint64_t sp_ptr;
+} xhci_scratchpad_t;
+
+int xhci_scratchpad_alloc(xhci_hc_t *);
+void xhci_scratchpad_free(xhci_hc_t *);
+
+#endif
+
+/**
+ * @}
+ */
