Index: uspace/lib/drv/include/usb_iface.h
===================================================================
--- uspace/lib/drv/include/usb_iface.h	(revision 35c37fc2ef57407c4bf38bf0ac3d777777e3ccd1)
+++ uspace/lib/drv/include/usb_iface.h	(revision 9e5b1621f4f41683f532e53cb098ad63a69b19a0)
@@ -103,4 +103,15 @@
  */
 typedef struct {
+	unsigned max_burst;
+	unsigned max_streams;
+	unsigned mult;
+	unsigned bytes_per_interval;
+} usb3_endpoint_desc_t;
+
+typedef struct {
+	unsigned polling_interval;
+} usb2_endpoint_desc_t;
+
+typedef struct usb_endpoint_desc {
 	/** Endpoint number. */
 	usb_endpoint_t endpoint_no;
@@ -122,14 +133,7 @@
 	unsigned packets;
 
-	struct {
-		unsigned polling_interval;
-	} usb2;
-
-	struct {
-		unsigned max_burst;
-		unsigned max_streams;
-		unsigned mult;
-		unsigned bytes_per_interval;
-	} usb3;
+	/** Bus version specific information */
+	usb2_endpoint_desc_t usb2;
+	usb3_endpoint_desc_t usb3;
 } usb_endpoint_desc_t;
 
Index: uspace/lib/usbdev/include/usb/dev/pipes.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/pipes.h	(revision 35c37fc2ef57407c4bf38bf0ac3d777777e3ccd1)
+++ uspace/lib/usbdev/include/usb/dev/pipes.h	(revision 9e5b1621f4f41683f532e53cb098ad63a69b19a0)
@@ -100,6 +100,5 @@
 } usb_endpoint_mapping_t;
 
-int usb_pipe_initialize(usb_pipe_t *, usb_endpoint_t, usb_transfer_type_t,
-    size_t, usb_direction_t, unsigned, unsigned, unsigned, unsigned, unsigned, usb_dev_session_t *);
+int usb_pipe_initialize(usb_pipe_t *, usb_dev_session_t *, const usb_endpoint_desc_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 35c37fc2ef57407c4bf38bf0ac3d777777e3ccd1)
+++ uspace/lib/usbdev/src/pipes.c	(revision 9e5b1621f4f41683f532e53cb098ad63a69b19a0)
@@ -271,36 +271,20 @@
  *
  * @param pipe Endpoint pipe to be initialized.
- * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).
- * @param transfer_type Transfer type (e.g. interrupt or bulk).
- * @param max_packet_size Maximum packet size in bytes.
- * @param direction Endpoint direction (in/out).
- * @return Error code.
- */
-int usb_pipe_initialize(usb_pipe_t *pipe, usb_endpoint_t endpoint_no,
-    usb_transfer_type_t transfer_type, size_t max_packet_size,
-    usb_direction_t direction, unsigned packets,
-    unsigned max_burst, unsigned max_streams, unsigned bytes_per_interval,
-	unsigned mult, usb_dev_session_t *bus_session)
+ * @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;
-	// FIXME: refactor this function PLEASE
-	assert(pipe);
-
-	pipe->desc.endpoint_no = endpoint_no;
-	pipe->desc.transfer_type = transfer_type;
-	pipe->desc.packets = packets;
-	pipe->desc.max_packet_size = max_packet_size;
-	pipe->desc.direction = direction;
-	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;
+	assert(pipe);
+
+	pipe->desc = *ep_desc;
 	pipe->auto_reset_halt = false;
 	pipe->bus_session = bus_session;
 
-	// TODO: hardcoded, remake to receive from device descriptors
-	pipe->desc.interval = 14;
-
-	if (transfer_type == USB_TRANSFER_ISOCHRONOUS) {
+	if (pipe->desc.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
 		ret = usb_isoch_session_initialize(pipe);
 	}
@@ -309,20 +293,19 @@
 }
 
+static const usb_endpoint_desc_t default_control_ep_desc = {
+	.max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
+	.direction = USB_DIRECTION_BOTH,
+	.packets = 1,
+};
+
 /** Initialize USB endpoint pipe as the default zero control pipe.
  *
  * @param pipe Endpoint pipe to be initialized.
- * @return Error code.
- */
-int usb_pipe_initialize_default_control(usb_pipe_t *pipe,
-    usb_dev_session_t *bus_session)
-{
-	assert(pipe);
-
-	const int rc = usb_pipe_initialize(pipe, 0, USB_TRANSFER_CONTROL,
-	    CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, 0, 0, 0, 0, bus_session);
-
-	pipe->auto_reset_halt = true;
-
-	return rc;
+ * @param bus_session
+ * @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); 
 }
 
Index: uspace/lib/usbdev/src/pipesinit.c
===================================================================
--- uspace/lib/usbdev/src/pipesinit.c	(revision 35c37fc2ef57407c4bf38bf0ac3d777777e3ccd1)
+++ uspace/lib/usbdev/src/pipesinit.c	(revision 9e5b1621f4f41683f532e53cb098ad63a69b19a0)
@@ -208,28 +208,35 @@
 	}
 
-	unsigned max_burst = 0;
-	unsigned max_streams = 0;
-	unsigned bytes_per_interval = 0;
-	unsigned mult = 0;
+	usb_endpoint_desc_t ep_desc = {
+		.endpoint_no = ep_no,
+		.transfer_type = description.transfer_type,
+		.direction = description.direction,
+		// 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)),
+	};
+
+	/* TODO Extract USB2-related information */
+	ep_desc.usb2 = (usb2_endpoint_desc_t) { 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
-	// 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
-	int rc = usb_pipe_initialize(&ep_mapping->pipe,
-	    ep_no, description.transfer_type,
-	    ED_MPS_PACKET_SIZE_GET(
-	        uint16_usb2host(endpoint_desc->max_packet_size)),
-	    description.direction, ED_MPS_TRANS_OPPORTUNITIES_GET(
-	        uint16_usb2host(endpoint_desc->max_packet_size)),
-	    max_burst, max_streams, bytes_per_interval, mult, bus_session);
-	if (rc != EOK) {
-		return rc;
-	}
+		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),
+		};
+	}
+
+	int err = usb_pipe_initialize(&ep_mapping->pipe, bus_session, &ep_desc);
+	if (err)
+		return err;
 
 	ep_mapping->present = true;
