app: aboot: select usb controller to be used at runtime

Instead of compile time selection, query the target at runtime
to select the usb controller to be used for fastboot.

Change-Id: Ib0081b0813589781b96b8993358223db196d1dbb
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index f5495f9..afab5b9 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -1557,7 +1557,7 @@
 #endif
 
 	fastboot_okay("");
-	udc_stop();
+	fastboot_stop();
 
 	boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
 		   (const char*) hdr->cmdline, board_machtype(),
@@ -1957,7 +1957,7 @@
 void cmd_continue(const char *arg, void *data, unsigned sz)
 {
 	fastboot_okay("");
-	udc_stop();
+	fastboot_stop();
 	if (target_is_emmc_boot())
 	{
 		boot_linux_from_mmc();
diff --git a/app/aboot/fastboot.c b/app/aboot/fastboot.c
index 67bd760..fd0b9eb 100644
--- a/app/aboot/fastboot.c
+++ b/app/aboot/fastboot.c
@@ -38,6 +38,28 @@
 #include <dev/udc.h>
 #include "fastboot.h"
 
+#ifdef USB30_SUPPORT
+#include <usb30_udc.h>
+#endif
+
+typedef struct
+{
+	int (*udc_init)(struct udc_device *devinfo);
+	int (*udc_register_gadget)(struct udc_gadget *gadget);
+	int (*udc_start)(void);
+	int (*udc_stop)(void);
+
+	struct udc_endpoint *(*udc_endpoint_alloc)(unsigned type, unsigned maxpkt);
+	void (*udc_endpoint_free)(struct udc_endpoint *ept);
+	struct udc_request *(*udc_request_alloc)(void);
+	void (*udc_request_free)(struct udc_request *req);
+
+	int (*usb_read)(void *buf, unsigned len);
+	int (*usb_write)(void *buf, unsigned len);
+} usb_controller_interface_t;
+
+usb_controller_interface_t usb_if;
+
 #define MAX_USBFS_BULK_SIZE (32 * 1024)
 
 void boot_linux(void *bootimg, unsigned sz);
@@ -160,7 +182,7 @@
 }
 
 #ifdef USB30_SUPPORT
-static int usb_read(void *buf, unsigned len)
+static int usb30_usb_read(void *buf, unsigned len)
 {
 	int r;
 	struct udc_request req;
@@ -177,7 +199,7 @@
 	req.length   = len;
 	req.complete = req_complete;
 
-	r = udc_request_queue(out, &req);
+	r = usb30_udc_request_queue(out, &req);
 	if (r < 0)
 	{
 		dprintf(CRITICAL, "usb_read() queue failed. r = %d\n", r);
@@ -208,7 +230,7 @@
 	return -1;
 }
 
-static int usb_write(void *buf, unsigned len)
+static int usb30_usb_write(void *buf, unsigned len)
 {
 	int r;
 	struct udc_request req;
@@ -228,7 +250,7 @@
 	req.length   = len;
 	req.complete = req_complete;
 
-	r = udc_request_queue(in, &req);
+	r = usb30_udc_request_queue(in, &req);
 	if (r < 0) {
 		dprintf(CRITICAL, "usb_write() queue failed. r = %d\n", r);
 		goto oops;
@@ -251,9 +273,9 @@
 	dprintf(CRITICAL, "usb_write(): DONE: ERROR: len = %d\n", len);
 	return -1;
 }
+#endif
 
-#else
-static int usb_read(void *_buf, unsigned len)
+static int hsusb_usb_read(void *_buf, unsigned len)
 {
 	int r;
 	unsigned xfer;
@@ -299,7 +321,7 @@
 	return -1;
 }
 
-static int usb_write(void *buf, unsigned len)
+static int hsusb_usb_write(void *buf, unsigned len)
 {
 	int r;
 
@@ -325,7 +347,6 @@
 	fastboot_state = STATE_ERROR;
 	return -1;
 }
-#endif
 
 void fastboot_ack(const char *code, const char *reason)
 {
@@ -340,7 +361,7 @@
 	snprintf(response, MAX_RSP_SIZE, "%s%s", code, reason);
 	fastboot_state = STATE_COMPLETE;
 
-	usb_write(response, strlen(response));
+	usb_if.usb_write(response, strlen(response));
 
 }
 
@@ -356,7 +377,7 @@
 
 	snprintf(response, MAX_RSP_SIZE, "INFO%s", reason);
 
-	usb_write(response, strlen(response));
+	usb_if.usb_write(response, strlen(response));
 }
 
 void fastboot_fail(const char *reason)
@@ -395,10 +416,10 @@
 	}
 
 	snprintf(response, MAX_RSP_SIZE, "DATA%08x", len);
-	if (usb_write(response, strlen(response)) < 0)
+	if (usb_if.usb_write(response, strlen(response)) < 0)
 		return;
 
-	r = usb_read(download_base, len);
+	r = usb_if.usb_read(download_base, len);
 	if ((r < 0) || ((unsigned) r != len)) {
 		fastboot_state = STATE_ERROR;
 		return;
@@ -429,7 +450,7 @@
 		memset(buffer, 0, MAX_RSP_SIZE);
 		arch_clean_invalidate_cache_range((addr_t) buffer, MAX_RSP_SIZE);
 
-		r = usb_read(buffer, MAX_RSP_SIZE);
+		r = usb_if.usb_read(buffer, MAX_RSP_SIZE);
 		if (r < 0) break;
 		buffer[r] = 0;
 		dprintf(INFO,"fastboot: %s\n", buffer);
@@ -486,28 +507,64 @@
 	dprintf(SPEW,"serial number: %s\n",sn_buf);
 	surf_udc_device.serialno = sn_buf;
 
+	if(!strcmp(target_usb_controller(), "dwc"))
+	{
+#ifdef USB30_SUPPORT
+		/* initialize udc functions to use dwc controller */
+		usb_if.udc_init            = usb30_udc_init;
+		usb_if.udc_register_gadget = usb30_udc_register_gadget;
+		usb_if.udc_start           = usb30_udc_start;
+		usb_if.udc_stop            = usb30_udc_stop;
+
+		usb_if.udc_endpoint_alloc  = usb30_udc_endpoint_alloc;
+		usb_if.udc_request_alloc   = usb30_udc_request_alloc;
+		usb_if.udc_request_free    = usb30_udc_request_free;
+
+		usb_if.usb_read            = usb30_usb_read;
+		usb_if.usb_write           = usb30_usb_write;
+#else
+		dprintf(CRITICAL, "USB30 needs to be enabled for this target.\n");
+		ASSERT(0);
+#endif
+	}
+	else
+	{
+		/* initialize udc functions to use the default chipidea controller */
+		usb_if.udc_init            = udc_init;
+		usb_if.udc_register_gadget = udc_register_gadget;
+		usb_if.udc_start           = udc_start;
+		usb_if.udc_stop            = udc_stop;
+
+		usb_if.udc_endpoint_alloc  = udc_endpoint_alloc;
+		usb_if.udc_request_alloc   = udc_request_alloc;
+		usb_if.udc_request_free    = udc_request_free;
+
+		usb_if.usb_read            = hsusb_usb_read;
+		usb_if.usb_write           = hsusb_usb_write;
+	}
+
 	/* register udc device */
-	udc_init(&surf_udc_device);
+	usb_if.udc_init(&surf_udc_device);
 
 	event_init(&usb_online, 0, EVENT_FLAG_AUTOUNSIGNAL);
 	event_init(&txn_done, 0, EVENT_FLAG_AUTOUNSIGNAL);
 
-	in = udc_endpoint_alloc(UDC_TYPE_BULK_IN, 512);
+	in = usb_if.udc_endpoint_alloc(UDC_TYPE_BULK_IN, 512);
 	if (!in)
 		goto fail_alloc_in;
-	out = udc_endpoint_alloc(UDC_TYPE_BULK_OUT, 512);
+	out = usb_if.udc_endpoint_alloc(UDC_TYPE_BULK_OUT, 512);
 	if (!out)
 		goto fail_alloc_out;
 
 	fastboot_endpoints[0] = in;
 	fastboot_endpoints[1] = out;
 
-	req = udc_request_alloc();
+	req = usb_if.udc_request_alloc();
 	if (!req)
 		goto fail_alloc_req;
 
 	/* register gadget */
-	if (udc_register_gadget(&fastboot_gadget))
+	if (usb_if.udc_register_gadget(&fastboot_gadget))
 		goto fail_udc_register;
 
 	fastboot_register("getvar:", cmd_getvar);
@@ -521,16 +578,21 @@
 	}
 	thread_resume(thr);
 
-	udc_start();
+	usb_if.udc_start();
 
 	return 0;
 
 fail_udc_register:
-	udc_request_free(req);
+	usb_if.udc_request_free(req);
 fail_alloc_req:
-	udc_endpoint_free(out);
+	usb_if.udc_endpoint_free(out);
 fail_alloc_out:
-	udc_endpoint_free(in);
+	usb_if.udc_endpoint_free(in);
 fail_alloc_in:
 	return -1;
 }
+
+void fastboot_stop(void)
+{
+	usb_if.udc_stop();
+}
diff --git a/app/aboot/fastboot.h b/app/aboot/fastboot.h
index 0703402..11355da 100644
--- a/app/aboot/fastboot.h
+++ b/app/aboot/fastboot.h
@@ -11,7 +11,7 @@
  *    notice, this list of conditions and the following disclaimer.
  *  * Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the 
+ *    the documentation and/or other materials provided with the
  *    distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
@@ -21,7 +21,7 @@
  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
@@ -35,8 +35,9 @@
 #define MAX_GET_VAR_NAME_SIZE   256
 
 int fastboot_init(void *xfer_buffer, unsigned max);
+void fastboot_stop(void);
 
-/* register a command handler 
+/* register a command handler
  * - command handlers will be called if their prefix matches
  * - they are expected to call fastboot_okay() or fastboot_fail()
  *   to indicate success/failure before returning