[U-Boot] [PATCH 4/4] usb: fastboot: implement fastboot
Steve Rae
srae at broadcom.com
Tue Jan 20 23:42:10 CET 2015
- add "bcm_usb_gadget.c"
- implement fastboot on 'bcm28155_ap' boards
Signed-off-by: Steve Rae <srae at broadcom.com>
---
drivers/usb/gadget/Makefile | 2 +
drivers/usb/gadget/bcm_usb_gadget.c | 240 ++++++++++++++++++++++++++++++++++++
include/configs/bcm28155_ap.h | 20 ++-
3 files changed, 261 insertions(+), 1 deletion(-)
create mode 100644 drivers/usb/gadget/bcm_usb_gadget.c
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 70bb550..8b55c1f 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -20,6 +20,8 @@ obj-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
obj-$(CONFIG_DFU_FUNCTION) += f_dfu.o
obj-$(CONFIG_USB_GADGET_MASS_STORAGE) += f_mass_storage.o
obj-$(CONFIG_CMD_FASTBOOT) += f_fastboot.o
+obj-$(CONFIG_BCM_UDC_OTG) += bcm_usb_gadget.o
+obj-$(CONFIG_BCM_UDC_OTG) += bcm_udc_otg.o
endif
ifdef CONFIG_USB_ETHER
obj-y += ether.o
diff --git a/drivers/usb/gadget/bcm_usb_gadget.c b/drivers/usb/gadget/bcm_usb_gadget.c
new file mode 100644
index 0000000..cc7e182
--- /dev/null
+++ b/drivers/usb/gadget/bcm_usb_gadget.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2015 Broadcom Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#include "bcm_udc_otg.h"
+
+/* fwd declarations */
+static struct usb_request *in_req;
+static struct usb_request *out_req;
+
+#define RESPONSE_LEN (64 + 1)
+
+/*
+ * usb_ep_ops: stub callback functions
+ */
+
+static int stub_enable(struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ printf("called: %s\n", __func__);
+ return 0;
+}
+
+static int stub_disable(struct usb_ep *ep)
+{
+ printf("called: %s\n", __func__);
+ return 0;
+}
+
+static struct usb_request *stub_alloc_request(struct usb_ep *ep,
+ gfp_t gfp_flags)
+{
+ printf("called: %s\n", __func__);
+ return NULL;
+}
+
+static void stub_free_request(struct usb_ep *ep, struct usb_request *req)
+{
+ printf("called: %s\n", __func__);
+}
+
+/*
+ * static int stub_queue(struct usb_ep *ep, struct usb_request *request,
+ * gfp_t gfp_flags)
+ */
+
+static int stub_dequeue(struct usb_ep *ep, struct usb_request *request)
+{
+ printf("called: %s\n", __func__);
+ return 0;
+}
+
+static int stub_set_halt(struct usb_ep *ep, int value)
+{
+ printf("called: %s\n", __func__);
+ return 0;
+}
+
+static int stub_fifo_status(struct usb_ep *ep)
+{
+ printf("called: %s\n", __func__);
+ return 0;
+}
+
+static void stub_fifo_flush(struct usb_ep *ep)
+{
+ printf("called: %s\n", __func__);
+}
+
+/*
+ * usb_ep_ops: implement callback functions
+ */
+
+static int queue_bulk_in_ep(struct usb_ep *ep, struct usb_request *req,
+ gfp_t gfp_flags)
+{
+ int ret;
+ /* verify: only "send" requests (in_req) on this bulk endpoint */
+ if (req != in_req) {
+ error("fatal %p %p", req, in_req);
+ return -1;
+ }
+
+ /* send a packet via the bulk endpoint */
+ ret = usb_send_bulk_otg(req->buf, strlen(req->buf));
+ if (ret)
+ printf("%s: usb_send_bulk_otg() returned: %d\n", __func__, ret);
+
+ if (req->complete)
+ req->complete(ep, req);
+ else
+ printf("%s: skipping complete()\n", __func__);
+
+ return ret;
+}
+
+static int queue_bulk_out_ep(struct usb_ep *ep, struct usb_request *req,
+ gfp_t gfp_flags)
+{
+ /* verify: only "receive" requests (out_req) on this bulk endpoint */
+ if (req != out_req) {
+ error("fatal %p %p", req, out_req);
+ return -1;
+ }
+
+ /* calling req->complete causes infinite loop, therefore, do nothing */
+
+ return 0;
+}
+
+/* initial values for USB Endpoint Operations */
+static const struct usb_ep_ops out_ep_ops = {
+ .enable = stub_enable,
+ .disable = stub_disable,
+ .alloc_request = stub_alloc_request,
+ .free_request = stub_free_request,
+ .queue = queue_bulk_out_ep,
+ .dequeue = stub_dequeue,
+ .set_halt = stub_set_halt,
+ .fifo_status = stub_fifo_status,
+ .fifo_flush = stub_fifo_flush
+};
+
+static const struct usb_ep_ops in_ep_ops = {
+ .enable = stub_enable,
+ .disable = stub_disable,
+ .alloc_request = stub_alloc_request,
+ .free_request = stub_free_request,
+ .queue = queue_bulk_in_ep,
+ .dequeue = stub_dequeue,
+ .set_halt = stub_set_halt,
+ .fifo_status = stub_fifo_status,
+ .fifo_flush = stub_fifo_flush
+};
+
+/* initial values for USB Endpoints */
+static struct usb_ep in_ep_init = {
+ .name = "in_ep",
+ .ops = &in_ep_ops,
+ .maxpacket = 512,
+};
+static struct usb_ep *in_ep = &in_ep_init; /* bulk ep, to host */
+
+static struct usb_ep out_ep_init = {
+ .name = "out_ep",
+ .ops = &out_ep_ops,
+ .maxpacket = 512,
+};
+static struct usb_ep *out_ep = &out_ep_init; /* bulk ep, from host */
+
+/* initial values for USB Requests */
+static struct usb_request in_req_init;
+static struct usb_request *in_req = &in_req_init;
+
+static struct usb_request out_req_init;
+static struct usb_request *out_req = &out_req_init;
+
+/*
+ * local functions
+ */
+
+static int rx_handler(const unsigned char *buffer, unsigned int buffer_size)
+{
+ /* zero the Response Buffer */
+ memset(in_req->buf, 0, RESPONSE_LEN);
+
+ /* seed the Out Request values */
+ out_req->buf = (char *)buffer;
+ out_req->actual = buffer_size;
+
+ /* perform the callback */
+ if (out_req->complete)
+ out_req->complete(out_ep, out_req);
+ else
+ error("FATAL: no handler defined!");
+
+ return out_req->status;
+}
+
+static int fastboot_init(void)
+{
+ int ret;
+
+ usb_shutdown_otg();
+
+ ret = usb_init_otg(rx_handler);
+
+ return ret;
+}
+
+extern void fastboot_func_init(struct usb_ep *in_ep, struct usb_ep *out_ep,
+ struct usb_request *in_req, struct usb_request *out_req);
+
+/*
+ * USB Gadget implementation
+ */
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+ int ret;
+ ret = fastboot_init();
+ debug("%s: ret=%d\n", __func__, ret);
+ if (ret) {
+ error("fastboot_init() failed!");
+ return -1;
+ }
+
+ in_req->length = RESPONSE_LEN;
+ in_req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, RESPONSE_LEN);
+ if (!in_req->buf) {
+ error("fatal: alloc failed");
+ return -1;
+ }
+
+ fastboot_func_init(in_ep, NULL, in_req, out_req);
+ return 0;
+}
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+ if (in_req->buf)
+ free(in_req->buf);
+ debug("%s\n", __func__);
+ return 0;
+}
+
+int usb_gadget_handle_interrupts(void)
+{
+ usb_handle_ints_otg();
+ return 0;
+}
diff --git a/include/configs/bcm28155_ap.h b/include/configs/bcm28155_ap.h
index 1045779..e5103d4 100644
--- a/include/configs/bcm28155_ap.h
+++ b/include/configs/bcm28155_ap.h
@@ -1,7 +1,7 @@
/*
* Copyright 2013 Broadcom Corporation.
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __BCM28155_AP_H
@@ -109,6 +109,7 @@
* for example.
*/
#define CONFIG_DOS_PARTITION
+#define CONFIG_EFI_PARTITION
/* version string, parser, etc */
#define CONFIG_VERSION_VARIABLE
@@ -137,4 +138,21 @@
#undef CONFIG_CMD_NET
#undef CONFIG_CMD_NFS
+/* Fastboot and USB OTG */
+#define CONFIG_USB_GADGET
+#define CONFIG_CMD_FASTBOOT
+#define CONFIG_FASTBOOT_NO_GADGET
+#define CONFIG_FASTBOOT_FLASH
+#define CONFIG_FASTBOOT_FLASH_MMC_DEV 0
+#define CONFIG_SYS_CACHELINE_SIZE 64
+#define CONFIG_USB_FASTBOOT_BUF_SIZE (CONFIG_SYS_SDRAM_SIZE - (1024 * 1024))
+#define CONFIG_USB_FASTBOOT_BUF_ADDR CONFIG_SYS_SDRAM_BASE
+#define CONFIG_USB_GADGET_VBUS_DRAW 0
+#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USBID_ADDR 0x34052c46
+#define CONFIG_G_DNL_VENDOR_NUM 0x18d1 /* google */
+#define CONFIG_G_DNL_PRODUCT_NUM 0x0d02 /* nexus one */
+#define CONFIG_G_DNL_MANUFACTURER "Broadcom Corporation"
+#define CONFIG_BCM_UDC_OTG
+
#endif /* __BCM28155_AP_H */
--
1.8.5
More information about the U-Boot
mailing list