Index: uspace/drv/usbmid/explore.c
===================================================================
--- uspace/drv/usbmid/explore.c	(revision 48d4231f406b1fda0a0c462ba0aa84cea1c6e84a)
+++ uspace/drv/usbmid/explore.c	(revision ecb107bc84e79baa507db5a2cae1a76a82a1da66)
@@ -48,21 +48,33 @@
 };
 
-/** Find starting indexes of all interface descriptors in a configuration.
- *
- * @param config_descriptor Full configuration descriptor.
- * @param config_descriptor_size Size of @p config_descriptor in bytes.
- * @param interface_positions Array where to store indexes of interfaces.
- * @param interface_count Size of @p interface_positions array.
- * @return Number of found interfaces.
- * @retval (size_t)-1 Error occured.
- */
-static size_t find_interface_descriptors(uint8_t *config_descriptor,
-    size_t config_descriptor_size,
-    size_t *interface_positions, size_t interface_count)
+/** Tell whether given interface is already in the list.
+ *
+ * @param list List of usbmid_interface_t members to be searched.
+ * @param interface_no Interface number caller is looking for.
+ * @return Interface @p interface_no is already present in the list.
+ */
+static bool interface_in_list(link_t *list, int interface_no)
 {
-	if (interface_count == 0) {
-		return (size_t) -1;
-	}
-
+	link_t *l;
+	for (l = list->next; l != list; l = l->next) {
+		usbmid_interface_t *iface
+		    = list_get_instance(l, usbmid_interface_t, link);
+		if (iface->interface_no == interface_no) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/** Create list of interfaces from configuration descriptor.
+ *
+ * @param config_descriptor Configuration descriptor.
+ * @param config_descriptor_size Size of configuration descriptor in bytes.
+ * @param list List where to add the interfaces.
+ */
+static void create_interfaces(uint8_t *config_descriptor,
+    size_t config_descriptor_size, link_t *list)
+{
 	usb_dp_parser_data_t data = {
 		.data = config_descriptor,
@@ -75,30 +87,43 @@
 	};
 
-	uint8_t *interface = usb_dp_get_nested_descriptor(&parser, &data,
+	uint8_t *interface_ptr = usb_dp_get_nested_descriptor(&parser, &data,
 	    data.data);
-	if (interface == NULL) {
-		return (size_t) -1;
-	}
-	if (interface[1] != USB_DESCTYPE_INTERFACE) {
-		return (size_t) -1;
-	}
-
-	size_t found_interfaces = 0;
-	interface_positions[found_interfaces] = interface - config_descriptor;
-	found_interfaces++;
-
-	while (interface != NULL) {
-		interface = usb_dp_get_sibling_descriptor(&parser, &data,
-		    data.data, interface);
-		if ((interface != NULL)
-		    && (found_interfaces < interface_count)
-		    && (interface[1] == USB_DESCTYPE_INTERFACE)) {
-			interface_positions[found_interfaces]
-			    = interface - config_descriptor;
-			found_interfaces++;
-		}
-	}
-
-	return found_interfaces;
+	if (interface_ptr == NULL) {
+		return;
+	}
+
+	do {
+		if (interface_ptr[1] != USB_DESCTYPE_INTERFACE) {
+			goto next_descriptor;
+		}
+
+		usb_standard_interface_descriptor_t *interface
+		    = (usb_standard_interface_descriptor_t *) interface_ptr;
+
+		/* Skip alternate interfaces. */
+		if (!interface_in_list(list, interface->interface_number)) {
+			usbmid_interface_t *iface
+			    = malloc(sizeof(usbmid_interface_t));
+			if (iface == NULL) {
+				break;
+			}
+			link_initialize(&iface->link);
+			iface->fun = NULL;
+			iface->interface_no = interface->interface_number;
+			iface->interface = interface;
+
+			list_append(&iface->link, list);
+		}
+
+		/* TODO: add the alternatives and create match ids from them
+		 * as well.
+		 */
+
+next_descriptor:
+		interface_ptr = usb_dp_get_sibling_descriptor(&parser, &data,
+		    data.data, interface_ptr);
+
+	} while (interface_ptr != NULL);
+
 }
 
@@ -130,23 +155,4 @@
 	    (usb_standard_configuration_descriptor_t *) config_descriptor_raw;
 
-	size_t *interface_descriptors
-	    = malloc(sizeof(size_t) * config_descriptor->interface_count);
-	if (interface_descriptors == NULL) {
-		usb_log_error("Out of memory (wanted %zuB).\n",
-		    sizeof(size_t) * config_descriptor->interface_count);
-		free(config_descriptor_raw);
-		return false;
-	}
-	size_t interface_descriptors_count
-	    = find_interface_descriptors(
-	    config_descriptor_raw, config_descriptor_size,
-	    interface_descriptors, config_descriptor->interface_count);
-
-	if (interface_descriptors_count == (size_t) -1) {
-		usb_log_error("Problem parsing configuration descriptor.\n");
-		free(interface_descriptors);
-		return false;
-	}
-
 	/* Select the first configuration */
 	rc = usb_request_set_configuration(&dev->ctrl_pipe,
@@ -155,8 +161,6 @@
 		usb_log_error("Failed to set device configuration: %s.\n",
 		    str_error(rc));
-		free(interface_descriptors);
-		return false;
-	}
-
+		return false;
+	}
 
 	/* Create control function */
@@ -164,5 +168,4 @@
 	if (ctl_fun == NULL) {
 		usb_log_error("Failed to create control function.\n");
-		free(interface_descriptors);
 		return false;
 	}
@@ -174,21 +177,25 @@
 		usb_log_error("Failed to bind control function: %s.\n",
 		    str_error(rc));
-		free(interface_descriptors);
-		return false;
-	}
-
-	/* Spawn interface children */
-	size_t i;
-	for (i = 0; i < interface_descriptors_count; i++) {
-		usb_standard_interface_descriptor_t *interface
-		    = (usb_standard_interface_descriptor_t *)
-		    (config_descriptor_raw + interface_descriptors[i]);
-		usb_log_debug2("Interface descriptor at index %zu (type %d).\n",
-		    interface_descriptors[i], (int) interface->descriptor_type);
+		return false;
+	}
+
+	/* Create interface children. */
+	link_t interface_list;
+	list_initialize(&interface_list);
+	create_interfaces(config_descriptor_raw, config_descriptor_size,
+	    &interface_list);
+
+	link_t *link;
+	for (link = interface_list.next; link != &interface_list;
+	    link = link->next) {
+		usbmid_interface_t *iface = list_get_instance(link,
+		    usbmid_interface_t, link);
+
 		usb_log_info("Creating child for interface %d (%s).\n",
-		    (int) interface->interface_number,
-		    usb_str_class(interface->interface_class));
-		rc = usbmid_spawn_interface_child(dev, &dev->descriptors.device,
-		    interface);
+		    (int) iface->interface_no,
+		    usb_str_class(iface->interface->interface_class));
+
+		rc = usbmid_spawn_interface_child(dev, iface,
+		    &dev->descriptors.device, iface->interface);
 		if (rc != EOK) {
 			usb_log_error("Failed to create interface child: %s.\n",
Index: uspace/drv/usbmid/usbmid.c
===================================================================
--- uspace/drv/usbmid/usbmid.c	(revision 48d4231f406b1fda0a0c462ba0aa84cea1c6e84a)
+++ uspace/drv/usbmid/usbmid.c	(revision ecb107bc84e79baa507db5a2cae1a76a82a1da66)
@@ -79,30 +79,9 @@
 };
 
-/** Create new interface for USB MID device.
- *
- * @param fun Backing generic DDF device function (representing interface).
- * @param iface_no Interface number.
- * @return New interface.
- * @retval NULL Error occured.
- */
-usbmid_interface_t *usbmid_interface_create(ddf_fun_t *fun, int iface_no)
-{
-	usbmid_interface_t *iface = malloc(sizeof(usbmid_interface_t));
-	if (iface == NULL) {
-		usb_log_error("Out of memory (wanted %zuB).\n",
-		    sizeof(usbmid_interface_t));
-		return NULL;
-	}
-
-	iface->fun = fun;
-	iface->interface_no = iface_no;
-
-	return iface;
-}
-
 
 /** Spawn new child device from one interface.
  *
  * @param parent Parent MID device.
+ * @param iface Interface information.
  * @param device_descriptor Device descriptor.
  * @param interface_descriptor Interface descriptor.
@@ -110,4 +89,5 @@
  */
 int usbmid_spawn_interface_child(usb_device_t *parent,
+    usbmid_interface_t *iface,
     const usb_standard_device_descriptor_t *device_descriptor,
     const usb_standard_interface_descriptor_t *interface_descriptor)
@@ -115,5 +95,4 @@
 	ddf_fun_t *child = NULL;
 	char *child_name = NULL;
-	usbmid_interface_t *child_as_interface = NULL;
 	int rc;
 
@@ -137,14 +116,7 @@
 	}
 
+	iface->fun = child;
 
-
-	child_as_interface = usbmid_interface_create(child,
-	    (int) interface_descriptor->interface_number);
-	if (child_as_interface == NULL) {
-		rc = ENOMEM;
-		goto error_leave;
-	}
-
-	child->driver_data = child_as_interface;
+	child->driver_data = iface;
 	child->ops = &child_device_ops;
 
@@ -172,7 +144,4 @@
 		free(child_name);
 	}
-	if (child_as_interface != NULL) {
-		free(child_as_interface);
-	}
 
 	return rc;
Index: uspace/drv/usbmid/usbmid.h
===================================================================
--- uspace/drv/usbmid/usbmid.h	(revision 48d4231f406b1fda0a0c462ba0aa84cea1c6e84a)
+++ uspace/drv/usbmid/usbmid.h	(revision ecb107bc84e79baa507db5a2cae1a76a82a1da66)
@@ -37,4 +37,5 @@
 #define USBMID_H_
 
+#include <adt/list.h>
 #include <ddf/driver.h>
 #include <usb/usb.h>
@@ -49,12 +50,14 @@
 	/** Function container. */
 	ddf_fun_t *fun;
-
+	/** Interface descriptor. */
+	usb_standard_interface_descriptor_t *interface;
 	/** Interface number. */
 	int interface_no;
+	/** List link. */
+	link_t link;
 } usbmid_interface_t;
 
-usbmid_interface_t *usbmid_interface_create(ddf_fun_t *, int);
 bool usbmid_explore_device(usb_device_t *);
-int usbmid_spawn_interface_child(usb_device_t *,
+int usbmid_spawn_interface_child(usb_device_t *, usbmid_interface_t *,
     const usb_standard_device_descriptor_t *,
     const usb_standard_interface_descriptor_t *);
