Index: uspace/lib/usbdev/src/devdrv.c
===================================================================
--- uspace/lib/usbdev/src/devdrv.c	(revision c90163262531a9d6fd0787466623f8e3732fd826)
+++ uspace/lib/usbdev/src/devdrv.c	(revision 0eadfd1e27518dc073e37ac4e81a1ba5a5e0929f)
@@ -255,11 +255,13 @@
 
 	/* Register created pipes. */
+	unsigned pipes_registered = 0;
 	for (size_t i = 0; i < pipe_count; i++) {
 		if (pipes[i].present) {
-			rc = usb_pipe_register(&pipes[i].pipe);
+			rc = usb_pipe_register(&pipes[i].pipe, pipes[i].descriptor, pipes[i].companion_descriptor);
 			if (rc != EOK) {
 				goto rollback_unregister_endpoints;
 			}
 		}
+		pipes_registered++;
 	}
 
@@ -276,5 +278,5 @@
 	 */
 rollback_unregister_endpoints:
-	for (size_t i = 0; i < pipe_count; i++) {
+	for (size_t i = 0; i < pipes_registered; i++) {
 		if (pipes[i].present) {
 			usb_pipe_unregister(&pipes[i].pipe);
@@ -419,6 +421,5 @@
 	/* This pipe was registered by the hub driver,
 	 * during device initialization. */
-	int rc = usb_pipe_initialize_default_control(
-	    &usb_dev->ctrl_pipe, usb_dev->bus_session);
+	int rc = usb_pipe_initialize_default_control(&usb_dev->ctrl_pipe, usb_dev->bus_session);
 	if (rc != EOK) {
 		usb_dev_disconnect(usb_dev->bus_session);
Index: uspace/lib/usbdev/src/devpoll.c
===================================================================
--- uspace/lib/usbdev/src/devpoll.c	(revision c90163262531a9d6fd0787466623f8e3732fd826)
+++ uspace/lib/usbdev/src/devpoll.c	(revision 0eadfd1e27518dc073e37ac4e81a1ba5a5e0929f)
@@ -96,5 +96,5 @@
 		    (int) mapping->interface->interface_subclass,
 		    (int) mapping->interface->interface_protocol,
-		    data->request_size, pipe->desc.max_packet_size);
+		    data->request_size, pipe->desc.max_transfer_size);
 	}
 
Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision c90163262531a9d6fd0787466623f8e3732fd826)
+++ uspace/lib/usbdev/src/pipes.c	(revision 0eadfd1e27518dc073e37ac4e81a1ba5a5e0929f)
@@ -272,40 +272,43 @@
  * @param pipe Endpoint pipe to be initialized.
  * @param bus_session Endpoint pipe to be initialized.
- * @param ep_desc Prepared endpoint descriptor
- * @return Error code.
- */
-int usb_pipe_initialize(usb_pipe_t *pipe,
-    usb_dev_session_t *bus_session,
-    const usb_endpoint_desc_t *ep_desc)
-{
-	int ret = EOK;
-	assert(pipe);
-
-	pipe->desc = *ep_desc;
+ * @return Error code.
+ */
+int usb_pipe_initialize(usb_pipe_t *pipe, usb_dev_session_t *bus_session, usb_transfer_type_t transfer_type)
+{
+	assert(pipe);
+
 	pipe->auto_reset_halt = false;
 	pipe->bus_session = bus_session;
 
-	if (pipe->desc.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
-		ret = usb_isoch_session_initialize(pipe);
-	}
-
-	return ret;
-}
-
-static const usb_endpoint_desc_t default_control_ep_desc = {
-	.max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
+	if (transfer_type == USB_TRANSFER_ISOCHRONOUS)
+		return usb_isoch_session_initialize(pipe);
+
+	return EOK;
+}
+
+static const usb_pipe_desc_t default_control_pipe = {
+	.endpoint_no = 0,
+	.transfer_type = USB_TRANSFER_CONTROL,
 	.direction = USB_DIRECTION_BOTH,
-	.packets = 1,
+	.max_transfer_size = CTRL_PIPE_MIN_PACKET_SIZE,
 };
 
-/** Initialize USB endpoint pipe as the default zero control pipe.
+/** Initialize USB default control pipe.
+ *
+ * This one is special because it must not be registered, it is registered automatically.
  *
  * @param pipe Endpoint pipe to be initialized.
- * @param bus_session
+ * @param bus_session Endpoint pipe to be initialized.
  * @return Error code.
  */
 int usb_pipe_initialize_default_control(usb_pipe_t *pipe, usb_dev_session_t *bus_session)
 {
-	return usb_pipe_initialize(pipe, bus_session, &default_control_ep_desc); 
+	const int ret = usb_pipe_initialize(pipe, bus_session, USB_TRANSFER_CONTROL);
+	if (ret)
+		return ret;
+
+	pipe->desc = default_control_pipe;
+
+	return EOK;
 }
 
@@ -313,11 +316,13 @@
  *
  * @param pipe Pipe to be registered.
- * @param interval Polling interval.
- * @return Error code.
- */
-int usb_pipe_register(usb_pipe_t *pipe)
+ * @param ep_desc Matched endpoint descriptor
+ * @param comp_desc Matched superspeed companion descriptro, if any
+ * @return Error code.
+ */
+int usb_pipe_register(usb_pipe_t *pipe, const usb_standard_endpoint_descriptor_t *ep_desc, const usb_superspeed_endpoint_companion_descriptor_t *comp_desc)
 {
 	assert(pipe);
 	assert(pipe->bus_session);
+	assert(ep_desc);
 
 	async_exch_t *exch = async_exchange_begin(pipe->bus_session);
@@ -325,6 +330,22 @@
 		return ENOMEM;
 
-	const int ret = usbhc_register_endpoint(exch, &pipe->desc);
-
+	usb_endpoint_descriptors_t descriptors;
+
+#define COPY(field) descriptors.endpoint.field = ep_desc->field
+	COPY(endpoint_address);
+	COPY(attributes);
+	COPY(max_packet_size);
+	COPY(poll_interval);
+#undef COPY
+
+#define COPY(field) descriptors.companion.field = comp_desc->field
+	if (comp_desc) {
+		COPY(max_burst);
+		COPY(attributes);
+		COPY(bytes_per_interval);
+	}
+#undef COPY
+
+	const int ret = usbhc_register_endpoint(exch, &pipe->desc, &descriptors);
 	async_exchange_end(exch);
 	return ret;
Index: uspace/lib/usbdev/src/pipesinit.c
===================================================================
--- uspace/lib/usbdev/src/pipesinit.c	(revision c90163262531a9d6fd0787466623f8e3732fd826)
+++ uspace/lib/usbdev/src/pipesinit.c	(revision 0eadfd1e27518dc073e37ac4e81a1ba5a5e0929f)
@@ -156,39 +156,4 @@
 }
 
-static void parse_endpoint_descriptors(usb_endpoint_desc_t *ep_desc,
-    usb_standard_endpoint_descriptor_t *endpoint_desc,
-    usb_superspeed_endpoint_companion_descriptor_t *companion_desc)
-{
-	*ep_desc = (usb_endpoint_desc_t) {
-		/* Actual endpoint number is in bits 0..3 */
-		.endpoint_no = endpoint_desc->endpoint_address & 0x0F,
-		/* Transfer type is in bits 0..2 and
-		 * the enum values corresponds 1:1 */
-		.transfer_type = endpoint_desc->attributes & 3,
-		/* Endpoint direction is set by bit 7 */
-		.direction = (endpoint_desc->endpoint_address & 128)
-		    ? USB_DIRECTION_IN : USB_DIRECTION_OUT,
-		// FIXME: USB2 max_packet_size is limited to 1023 bytes, 1024+ doesn't work for USB3
-		// See 4.14.2.1.1 of XHCI specification -> possibly refactor into one somehow-named field
-		.max_packet_size
-			= ED_MPS_PACKET_SIZE_GET(uint16_usb2host(endpoint_desc->max_packet_size)),
-		.interval = endpoint_desc->poll_interval,
-		// FIXME: USB2 packets and USB3 max_burst are probably the same thing
-		.packets = ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(endpoint_desc->max_packet_size)),
-	};
-
-	if (companion_desc) {
-		ep_desc->usb3 = (usb3_endpoint_desc_t) {
-			.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),
-		};
-	}
-}
-
-
 /** Process endpoint descriptor.
  *
@@ -211,10 +176,7 @@
 	 * Get endpoint characteristics.
 	 */
-	usb_endpoint_desc_t ep_desc;
-	parse_endpoint_descriptors(&ep_desc, endpoint_desc, companion_desc);
-
 	const usb_endpoint_description_t description = {
-		.direction = ep_desc.direction,
-		.transfer_type = ep_desc.transfer_type,
+		.transfer_type = USB_ED_GET_TRANSFER_TYPE(*endpoint_desc),
+		.direction = USB_ED_GET_DIR(*endpoint_desc),
 
 		/* Get interface characteristics. */
@@ -238,5 +200,5 @@
 	}
 
-	int err = usb_pipe_initialize(&ep_mapping->pipe, bus_session, &ep_desc);
+	int err = usb_pipe_initialize(&ep_mapping->pipe, bus_session, description.transfer_type);
 	if (err)
 		return err;
