Index: uspace/lib/usbdev/src/devdrv.c
===================================================================
--- uspace/lib/usbdev/src/devdrv.c	(revision 96ec0a98f3a2e1ddbe0af6578f3ff4e8a63b038b)
+++ uspace/lib/usbdev/src/devdrv.c	(revision 7d9cd628da1d41c8b4af968ca48767e44d0850f8)
@@ -140,15 +140,17 @@
 	assert(driver->ops->device_add);
 
-	int rc;
-
-	usb_device_t *dev = NULL;
+	usb_device_t *dev = ddf_dev_data_alloc(gen_dev, sizeof(usb_device_t));
+	if (dev == NULL) {
+		usb_log_error("USB device `%s' structure allocation failed.\n",
+		    gen_dev->name);
+		return ENOMEM;
+	}
 	const char *err_msg = NULL;
-	rc = usb_device_create(gen_dev, driver->endpoints, &dev, &err_msg);
-	if (rc != EOK) {
-		usb_log_error("USB device `%s' creation failed (%s): %s.\n",
+	int rc = usb_device_init(dev, gen_dev, driver->endpoints, &err_msg);
+	if (rc != EOK) {
+		usb_log_error("USB device `%s' init failed (%s): %s.\n",
 		    gen_dev->name, err_msg, str_error(rc));
 		return rc;
 	}
-	gen_dev->driver_data = dev;
 
 	rc = driver->ops->device_add(dev);
@@ -516,40 +518,28 @@
 
 
-/** Create new instance of USB device.
- *
+/** Initialize new instance of USB device.
+ *
+ * @param[in] usb_dev Pointer to the new device.
  * @param[in] ddf_dev Generic DDF device backing the USB one.
  * @param[in] endpoints NULL terminated array of endpoints (NULL for none).
- * @param[out] dev_ptr Where to store pointer to the new device.
  * @param[out] errstr_ptr Where to store description of context
  *	(in case error occurs).
  * @return Error code.
  */
-int usb_device_create(ddf_dev_t *ddf_dev,
-    const usb_endpoint_description_t **endpoints,
-    usb_device_t **dev_ptr, const char **errstr_ptr)
-{
-	assert(dev_ptr != NULL);
+int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
+    const usb_endpoint_description_t **endpoints, const char **errstr_ptr)
+{
+	assert(usb_dev != NULL);
 	assert(ddf_dev != NULL);
 
-	int rc;
-
-	usb_device_t *dev = malloc(sizeof(usb_device_t));
-	if (dev == NULL) {
-		*errstr_ptr = "structure allocation";
-		return ENOMEM;
-	}
-
-	// FIXME: proper deallocation in case of errors
-
-	dev->ddf_dev = ddf_dev;
-	dev->driver_data = NULL;
-	dev->descriptors.configuration = NULL;
-	dev->alternate_interfaces = NULL;
-
-	dev->pipes_count = 0;
-	dev->pipes = NULL;
+	usb_dev->ddf_dev = ddf_dev;
+	usb_dev->driver_data = NULL;
+	usb_dev->descriptors.configuration = NULL;
+	usb_dev->alternate_interfaces = NULL;
+	usb_dev->pipes_count = 0;
+	usb_dev->pipes = NULL;
 
 	/* Initialize backing wire and control pipe. */
-	rc = init_wire_and_ctrl_pipe(dev, errstr_ptr);
+	int rc = init_wire_and_ctrl_pipe(usb_dev, errstr_ptr);
 	if (rc != EOK) {
 		return rc;
@@ -557,25 +547,27 @@
 
 	/* Get our interface. */
-	dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
+	usb_dev->interface_no = usb_device_get_assigned_interface(ddf_dev);
 
 	/* Retrieve standard descriptors. */
-	rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe,
-	    &dev->descriptors);
-	if (rc != EOK) {
+	rc = usb_device_retrieve_descriptors(&usb_dev->ctrl_pipe,
+	    &usb_dev->descriptors);
+	if (rc != EOK) {
+		/* Nothing allocated, nothing to free. */
 		*errstr_ptr = "descriptor retrieval";
 		return rc;
 	}
 
-	/* Create alternate interfaces. */
-	rc = usb_alternate_interfaces_create(dev->descriptors.configuration,
-	    dev->descriptors.configuration_size, dev->interface_no,
-	    &dev->alternate_interfaces);
-	if (rc != EOK) {
-		/* We will try to silently ignore this. */
-		dev->alternate_interfaces = NULL;
-	}
-
-	rc = initialize_other_pipes(endpoints, dev, 0);
-	if (rc != EOK) {
+	/* Create alternate interfaces. We will silently ignore failure. */
+	//TODO Why ignore?
+	usb_alternate_interfaces_create(usb_dev->descriptors.configuration,
+	    usb_dev->descriptors.configuration_size, usb_dev->interface_no,
+	    &usb_dev->alternate_interfaces);
+
+	rc = initialize_other_pipes(endpoints, usb_dev, 0);
+	if (rc != EOK) {
+		/* Full configuration descriptor is allocated. */
+		free(usb_dev->descriptors.configuration);
+		/* Alternate interfaces may be allocated */
+		usb_alternate_interfaces_destroy(usb_dev->alternate_interfaces);
 		*errstr_ptr = "pipes initialization";
 		return rc;
@@ -583,10 +575,9 @@
 
 	*errstr_ptr = NULL;
-	*dev_ptr = dev;
 
 	return EOK;
 }
 
-/** Destroy instance of a USB device.
+/** Clean instance of a USB device.
  *
  * @param dev Device to be de-initialized.
@@ -596,17 +587,12 @@
 void usb_device_deinit(usb_device_t *dev)
 {
-	if (dev == NULL) {
-		return;
-	}
-
-	/* Ignore errors and hope for the best. */
-	destroy_current_pipes(dev);
-
-	if (dev->alternate_interfaces != NULL) {
-		free(dev->alternate_interfaces->alternatives);
-	}
-	free(dev->alternate_interfaces);
-	free(dev->descriptors.configuration);
-	free(dev->driver_data);
+	if (dev) {
+		/* Ignore errors and hope for the best. */
+		destroy_current_pipes(dev);
+
+		usb_alternate_interfaces_destroy(dev->alternate_interfaces);
+		free(dev->descriptors.configuration);
+		free(dev->driver_data);
+	}
 }
 
