Index: uspace/lib/usbdev/include/usb/dev/driver.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/driver.h	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/usbdev/include/usb/dev/driver.h	(revision b80c1ab4fd7df617a684e9fc7af13b2626a47d6e)
@@ -48,4 +48,8 @@
 	/** Callback when a device was removed from the system. */
 	int (*device_gone)(usb_device_t *);
+	/** Callback asking the driver to online a specific function. */
+	int (*function_online)(ddf_fun_t *);
+	/** Callback asking the driver to offline a specific function. */
+	int (*function_offline)(ddf_fun_t *);
 } usb_driver_ops_t;
 
Index: uspace/lib/usbdev/include/usb/dev/pipes.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/pipes.h	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/usbdev/include/usb/dev/pipes.h	(revision b80c1ab4fd7df617a684e9fc7af13b2626a47d6e)
@@ -50,25 +50,10 @@
  */
 typedef struct {
-	/** Endpoint number. */
-	usb_endpoint_t endpoint_no;
-
-	/** Endpoint transfer type. */
-	usb_transfer_type_t transfer_type;
-
-	/** Endpoint direction. */
-	usb_direction_t direction;
-
-	/** Maximum packet size for the endpoint. */
-	size_t max_packet_size;
-
-	/** Number of packets per frame/uframe.
-	 * Only valid for HS INT and ISO transfers. All others should set to 1*/
-	unsigned packets;
-
+	/** Endpoint description */
+	usb_endpoint_desc_t desc;
 	/** Whether to automatically reset halt on the endpoint.
 	 * Valid only for control endpoint zero.
 	 */
 	bool auto_reset_halt;
-
 	/** The connection used for sending the data. */
 	usb_dev_session_t *bus_session;
@@ -103,4 +88,6 @@
 	/** Found descriptor fitting the description. */
 	const usb_standard_endpoint_descriptor_t *descriptor;
+	/** Relevant superspeed companion descriptor. */
+	const usb_superspeed_endpoint_companion_descriptor_t *companion_descriptor;
 	/** Interface descriptor the endpoint belongs to. */
 	const usb_standard_interface_descriptor_t *interface;
@@ -110,5 +97,5 @@
 
 int usb_pipe_initialize(usb_pipe_t *, usb_endpoint_t, usb_transfer_type_t,
-    size_t, usb_direction_t, unsigned, usb_dev_session_t *);
+    size_t, usb_direction_t, unsigned, unsigned, unsigned, usb_dev_session_t *);
 int usb_pipe_initialize_default_control(usb_pipe_t *, usb_dev_session_t *);
 
Index: uspace/lib/usbdev/src/devdrv.c
===================================================================
--- uspace/lib/usbdev/src/devdrv.c	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/usbdev/src/devdrv.c	(revision b80c1ab4fd7df617a684e9fc7af13b2626a47d6e)
@@ -56,11 +56,11 @@
 	/** Connection to device on USB bus */
 	usb_dev_session_t *bus_session;
-	
+
 	/** devman handle */
 	devman_handle_t handle;
-	
+
 	/** The default control pipe. */
 	usb_pipe_t ctrl_pipe;
-	
+
 	/** Other endpoint pipes.
 	 *
@@ -69,8 +69,8 @@
 	 */
 	usb_endpoint_mapping_t *pipes;
-	
+
 	/** Number of other endpoint pipes. */
 	size_t pipes_count;
-	
+
 	/** Current interface.
 	 *
@@ -79,14 +79,14 @@
 	 */
 	int interface_no;
-	
+
 	/** Alternative interfaces. */
 	usb_alternate_interfaces_t alternate_interfaces;
-	
+
 	/** Some useful descriptors for USB device. */
 	usb_device_descriptors_t descriptors;
-	
+
 	/** Generic DDF device backing this one. DO NOT TOUCH! */
 	ddf_dev_t *ddf_dev;
-	
+
 	/** Custom driver data.
 	 *
@@ -146,5 +146,5 @@
 		return rc;
 	}
-	
+
 	/* Change current alternative */
 	usb_dev->alternate_interfaces.current = alternate_setting;
@@ -296,5 +296,5 @@
 	assert(usb_dev);
 	assert(usb_dev->pipes || usb_dev->pipes_count == 0);
-	
+
 	/* Destroy the pipes. */
 	for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
@@ -304,5 +304,5 @@
 			usb_pipe_unregister(&usb_dev->pipes[i].pipe);
 	}
-	
+
 	free(usb_dev->pipes);
 	usb_dev->pipes = NULL;
@@ -332,5 +332,5 @@
 	assert(usb_dev);
 	for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
-		if (usb_dev->pipes[i].pipe.endpoint_no == ep)
+		if (usb_dev->pipes[i].pipe.desc.endpoint_no == ep)
 			return &usb_dev->pipes[i];
 	}
@@ -462,9 +462,9 @@
 	assert(handle);
 	assert(iface_no);
-	
+
 	async_exch_t *exch = async_exchange_begin(sess);
 	if (!exch)
 		return EPARTY;
-	
+
 	int ret = usb_get_my_device_handle(exch, handle);
 	if (ret == EOK) {
@@ -475,5 +475,5 @@
 		}
 	}
-	
+
 	async_exchange_end(exch);
 	return ret;
@@ -502,5 +502,5 @@
 		return ENOMEM;
 	}
-	
+
 	return usb_device_init(usb_dev, ddf_dev, desc, err, h, iface_no);
 }
Index: uspace/lib/usbdev/src/devpoll.c
===================================================================
--- uspace/lib/usbdev/src/devpoll.c	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/usbdev/src/devpoll.c	(revision b80c1ab4fd7df617a684e9fc7af13b2626a47d6e)
@@ -96,5 +96,5 @@
 		    (int) mapping->interface->interface_subclass,
 		    (int) mapping->interface->interface_protocol,
-		    data->request_size, pipe->max_packet_size);
+		    data->request_size, pipe->desc.max_packet_size);
 	}
 
@@ -128,5 +128,5 @@
 			usb_request_clear_endpoint_halt(
 			    usb_device_get_default_pipe(data->dev),
-			    pipe->endpoint_no);
+			    pipe->desc.endpoint_no);
 		}
 
@@ -156,5 +156,5 @@
 
 		/* Take a rest before next request. */
-		
+
 		// FIXME TODO: This is broken, the time is in ms not us.
 		// but first we need to fix drivers to actually stop using this,
@@ -216,9 +216,9 @@
 	if (request_size == 0)
 		return EINVAL;
-	
-	if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||
-	    (epm->pipe.direction != USB_DIRECTION_IN))
+
+	if (!epm || (epm->pipe.desc.transfer_type != USB_TRANSFER_INTERRUPT) ||
+	    (epm->pipe.desc.direction != USB_DIRECTION_IN))
 		return EINVAL;
-	
+
 
 	polling_data_t *polling_data = malloc(sizeof(polling_data_t));
Index: uspace/lib/usbdev/src/driver.c
===================================================================
--- uspace/lib/usbdev/src/driver.c	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/usbdev/src/driver.c	(revision b80c1ab4fd7df617a684e9fc7af13b2626a47d6e)
@@ -117,8 +117,42 @@
 }
 
+/** Callback when the driver is asked to online a specific function.
+ *
+ * This callback is a wrapper for USB specific version of @c fun_online.
+ *
+ * @param gen_dev Device function structure as prepared by DDF.
+ * @return Error code.
+ */
+static int generic_function_online(ddf_fun_t *fun)
+{
+	assert(driver);
+	assert(driver->ops);
+	if (driver->ops->function_online == NULL)
+		return ENOTSUP;
+	return driver->ops->function_online(fun);
+}
+
+/** Callback when the driver is asked to offline a specific function.
+ *
+ * This callback is a wrapper for USB specific version of @c fun_offline.
+ *
+ * @param gen_dev Device function structure as prepared by DDF.
+ * @return Error code.
+ */
+static int generic_function_offline(ddf_fun_t *fun)
+{
+	assert(driver);
+	assert(driver->ops);
+	if (driver->ops->function_offline == NULL)
+		return ENOTSUP;
+	return driver->ops->function_offline(fun);
+}
+
 static driver_ops_t generic_driver_ops = {
 	.dev_add = generic_device_add,
 	.dev_remove = generic_device_remove,
 	.dev_gone = generic_device_gone,
+	.fun_online = generic_function_online,
+	.fun_offline = generic_function_offline,
 };
 static driver_t generic_driver = {
Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/usbdev/src/pipes.c	(revision b80c1ab4fd7df617a684e9fc7af13b2626a47d6e)
@@ -36,5 +36,5 @@
 #include <usb/dev/request.h>
 #include <usb/usb.h>
-#include <usb_iface.h>
+#include <usbhc_iface.h>
 
 #include <assert.h>
@@ -51,5 +51,5 @@
 	assert(pipe != NULL);
 
-	if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) {
+	if (!pipe->auto_reset_halt || (pipe->desc.endpoint_no != 0)) {
 		return;
 	}
@@ -88,6 +88,6 @@
 	}
 
-	if ((pipe->direction != USB_DIRECTION_BOTH)
-	    || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
+	if ((pipe->desc.direction != USB_DIRECTION_BOTH)
+	    || (pipe->desc.transfer_type != USB_TRANSFER_CONTROL)) {
 		return EBADF;
 	}
@@ -98,5 +98,5 @@
 	async_exch_t *exch = async_exchange_begin(pipe->bus_session);
 	size_t act_size = 0;
-	const int rc = usb_read(exch, pipe->endpoint_no, setup_packet, buffer,
+	const int rc = usbhc_read(exch, pipe->desc.endpoint_no, setup_packet, buffer,
 	    buffer_size, &act_size);
 	async_exchange_end(exch);
@@ -142,6 +142,6 @@
 	}
 
-	if ((pipe->direction != USB_DIRECTION_BOTH)
-	    || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
+	if ((pipe->desc.direction != USB_DIRECTION_BOTH)
+	    || (pipe->desc.transfer_type != USB_TRANSFER_CONTROL)) {
 		return EBADF;
 	}
@@ -151,6 +151,6 @@
 
 	async_exch_t *exch = async_exchange_begin(pipe->bus_session);
-	const int rc = usb_write(exch,
-	    pipe->endpoint_no, setup_packet, buffer, buffer_size);
+	const int rc = usbhc_write(exch,
+	    pipe->desc.endpoint_no, setup_packet, buffer, buffer_size);
 	async_exchange_end(exch);
 
@@ -183,15 +183,15 @@
 	}
 
-	if (pipe->direction != USB_DIRECTION_IN) {
-		return EBADF;
-	}
-
-	if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
+	if (pipe->desc.direction != USB_DIRECTION_IN) {
+		return EBADF;
+	}
+
+	if (pipe->desc.transfer_type == USB_TRANSFER_CONTROL) {
 		return EBADF;
 	}
 
 	/* Isochronous transfer are not supported (yet) */
-	if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
-	    pipe->transfer_type != USB_TRANSFER_BULK)
+	if (pipe->desc.transfer_type != USB_TRANSFER_INTERRUPT &&
+	    pipe->desc.transfer_type != USB_TRANSFER_BULK)
 	    return ENOTSUP;
 
@@ -199,5 +199,5 @@
 	size_t act_size = 0;
 	const int rc =
-	    usb_read(exch, pipe->endpoint_no, 0, buffer, size, &act_size);
+	    usbhc_read(exch, pipe->desc.endpoint_no, 0, buffer, size, &act_size);
 	async_exchange_end(exch);
 
@@ -224,19 +224,19 @@
 	}
 
-	if (pipe->direction != USB_DIRECTION_OUT) {
-		return EBADF;
-	}
-
-	if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
+	if (pipe->desc.direction != USB_DIRECTION_OUT) {
+		return EBADF;
+	}
+
+	if (pipe->desc.transfer_type == USB_TRANSFER_CONTROL) {
 		return EBADF;
 	}
 
 	/* Isochronous transfer are not supported (yet) */
-	if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
-	    pipe->transfer_type != USB_TRANSFER_BULK)
+	if (pipe->desc.transfer_type != USB_TRANSFER_INTERRUPT &&
+	    pipe->desc.transfer_type != USB_TRANSFER_BULK)
 	    return ENOTSUP;
 
 	async_exch_t *exch = async_exchange_begin(pipe->bus_session);
-	const int rc = usb_write(exch, pipe->endpoint_no, 0, buffer, size);
+	const int rc = usbhc_write(exch, pipe->desc.endpoint_no, 0, buffer, size);
 	async_exchange_end(exch);
 	return rc;
@@ -254,13 +254,17 @@
 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, usb_dev_session_t *bus_session)
-{
-	assert(pipe);
-
-	pipe->endpoint_no = endpoint_no;
-	pipe->transfer_type = transfer_type;
-	pipe->packets = packets;
-	pipe->max_packet_size = max_packet_size;
-	pipe->direction = direction;
+    usb_direction_t direction, unsigned packets,
+    unsigned max_burst, unsigned max_streams, usb_dev_session_t *bus_session)
+{
+	// FIXME refactor this function
+	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->auto_reset_halt = false;
 	pipe->bus_session = bus_session;
@@ -280,5 +284,5 @@
 
 	const int rc = usb_pipe_initialize(pipe, 0, USB_TRANSFER_CONTROL,
-	    CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, bus_session);
+	    CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, 0, 0, bus_session);
 
 	pipe->auto_reset_halt = true;
@@ -297,10 +301,12 @@
 	assert(pipe);
 	assert(pipe->bus_session);
+
+	pipe->desc.usb2.polling_interval = interval;
 	async_exch_t *exch = async_exchange_begin(pipe->bus_session);
 	if (!exch)
 		return ENOMEM;
-	const int ret = usb_register_endpoint(exch, pipe->endpoint_no,
-	    pipe->transfer_type, pipe->direction, pipe->max_packet_size,
-	    pipe->packets, interval);
+
+	const int ret = usbhc_register_endpoint(exch, &pipe->desc);
+
 	async_exchange_end(exch);
 	return ret;
@@ -319,6 +325,7 @@
 	if (!exch)
 		return ENOMEM;
-	const int ret = usb_unregister_endpoint(exch, pipe->endpoint_no,
-	    pipe->direction);
+
+	const int ret = usbhc_unregister_endpoint(exch, &pipe->desc);
+
 	async_exchange_end(exch);
 	return ret;
Index: uspace/lib/usbdev/src/pipesinit.c
===================================================================
--- uspace/lib/usbdev/src/pipesinit.c	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/usbdev/src/pipesinit.c	(revision b80c1ab4fd7df617a684e9fc7af13b2626a47d6e)
@@ -38,4 +38,5 @@
 #include <usb/dev/request.h>
 #include <usb/usb.h>
+#include <usb/debug.h>
 #include <usb/descriptor.h>
 
@@ -59,4 +60,5 @@
 	NESTING(INTERFACE, HID),
 	NESTING(HID, HID_REPORT),
+	NESTING(ENDPOINT, SSPEED_EP_COMPANION),
 	LAST_NESTING
 };
@@ -70,4 +72,14 @@
 {
 	return descriptor[1] == USB_DESCTYPE_ENDPOINT;
+}
+
+/** Tells whether given descriptor is of superspeed companion type.
+ *
+ * @param descriptor Descriptor in question.
+ * @return Whether the given descriptor is superspeed companion descriptor.
+ */
+static inline bool is_superspeed_companion_descriptor(const uint8_t *descriptor)
+{
+	return descriptor[1] == USB_DESCTYPE_SSPEED_EP_COMPANION;
 }
 
@@ -150,4 +162,5 @@
  * @param interface Interface descriptor under which belongs the @p endpoint.
  * @param endpoint Endpoint descriptor.
+ * @param companion Superspeed companion descriptor.
  * @return Error code.
  */
@@ -156,4 +169,5 @@
     usb_standard_interface_descriptor_t *interface,
     usb_standard_endpoint_descriptor_t *endpoint_desc,
+    usb_superspeed_endpoint_companion_descriptor_t *companion_desc,
     usb_dev_session_t *bus_session)
 {
@@ -194,11 +208,18 @@
 	}
 
+	unsigned max_burst = 0;
+	unsigned max_streams = 0;
+	if(companion_desc) {
+		max_burst = companion_desc->max_burst;
+		max_streams = SS_COMPANION_MAX_STREAMS(companion_desc->attributes);
+	}
+
 	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)), bus_session);
+	    description.direction, ED_MPS_TRANS_OPPORTUNITIES_GET(
+	        uint16_usb2host(endpoint_desc->max_packet_size)),
+	    max_burst, max_streams, bus_session);
 	if (rc != EOK) {
 		return rc;
@@ -207,4 +228,5 @@
 	ep_mapping->present = true;
 	ep_mapping->descriptor = endpoint_desc;
+	ep_mapping->companion_descriptor = companion_desc;
 	ep_mapping->interface = interface;
 
@@ -235,4 +257,12 @@
 	do {
 		if (is_endpoint_descriptor(descriptor)) {
+			/* Check if companion descriptor is present too, it should immediatelly follow. */
+			const uint8_t *companion_desc = usb_dp_get_nested_descriptor(parser,
+				parser_data, descriptor);
+			if (companion_desc && !is_superspeed_companion_descriptor(companion_desc)) {
+				/* Not what we wanted, don't pass it further. */
+				companion_desc = NULL;
+			}
+
 			(void) process_endpoint(mapping, mapping_count,
 			    (usb_standard_interface_descriptor_t *)
@@ -240,4 +270,6 @@
 			    (usb_standard_endpoint_descriptor_t *)
 			        descriptor,
+			    (usb_superspeed_endpoint_companion_descriptor_t *)
+			        companion_desc,
 			    bus_session);
 		}
@@ -288,5 +320,5 @@
 	if (config_descriptor == NULL)
 		return EBADMEM;
-	
+
 	if (config_descriptor_size <
 	    sizeof(usb_standard_configuration_descriptor_t)) {
@@ -343,7 +375,7 @@
 	static_assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE);
 
-	if ((pipe->direction != USB_DIRECTION_BOTH) ||
-	    (pipe->transfer_type != USB_TRANSFER_CONTROL) ||
-	    (pipe->endpoint_no != 0)) {
+	if ((pipe->desc.direction != USB_DIRECTION_BOTH) ||
+	    (pipe->desc.transfer_type != USB_TRANSFER_CONTROL) ||
+	    (pipe->desc.endpoint_no != 0)) {
 		return EINVAL;
 	}
@@ -369,5 +401,5 @@
 	}
 
-	pipe->max_packet_size
+	pipe->desc.max_packet_size
 	    = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];
 
Index: uspace/lib/usbdev/src/request.c
===================================================================
--- uspace/lib/usbdev/src/request.c	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/usbdev/src/request.c	(revision b80c1ab4fd7df617a684e9fc7af13b2626a47d6e)
@@ -844,5 +844,5 @@
 	}
 	return usb_request_clear_endpoint_halt(ctrl_pipe,
-	    target_pipe->endpoint_no);
+	    target_pipe->desc.endpoint_no);
 }
 
@@ -858,5 +858,5 @@
 {
 	uint16_t status_tmp;
-	uint16_t pipe_index = (uint16_t) pipe->endpoint_no;
+	uint16_t pipe_index = (uint16_t) pipe->desc.endpoint_no;
 	int rc = usb_request_get_status(ctrl_pipe,
 	    USB_REQUEST_RECIPIENT_ENDPOINT, uint16_host2usb(pipe_index),
