📄 uboot-dfu.patch
字号:
++ if (part)+ strdesc = create_usbstring(part->name);+ else+ strdesc = create_usbstring("undefined partition");+ if (!strdesc)+ continue;+ slot = usb_strings+STR_COUNT+i+1;+ if (*slot)+ free(*slot);+ *slot = strdesc;+ }+}++#endif /* CONFIG_NAND_DYNPART */+++int dfu_init_instance(struct usb_device_instance *dev)+{+ int i;++ for (i = 0; i != DFU_NUM_ALTERNATES; i++) {+ struct usb_interface_descriptor *uif =+ dfu_cfg_descriptor.uif+i;++ uif->bLength = USB_DT_INTERFACE_SIZE;+ uif->bDescriptorType = USB_DT_INTERFACE;+ uif->bAlternateSetting = i;+ uif->bInterfaceClass = 0xfe;+ uif->bInterfaceSubClass = 1;+ uif->bInterfaceProtocol = 2;+ uif->iInterface = DFU_STR_ALT(i);+ }++ dev->dfu_dev_desc = &dfu_dev_descriptor;+ dev->dfu_cfg_desc = &dfu_cfg_descriptor;+ dev->dfu_state = DFU_STATE_appIDLE;+ dev->dfu_status = DFU_STATUS_OK;++ if (system_dfu_state)+ printf("SURPRISE: system_dfu_state is already set\n");+ system_dfu_state = &dev->dfu_state;++ dfu_init_strings(dev);++ return 0;+}++static int stdout_switched;++/* event handler for usb device state events */+void dfu_event(struct usb_device_instance *device,+ usb_device_event_t event, int data)+{+ char *out;++ switch (event) {+ case DEVICE_RESET:+ switch (device->dfu_state) {+ case DFU_STATE_appDETACH:+ device->dfu_state = DFU_STATE_dfuIDLE;+ out = getenv("stdout");+ if (out && !strcmp(out, "usbtty")) {+ setenv("stdout", "vga");+ setenv("stderr", "vga");+ stdout_switched = 1;+ }+ printf("DFU: Switching to DFU Mode\n");+ break;+ case DFU_STATE_dfuMANIFEST_WAIT_RST:+ device->dfu_state = DFU_STATE_appIDLE;+ printf("DFU: Switching back to Runtime mode\n");+ if (stdout_switched) {+ setenv("stdout", "usbtty");+ setenv("stderr", "usbtty");+ stdout_switched = 0;+ }+ break;+ default:+ break;+ }+ break;+ case DEVICE_CONFIGURED:+ case DEVICE_DE_CONFIGURED:+ debug("SET_CONFIGURATION(%u) ", device->configuration);+ /* fallthrough */+ case DEVICE_SET_INTERFACE:+ debug("SET_INTERFACE(%u,%u) old_state = %u ",+ device->interface, device->alternate,+ device->dfu_state);+ switch (device->dfu_state) {+ case DFU_STATE_appIDLE:+ case DFU_STATE_appDETACH:+ case DFU_STATE_dfuIDLE:+ case DFU_STATE_dfuMANIFEST_WAIT_RST:+ /* do nothing, we're fine */+ break;+ case DFU_STATE_dfuDNLOAD_SYNC:+ case DFU_STATE_dfuDNBUSY:+ case DFU_STATE_dfuDNLOAD_IDLE:+ case DFU_STATE_dfuMANIFEST:+ device->dfu_state = DFU_STATE_dfuERROR;+ device->dfu_status = DFU_STATUS_errNOTDONE;+ /* FIXME: free malloc()ed buffer! */+ break;+ case DFU_STATE_dfuMANIFEST_SYNC:+ case DFU_STATE_dfuUPLOAD_IDLE:+ case DFU_STATE_dfuERROR:+ device->dfu_state = DFU_STATE_dfuERROR;+ device->dfu_status = DFU_STATUS_errUNKNOWN;+ break;+ }+ debug("new_state = %u\n", device->dfu_state);+ break;+ default:+ break;+ }+}+#endif /* CONFIG_USBD_DFU */Index: u-boot/drivers/usb/Makefile===================================================================--- u-boot.orig/drivers/usb/Makefile+++ u-boot/drivers/usb/Makefile@@ -28,6 +28,7 @@ COBJS-y += isp116x-hcd.o COBJS-y += sl811_usb.o COBJS-y += usb_ohci.o+COBJS-y += usbdfu.o COBJS-y += usbdcore.o COBJS-y += usbdcore_ep0.o COBJS-y += usbdcore_mpc8xx.oIndex: u-boot/drivers/usb/usbdcore.c===================================================================--- u-boot.orig/drivers/usb/usbdcore.c+++ u-boot/drivers/usb/usbdcore.c@@ -31,6 +31,7 @@ #include <malloc.h> #include "usbdcore.h"+#include <usb_dfu.h> #define MAX_INTERFACES 2 @@ -212,6 +213,10 @@ */ struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *device, int port) {+#ifdef CONFIG_USBD_DFU+ if (device->dfu_state != DFU_STATE_appIDLE)+ return device->dfu_dev_desc;+#endif return (device->device_descriptor); } @@ -232,6 +237,10 @@ if (!(configuration_instance = usbd_device_configuration_instance (device, port, configuration))) { return NULL; }+#ifdef CONFIG_USBD_DFU+ if (device->dfu_state != DFU_STATE_appIDLE)+ return (&device->dfu_cfg_desc->ucfg);+#endif return (configuration_instance->configuration_descriptor); } @@ -253,6 +262,13 @@ if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) { return NULL; }+#ifdef CONFIG_USBD_DFU+ if (device->dfu_state != DFU_STATE_appIDLE) {+ if (alternate < 0 || alternate >= DFU_NUM_ALTERNATES)+ return NULL;+ return &device->dfu_cfg_desc->uif[alternate];+ }+#endif if ((alternate < 0) || (alternate >= interface_instance->alternates)) { return NULL; }@@ -681,4 +697,7 @@ /* usbdbg("calling device->event"); */ device->event(device, event, data); }+#ifdef CONFIG_USBD_DFU+ dfu_event(device, event, data);+#endif }Index: u-boot/drivers/serial/usbtty.c===================================================================--- u-boot.orig/drivers/serial/usbtty.c+++ u-boot/drivers/serial/usbtty.c@@ -31,6 +31,8 @@ #include "usbtty.h" #include "usb_cdc_acm.h" #include "usbdescriptors.h"+#include <usb_dfu_descriptors.h>+#include <usb_dfu.h> #include <config.h> /* If defined, override Linux identifiers with * vendor specific ones */ @@ -106,7 +108,7 @@ static unsigned short rx_endpoint = 0; static unsigned short tx_endpoint = 0; static unsigned short interface_count = 0;-static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];+static struct usb_string_descriptor *usbtty_string_table[NUM_STRINGS]; /* USB Descriptor Strings */ static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};@@ -157,6 +159,10 @@ struct usb_interface_descriptor data_class_interface; struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));+#ifdef CONFIG_USBD_DFU+ struct usb_interface_descriptor uif_dfu;+ struct usb_dfu_func_descriptor func_dfu;+#endif } __attribute__((packed)); static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {@@ -167,7 +173,11 @@ .bDescriptorType = USB_DT_CONFIG, .wTotalLength = cpu_to_le16(sizeof(struct acm_config_desc)),+#ifdef CONFIG_USBD_DFU+ .bNumInterfaces = NUM_ACM_INTERFACES +1,+#else .bNumInterfaces = NUM_ACM_INTERFACES,+#endif .bConfigurationValue = 1, .iConfiguration = STR_CONFIG, .bmAttributes =@@ -266,6 +276,11 @@ .bInterval = 0xFF, }, },+#ifdef CONFIG_USBD_DFU+ /* Interface 3 */+ .uif_dfu = DFU_RT_IF_DESC,+ .func_dfu = DFU_FUNC_DESC,+#endif }, }; @@ -378,7 +393,7 @@ void usbtty_poll (void); /* utility function for converting char* to wide string used by USB */-static void str2wide (char *str, u16 * wide)+void str2wide (char *str, u16 * wide) { int i; for (i = 0; i < strlen (str) && str[i]; i++){@@ -654,6 +669,9 @@ device_instance->bus = bus_instance; device_instance->configurations = NUM_CONFIGS; device_instance->configuration_instance_array = config_instance;+#ifdef CONFIG_USBD_DFU+ dfu_init_instance(device_instance);+#endif /* initialize bus instance */ memset (bus_instance, 0, sizeof (struct usb_bus_instance));Index: u-boot/include/configs/neo1973_gta01.h===================================================================--- u-boot.orig/include/configs/neo1973_gta01.h+++ u-boot/include/configs/neo1973_gta01.h@@ -159,7 +159,7 @@ */ #define CONFIG_STACKSIZE (128*1024) /* regular stack */ #ifdef CONFIG_USE_IRQ-#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */+#define CONFIG_STACKSIZE_IRQ (8*1024) /* IRQ stack */ #define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ #endif @@ -176,6 +176,10 @@ #define CONFIG_USBD_MANUFACTURER "OpenMoko, Inc" #define CONFIG_USBD_PRODUCT_NAME "Neo1973 Bootloader " U_BOOT_VERSION #define CONFIG_EXTRA_ENV_SETTINGS "usbtty=cdc_acm\0"+#define CONFIG_USBD_DFU 1+#define CONFIG_USBD_DFU_XFER_SIZE 4096 /* 0x4000 */+#define CONFIG_USBD_DFU_INTERFACE 2+ /*----------------------------------------------------------------------- * Physical Memory MapIndex: u-boot/include/usb_dfu.h===================================================================--- /dev/null+++ u-boot/include/usb_dfu.h@@ -0,0 +1,94 @@+#ifndef _DFU_H+#define _DFU_H++/* USB Device Firmware Update Implementation for u-boot+ * (C) 2007 by OpenMoko, Inc.+ * Author: Harald Welte <laforge@openmoko.org>+ *+ * based on: USB Device Firmware Update Implementation for OpenPCD+ * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>+ *+ * This ought to be compliant to the USB DFU Spec 1.0 as available from+ * http://www.usb.org/developers/devclass_docs/usbdfu10.pdf+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+ */++#include <asm/types.h>+#include <usbdescriptors.h>+#include <usb_dfu_descriptors.h>+#include <config.h>++/* USB DFU functional descriptor */+#define DFU_FUNC_DESC { \+ .bLength = USB_DT_DFU_SIZE, \+ .bDescriptorType = USB_DT_DFU, \+ .bmAttributes = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD | USB_DFU_MANIFEST_TOL, \+ .wDetachTimeOut = 0xff00, \+ .wTransferSize = CONFIG_USBD_DFU_XFER_SIZE, \+ .bcdDFUVersion = 0x0100, \+}++/* USB Interface descriptor in Runtime mode */+#define DFU_RT_IF_DESC { \+ .bLength = USB_DT_INTERFACE_SIZE, \+ .bDescriptorType = USB_DT_INTERFACE, \+ .bInterfaceNumber = CONFIG_USBD_DFU_INTERFACE, \+ .bAlternateSetting = 0x00, \+ .bNumEndpoints = 0x00, \+ .bInterfaceClass = 0xfe, \+ .bInterfaceSubClass = 0x01, \+ .bInterfaceProtocol = 0x01, \+ .iInterface = DFU_STR_CONFIG, \+}++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))++#ifndef DFU_NUM_ALTERNATES+#define DFU_NUM_ALTERNATES 6+#endif++#define DFU_STR_MANUFACTURER STR_MANUFACTURER+#define DFU_STR_PRODUCT STR_PRODUCT+#define DFU_STR_SERIAL STR_SERIAL+#define DFU_STR_CONFIG (STR_COUNT)+#define DFU_STR_ALT(n) (STR_COUNT+(n)+1)+#define DFU_STR_COUNT DFU_STR_ALT(DFU_NUM_ALTERNATES)++#define CONFIG_DFU_CFG_STR "USB Device Firmware Upgrade"+#define CONFIG_DFU_ALT0_STR "RAM 0x32000000"++struct _dfu_desc {+ struct usb_configuration_descriptor ucfg;+ struct usb_interface_descriptor uif[DFU_NUM_ALTERNATES];+ struct usb_dfu_func_descriptor func_dfu;+};++int dfu_init_instance(struct usb_device_instance *dev);++#define DFU_EP0_NONE 0+#define DFU_EP0_UNHANDLED 1+#define DFU_EP0_STALL 2+#define DFU_EP0_ZLP 3+#define DFU_EP0_DATA 4++extern volatile enum dfu_state *system_dfu_state; /* for 3rd parties */++int dfu_ep0_handler(struct urb *urb);++void dfu_event(struct usb_device_instance *device,+ usb_device_event_t event, int data);++#endif /* _DFU_H */Index: u-boot/include/usb_dfu_descriptors.h===================================================================--- /dev/null+++ u-boot/include/usb_dfu_descriptors.h@@ -0,0 +1,94 @@+#ifndef _USB_DFU_H+#define _USB_DFU_H+/* USB Device Firmware Update Implementation for OpenPCD+ * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>+ *+ * Protocol definitions for USB DFU+ *+ * This ought to be compliant to the USB DFU Spec 1.0 as available from+ * http://www.usb.org/developers/devclass_docs/usbdfu10.pdf+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+ */++#include <linux/types.h>++#define USB_DT_DFU 0x21++struct usb_dfu_func_descriptor {+ u_int8_t bLength;+ u_int8_t bDescriptorType;+ u_int8_t bmAttributes;+#define USB_DFU_CAN_DOWNLOAD (1 << 0)+#define USB_DFU_CAN_UPLOAD (1 << 1)+#define USB_DFU_MANIFEST_TOL (1 << 2)+#define USB_DFU_WILL_DETACH (1 << 3)+ u_int16_t wDetachTimeOut;+ u_int16_t wTransferSize;+ u_int16_t bcdDFUVersion;+} __attribute__ ((packed));++#define USB_DT_DFU_SIZE 9++#define USB_TYPE_DFU (USB_TYPE_CLASS|USB_RECIP_INTERFACE)++/* DFU class-specific requests (Section 3, DFU Rev 1.1) */+#define USB_REQ_DFU_DETACH 0x00+#define USB_REQ_DFU_DNLOAD 0x01+#define USB_REQ_DFU_UPLOAD 0x02+#define USB_REQ_DFU_GETSTATUS 0x03+#define USB_REQ_DFU_CLRSTATUS 0x04+#define USB_REQ_DFU_GETSTATE 0x05+#define USB_REQ_DFU_ABORT 0x06++struct dfu_status {+ u_int8_t bStatus;+ u_int8_t bwPollTimeout[3];+ u_int8_t bState;+ u_int8_t iString;+} __attribute__((packed));++#define DFU_STATUS_OK 0x00+#define DFU_STATUS_errTARGET 0x01+#define DFU_STATUS_errFILE 0x02+#define DFU_STATUS_errWRITE 0x03+#define DFU_STATUS_errERASE 0x04+#define DFU_STATUS_errCHECK_ERASED 0x05+#define DFU_STATUS_errPROG 0x06+#define DFU_STATUS_errVERIFY 0x07+#define DFU_STATUS_errADDRESS 0x08+#define DFU_STATUS_errNOTDONE 0x09+#define DFU_STATUS_errFIRMWARE 0x0a+#define DFU_STATUS_errVENDOR 0x0b+#define DFU_STATUS_errUSBR 0x0c+#define DFU_STATUS_errPOR 0x0d+#define DFU_STATUS_errUNKNOWN 0x0e+#define DFU_STATUS_errSTALLEDPKT 0x0f++enum dfu_state {+ DFU_STATE_appIDLE = 0,+ DFU_STATE_appDETACH = 1,+ DFU_STATE_dfuIDLE = 2,+ DFU_STATE_dfuDNLOAD_SYNC = 3,+ DFU_STATE_dfuDNBUSY = 4,+ DFU_STATE_dfuDNLOAD_IDLE = 5,+ DFU_STATE_dfuMANIFEST_SYNC = 6,+ DFU_STATE_dfuMANIFEST = 7,+ DFU_STATE_dfuMANIFEST_WAIT_RST = 8,+ DFU_STATE_dfuUPLOAD_IDLE = 9,+ DFU_STATE_dfuERROR = 10,+};++#endif /* _USB_DFU_H */Index: u-boot/include/usbdcore.h===================================================================--- u-boot.orig/include/usbdcore.h+++ u-boot/include/usbdcore.h@@ -33,6 +33,7 @@ #include <common.h> #include "usbdescriptors.h"+#include <usb_dfu_descriptors.h> #define MAX_URBS_QUEUED 5@@ -475,7 +476,11 @@ * function driver to inform it that data has arrived. */ +#ifdef CONFIG_USBD_DFU+#define URB_BUF_SIZE (128+CONFIG_USBD_DFU_XFER_SIZE)+#else #define URB_BUF_SIZE 128 /* in linux we'd malloc this, but in u-boot we prefer static data */+#endif struct urb { struct usb_endpoint_instance *endpoint;@@ -603,6 +608,12 @@ unsigned long usbd_rxtx_timestamp; unsigned long usbd_last_rxtx_timestamp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -