Index: uspace/drv/bus/usb/xhci/endpoint.c
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.c	(revision 3afcf68458411c50a4d1233505058c6e2a12f946)
+++ uspace/drv/bus/usb/xhci/endpoint.c	(revision f971e957f3d5889a37d9c43b655cdd5c637dd670)
@@ -81,5 +81,5 @@
 }
 
-static inline uint8_t xhci_endpoint_ctx_offset(xhci_endpoint_t *ep)
+uint8_t xhci_endpoint_ctx_offset(xhci_endpoint_t *ep)
 {
 	/* 0 is slot ctx, 1 is EP0, then it's EP1 out, in, EP2 out, in, etc. */
Index: uspace/drv/bus/usb/xhci/endpoint.h
===================================================================
--- uspace/drv/bus/usb/xhci/endpoint.h	(revision 3afcf68458411c50a4d1233505058c6e2a12f946)
+++ uspace/drv/bus/usb/xhci/endpoint.h	(revision f971e957f3d5889a37d9c43b655cdd5c637dd670)
@@ -97,4 +97,6 @@
 void xhci_device_fini(xhci_device_t *);
 
+uint8_t xhci_endpoint_ctx_offset(xhci_endpoint_t *);
+
 int xhci_device_add_endpoint(xhci_device_t *, xhci_endpoint_t *);
 int xhci_device_remove_endpoint(xhci_device_t *, xhci_endpoint_t *);
Index: uspace/drv/bus/usb/xhci/transfers.c
===================================================================
--- uspace/drv/bus/usb/xhci/transfers.c	(revision 3afcf68458411c50a4d1233505058c6e2a12f946)
+++ uspace/drv/bus/usb/xhci/transfers.c	(revision f971e957f3d5889a37d9c43b655cdd5c637dd670)
@@ -167,7 +167,7 @@
 		return EINVAL;
 	}
-	if (batch->ep->target.endpoint != 0 || batch->ep->transfer_type != USB_TRANSFER_CONTROL) {
+	if (batch->ep->transfer_type != USB_TRANSFER_CONTROL) {
 		/* This method only works for control transfers. */
-		usb_log_error("Attempted to schedule control transfer to non 0 endpoint.");
+		usb_log_error("Attempted to schedule a control transfer to non control endpoint.");
 		return EINVAL;
 	}
@@ -176,5 +176,5 @@
 
 	uint8_t slot_id = xhci_ep->device->slot_id;
-	xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[0];
+	xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[batch->ep->target.endpoint];
 
 	usb_device_request_setup_packet_t* setup =
@@ -254,5 +254,6 @@
 	/* For control transfers, the target is always 1. */
 	// FIXME: ignoring return code
-	hc_ring_doorbell(hc, slot_id, 1);
+	const uint8_t target = xhci_endpoint_ctx_offset(xhci_ep);
+	hc_ring_doorbell(hc, slot_id, target);
 
 	// Issue a Configure Endpoint command, if needed.
@@ -300,5 +301,6 @@
 
 	// TODO: target = endpoint | stream_id << 16
-	hc_ring_doorbell(hc, slot_id, xhci_ep->base.target.endpoint);
+	const uint8_t target = xhci_endpoint_ctx_offset(xhci_ep);
+	hc_ring_doorbell(hc, slot_id, target);
 	return EOK;
 }
@@ -337,6 +339,5 @@
 	list_append(&transfer->link, &hc->transfers);
 
-	const uint8_t target = 2 * batch->ep->target.endpoint
-		+ (batch->ep->direction == USB_DIRECTION_IN ? 1 : 0);
+	const uint8_t target = xhci_endpoint_ctx_offset(xhci_ep);
 	usb_log_debug("Ringing doorbell for slot_id = %d, target = %d", slot_id, target);
 	return hc_ring_doorbell(hc, slot_id, target);
