Index: uspace/lib/usbdev/src/devdrv.c
===================================================================
--- uspace/lib/usbdev/src/devdrv.c	(revision 0c0f823be60de51c77b4a379e049bb77bd2df4bc)
+++ uspace/lib/usbdev/src/devdrv.c	(revision 4291215b8cf3045e4106151a70b74f21b175018d)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2011 Vojtech Horky
+ * Copyright (c) 2011 Jan Vesely
  * All rights reserved.
  *
@@ -26,5 +27,4 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
 /** @addtogroup libusbdev
  * @{
@@ -36,5 +36,5 @@
 #include <usb/dev/request.h>
 #include <usb/debug.h>
-#include <usb/dev/dp.h>
+#include <usb/dev.h>
 #include <errno.h>
 #include <str_error.h>
@@ -56,5 +56,4 @@
 static const usb_driver_t *driver = NULL;
 
-
 /** Main routine of USB device driver.
  *
@@ -75,5 +74,5 @@
 	return ddf_driver_main(&generic_driver);
 }
-
+/*----------------------------------------------------------------------------*/
 /** Count number of pipes the driver expects.
  *
@@ -85,40 +84,6 @@
 {
 	size_t count;
-	for (count = 0; endpoints && endpoints[count] != NULL; ++count);
+	for (count = 0; endpoints != NULL && endpoints[count] != NULL; ++count);
 	return count;
-}
-
-/** Initialize endpoint pipes, excluding default control one.
- *
- * @param drv The device driver.
- * @param dev Device to be initialized.
- * @return Error code.
- */
-static int initialize_other_pipes(const usb_endpoint_description_t **endpoints,
-    usb_device_t *dev, int alternate_setting)
-{
-	assert(dev);
-
-	if (endpoints == NULL) {
-		dev->pipes = NULL;
-		dev->pipes_count = 0;
-		return EOK;
-	}
-
-	usb_endpoint_mapping_t *pipes;
-	size_t pipes_count;
-
-	int rc = usb_device_create_pipes(dev->ddf_dev, &dev->wire, endpoints,
-	    dev->descriptors.configuration, dev->descriptors.configuration_size,
-	    dev->interface_no, alternate_setting, &pipes, &pipes_count);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	dev->pipes = pipes;
-	dev->pipes_count = pipes_count;
-
-	return EOK;
 }
 /*----------------------------------------------------------------------------*/
@@ -136,4 +101,5 @@
 	assert(driver->ops->device_add);
 
+	/* Get place for driver data. */
 	usb_device_t *dev = ddf_dev_data_alloc(gen_dev, sizeof(usb_device_t));
 	if (dev == NULL) {
@@ -142,4 +108,6 @@
 		return ENOMEM;
 	}
+
+	/* Initialize generic USB driver data. */
 	const char *err_msg = NULL;
 	int rc = usb_device_init(dev, gen_dev, driver->endpoints, &err_msg);
@@ -150,4 +118,5 @@
 	}
 
+	/* Start USB driver specific initialization. */
 	rc = driver->ops->device_add(dev);
 	if (rc != EOK)
@@ -169,6 +138,11 @@
 	if (driver->ops->device_rem == NULL)
 		return ENOTSUP;
-	/* Just tell the driver to stop whatever it is doing, keep structures */
-	return driver->ops->device_rem(gen_dev->driver_data);
+	/* Just tell the driver to stop whatever it is doing */
+	usb_device_t *usb_dev = gen_dev->driver_data;
+	const int ret = driver->ops->device_rem(usb_dev);
+	if (ret != EOK)
+		return ret;
+	usb_device_deinit(usb_dev);
+	return EOK;
 }
 /*----------------------------------------------------------------------------*/
@@ -197,20 +171,12 @@
  *
  * @param dev Device where to destroy the pipes.
- * @return Error code.
- */
-static int destroy_current_pipes(usb_device_t *dev)
-{
-	int rc = usb_device_destroy_pipes(dev->ddf_dev,
-	    dev->pipes, dev->pipes_count);
-	if (rc != EOK) {
-		return rc;
-	}
-
+ */
+static void destroy_current_pipes(usb_device_t *dev)
+{
+	usb_device_destroy_pipes(dev->pipes, dev->pipes_count);
 	dev->pipes = NULL;
 	dev->pipes_count = 0;
-
-	return EOK;
-}
-
+}
+/*----------------------------------------------------------------------------*/
 /** Change interface setting of a device.
  * This function selects new alternate setting of an interface by issuing
@@ -242,14 +208,9 @@
 	}
 
-	int rc;
-
 	/* Destroy existing pipes. */
-	rc = destroy_current_pipes(dev);
-	if (rc != EOK) {
-		return rc;
-	}
+	destroy_current_pipes(dev);
 
 	/* Change the interface itself. */
-	rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
+	int rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
 	    alternate_setting);
 	if (rc != EOK) {
@@ -258,5 +219,8 @@
 
 	/* Create new pipes. */
-	rc = initialize_other_pipes(endpoints, dev, (int) alternate_setting);
+	rc = usb_device_create_pipes(&dev->wire, endpoints,
+	    dev->descriptors.configuration, dev->descriptors.configuration_size,
+	    dev->interface_no, (int)alternate_setting,
+	    &dev->pipes, &dev->pipes_count);
 
 	return rc;
@@ -316,5 +280,4 @@
  * - registers endpoints with the host controller
  *
- * @param[in] dev Generic DDF device backing the USB one.
  * @param[in] wire Initialized backing connection to the host controller.
  * @param[in] endpoints Endpoints description, NULL terminated.
@@ -329,5 +292,5 @@
  * @return Error code.
  */
-int usb_device_create_pipes(const ddf_dev_t *dev, usb_device_connection_t *wire,
+int usb_device_create_pipes(usb_device_connection_t *wire,
     const usb_endpoint_description_t **endpoints,
     const uint8_t *config_descr, size_t config_descr_size,
@@ -335,7 +298,5 @@
     usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr)
 {
-	assert(dev != NULL);
 	assert(wire != NULL);
-	assert(endpoints != NULL);
 	assert(config_descr != NULL);
 	assert(config_descr_size > 0);
@@ -359,5 +320,5 @@
 	}
 
-	/* Now allocate and fully initialize. */
+	/* Now initialize. */
 	for (i = 0; i < pipe_count; i++) {
 		pipes[i].description = endpoints[i];
@@ -370,23 +331,13 @@
 	    config_descr, config_descr_size, wire);
 	if (rc != EOK) {
-		goto rollback_free_only;
-	}
-
-	/* Register the endpoints with HC. */
-	usb_hc_connection_t hc_conn;
-	rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
-	if (rc != EOK) {
-		goto rollback_free_only;
-	}
-
-	rc = usb_hc_connection_open(&hc_conn);
-	if (rc != EOK) {
-		goto rollback_free_only;
-	}
-
+		free(pipes);
+		return rc;
+	}
+
+	/* Register created pipes. */
 	for (i = 0; i < pipe_count; i++) {
 		if (pipes[i].present) {
 			rc = usb_pipe_register(&pipes[i].pipe,
-			    pipes[i].descriptor->poll_interval, &hc_conn);
+			    pipes[i].descriptor->poll_interval);
 			if (rc != EOK) {
 				goto rollback_unregister_endpoints;
@@ -394,8 +345,4 @@
 		}
 	}
-
-	if (usb_hc_connection_close(&hc_conn) != EOK)
-		usb_log_warning("%s: Failed to close connection.\n",
-		    __FUNCTION__);
 
 	*pipes_ptr = pipes;
@@ -415,20 +362,9 @@
 	for (i = 0; i < pipe_count; i++) {
 		if (pipes[i].present) {
-			usb_pipe_unregister(&pipes[i].pipe, &hc_conn);
+			usb_pipe_unregister(&pipes[i].pipe);
 		}
 	}
 
-	if (usb_hc_connection_close(&hc_conn) != EOK)
-		usb_log_warning("usb_device_create_pipes(): "
-		    "Failed to close connection.\n");
-
-	/*
-	 * Jump here if something went wrong before some actual communication
-	 * with HC. Then the only thing that needs to be done is to free
-	 * allocated memory.
-	 */
-rollback_free_only:
 	free(pipes);
-
 	return rc;
 }
@@ -436,48 +372,18 @@
 /** Destroy pipes previously created by usb_device_create_pipes.
  *
- * @param[in] dev Generic DDF device backing the USB one.
  * @param[in] pipes Endpoint mapping to be destroyed.
  * @param[in] pipes_count Number of endpoints.
  */
-int usb_device_destroy_pipes(const ddf_dev_t *dev,
-    usb_endpoint_mapping_t *pipes, size_t pipes_count)
-{
-	assert(dev != NULL);
-
-	if (pipes_count == 0) {
-		assert(pipes == NULL);
-		return EOK;
-	}
-	assert(pipes != NULL);
-
-	int rc;
-
-	/* Prepare connection to HC to allow endpoint unregistering. */
-	usb_hc_connection_t hc_conn;
-	rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
-	if (rc != EOK) {
-		return rc;
-	}
-	rc = usb_hc_connection_open(&hc_conn);
-	if (rc != EOK) {
-		return rc;
-	}
-
+void usb_device_destroy_pipes(usb_endpoint_mapping_t *pipes, size_t pipes_count)
+{
 	/* Destroy the pipes. */
-	size_t i;
-	for (i = 0; i < pipes_count; i++) {
-		usb_log_debug2("Unregistering pipe %zu (%spresent).\n",
+	for (size_t i = 0; i < pipes_count; ++i) {
+		assert(pipes);
+		usb_log_debug2("Unregistering pipe %zu: %spresent.\n",
 		    i, pipes[i].present ? "" : "not ");
 		if (pipes[i].present)
-			usb_pipe_unregister(&pipes[i].pipe, &hc_conn);
-	}
-
-	if (usb_hc_connection_close(&hc_conn) != EOK)
-		usb_log_warning("usb_device_destroy_pipes(): "
-		    "Failed to close connection.\n");
-
+			usb_pipe_unregister(&pipes[i].pipe);
+	}
 	free(pipes);
-
-	return EOK;
 }
 
@@ -505,7 +411,21 @@
 	usb_dev->pipes = NULL;
 
+	/* Get assigned params */
+	devman_handle_t hc_handle;
+	usb_address_t address;
+
+	int rc = usb_get_info_by_handle(ddf_dev->handle,
+	    &hc_handle, &address, &usb_dev->interface_no);
+	if (rc != EOK) {
+		*errstr_ptr = "device parameters retrieval";
+		return rc;
+	}
+
+	/* Initialize hc connection. */
+	usb_hc_connection_initialize(&usb_dev->hc_conn, hc_handle);
+
 	/* Initialize backing wire and control pipe. */
-	int rc = usb_device_connection_initialize_from_device(
-	    &usb_dev->wire, ddf_dev);
+	rc = usb_device_connection_initialize(
+	    &usb_dev->wire, &usb_dev->hc_conn, address);
 	if (rc != EOK) {
 		*errstr_ptr = "device connection initialization";
@@ -515,6 +435,6 @@
 	/* This pipe was registered by the hub driver,
 	 * during device initialization. */
-	rc = usb_pipe_initialize_default_control(&usb_dev->ctrl_pipe,
-	    &usb_dev->wire);
+	rc = usb_pipe_initialize_default_control(
+	    &usb_dev->ctrl_pipe, &usb_dev->wire);
 	if (rc != EOK) {
 		*errstr_ptr = "default control pipe initialization";
@@ -522,12 +442,17 @@
 	}
 
-	/* Get our interface. */
-	usb_dev->interface_no = usb_device_get_assigned_interface(ddf_dev);
+	/* Open hc connection for pipe registration. */
+	rc = usb_hc_connection_open(&usb_dev->hc_conn);
+	if (rc != EOK) {
+		*errstr_ptr = "hc connection open";
+		return rc;
+	}
 
 	/* Retrieve standard descriptors. */
-	rc = usb_device_retrieve_descriptors(&usb_dev->ctrl_pipe,
-	    &usb_dev->descriptors);
+	rc = usb_device_retrieve_descriptors(
+	    &usb_dev->ctrl_pipe, &usb_dev->descriptors);
 	if (rc != EOK) {
 		*errstr_ptr = "descriptor retrieval";
+		usb_hc_connection_close(&usb_dev->hc_conn);
 		return rc;
 	}
@@ -543,7 +468,12 @@
 	    (rc == EOK) ? usb_dev->alternate_interfaces.current : 0;
 
-	/* TODO Add comment here. */
-	rc = initialize_other_pipes(endpoints, usb_dev, alternate_iface);
-	if (rc != EOK) {
+	/* Create and register other pipes than default control (EP 0) */
+	rc = usb_device_create_pipes(&usb_dev->wire, endpoints,
+	    usb_dev->descriptors.configuration,
+	    usb_dev->descriptors.configuration_size,
+	    usb_dev->interface_no, (int)alternate_iface,
+	    &usb_dev->pipes, &usb_dev->pipes_count);
+	if (rc != EOK) {
+		usb_hc_connection_close(&usb_dev->hc_conn);
 		/* Full configuration descriptor is allocated. */
 		usb_device_release_descriptors(&usb_dev->descriptors);
@@ -554,4 +484,5 @@
 	}
 
+	usb_hc_connection_close(&usb_dev->hc_conn);
 	return EOK;
 }
@@ -566,13 +497,20 @@
 {
 	if (dev) {
+		/* Destroy existing pipes. */
+		destroy_current_pipes(dev);
 		/* Ignore errors and hope for the best. */
-		destroy_current_pipes(dev);
-
+		usb_hc_connection_deinitialize(&dev->hc_conn);
 		usb_alternate_interfaces_deinit(&dev->alternate_interfaces);
 		usb_device_release_descriptors(&dev->descriptors);
 		free(dev->driver_data);
-	}
-}
-
+		dev->driver_data = NULL;
+	}
+}
+
+/** Allocate driver specific data.
+ * @param usb_dev usb_device structure.
+ * @param size requested data size.
+ * @return Pointer to the newly allocated space, NULL on failure.
+ */
 void * usb_device_data_alloc(usb_device_t *usb_dev, size_t size)
 {
