Index: uspace/drv/bus/usb/xhci/endpoint.c
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.c	(revision 2297fab2d625c81532443a5c6e3ea194af2bb52d)
+++ uspace/drv/bus/usb/xhci/endpoint.c	(revision d7869d7e00b2e62dbfbb2c4a30abf9a95caa7e73)
@@ -39,4 +39,5 @@
 
 #include "bus.h"
+#include "commands.h"
 #include "endpoint.h"
 
@@ -114,4 +115,41 @@
 }
 
+int xhci_device_configure(xhci_device_t *dev, xhci_hc_t *hc)
+{
+	int err;
+
+	// Prepare input context.
+	xhci_input_ctx_t *ictx = malloc(sizeof(xhci_input_ctx_t));
+	if (!ictx) {
+		return ENOMEM;
+	}
+
+	memset(ictx, 0, sizeof(xhci_input_ctx_t));
+
+	// Quoting sec. 4.6.6: A1, D0, D1 are down, A0 is up.
+	XHCI_INPUT_CTRL_CTX_ADD_CLEAR(ictx->ctrl_ctx, 1);
+	XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 0);
+	XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 1);
+	XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 0);
+
+	// TODO: Set slot context and other flags. (probably forgot a lot of 'em)
+
+	// Issue configure endpoint command (sec 4.3.5).
+	xhci_cmd_t cmd;
+	xhci_cmd_init(&cmd);
+
+	cmd.slot_id = dev->slot_id;
+	xhci_send_configure_endpoint_command(hc, &cmd, ictx);
+	if ((err = xhci_cmd_wait(&cmd, 100000)) != EOK)
+		goto err_cmd;
+
+	xhci_cmd_fini(&cmd);
+	return EOK;
+
+err_cmd:
+	free(ictx);
+	return err;
+}
+
 /**
  * @}
Index: uspace/drv/bus/usb/xhci/endpoint.h
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.h	(revision 2297fab2d625c81532443a5c6e3ea194af2bb52d)
+++ uspace/drv/bus/usb/xhci/endpoint.h	(revision d7869d7e00b2e62dbfbb2c4a30abf9a95caa7e73)
@@ -43,4 +43,6 @@
 #include <usb/host/hcd.h>
 
+#include "hc.h"
+
 typedef struct xhci_device xhci_device_t;
 typedef struct xhci_endpoint xhci_endpoint_t;
@@ -85,4 +87,5 @@
 int xhci_device_remove_endpoint(xhci_device_t *, xhci_endpoint_t *);
 xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t);
+int xhci_device_configure(xhci_device_t *, xhci_hc_t *);
 
 static inline xhci_endpoint_t * xhci_endpoint_get(endpoint_t *ep)
Index: uspace/drv/bus/usb/xhci/hw_struct/context.h
===================================================================
--- uspace/drv/bus/usb/xhci/hw_struct/context.h	(revision 2297fab2d625c81532443a5c6e3ea194af2bb52d)
+++ uspace/drv/bus/usb/xhci/hw_struct/context.h	(revision d7869d7e00b2e62dbfbb2c4a30abf9a95caa7e73)
@@ -166,4 +166,5 @@
 
 #define XHCI_INPUT_CTRL_CTX_DROP_SET(ctx, idx) (ctx).data[0] |= (1 << (idx))
+#define XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ctx, idx) (ctx).data[0] &= ~(1 << (idx))
 
 #define XHCI_INPUT_CTRL_CTX_ADD(ctx, idx) \
@@ -171,4 +172,5 @@
 
 #define XHCI_INPUT_CTRL_CTX_ADD_SET(ctx, idx) (ctx).data[1] |= (1 << (idx))
+#define XHCI_INPUT_CTRL_CTX_ADD_CLEAR(ctx, idx) (ctx).data[1] &= ~(1 << (idx))
 
 #define XHCI_INPUT_CTRL_CTX_CONFIG_VALUE(ctx)   XHCI_DWORD_EXTRACT((ctx).data[7],  7,  0)
Index: uspace/drv/bus/usb/xhci/rh.c
===================================================================
--- uspace/drv/bus/usb/xhci/rh.c	(revision 2297fab2d625c81532443a5c6e3ea194af2bb52d)
+++ uspace/drv/bus/usb/xhci/rh.c	(revision d7869d7e00b2e62dbfbb2c4a30abf9a95caa7e73)
@@ -149,5 +149,10 @@
 	xhci_cmd_fini(&cmd);
 
-	// TODO: Issue configure endpoint commands (sec 4.3.5).
+	usb_address_t address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx);
+	usb_log_debug2("Obtained USB address: %d.\n", address);
+
+	// TODO: Ask libusbhost to create a control endpoint for EP0.
+
+	// TODO: Save all data structures in the corresponding xhci_device_t.
 
 	return EOK;
Index: uspace/drv/bus/usb/xhci/transfers.c
===================================================================
--- uspace/drv/bus/usb/xhci/transfers.c	(revision 2297fab2d625c81532443a5c6e3ea194af2bb52d)
+++ uspace/drv/bus/usb/xhci/transfers.c	(revision d7869d7e00b2e62dbfbb2c4a30abf9a95caa7e73)
@@ -103,4 +103,24 @@
 }
 
+static inline bool configure_endpoint_needed(usb_device_request_setup_packet_t *setup)
+{
+	usb_request_type_t request_type = SETUP_REQUEST_TYPE_GET_TYPE(setup->request_type);
+
+	if (request_type == USB_REQUEST_TYPE_STANDARD) {
+		usb_stddevreq_t request = setup->request;
+
+		switch (request) {
+		case USB_DEVREQ_SET_CONFIGURATION:
+		case USB_DEVREQ_SET_INTERFACE:
+			return true;
+
+		default:
+			return false;
+		}
+	}
+
+	return false;
+}
+
 int xhci_init_transfers(xhci_hc_t *hc)
 {
@@ -225,5 +245,14 @@
 
 	/* For control transfers, the target is always 1. */
+	// FIXME: ignoring return code
 	hc_ring_doorbell(hc, slot_id, 1);
+
+	// Issue a Configure Endpoint command, if needed.
+	if (configure_endpoint_needed(setup)) {
+		// TODO: figure out the best time to issue this command
+		// FIXME: ignoring return code
+		xhci_device_configure(xhci_ep->device, hc);
+	}
+
 	return EOK;
 }
