r1106 - trunk/src/target/u-boot/patches

laforge at sita.openmoko.org laforge at sita.openmoko.org
Sat Feb 24 20:37:46 CET 2007


Author: laforge
Date: 2007-02-24 20:37:46 +0100 (Sat, 24 Feb 2007)
New Revision: 1106

Modified:
   trunk/src/target/u-boot/patches/series
   trunk/src/target/u-boot/patches/uboot-dfu.patch
Log:
* DFU now actually can do flash updates, within limited conditions
** no transfer size % 8 allowed
** only one upload, then USB is dead
* update series file to move u-boot to the end

test this with something like 'dfu-util -a 4 -t 4093 -D /etc/passwd' which will put your /etc/passwd from the hsot into the splash partition ;)


Modified: trunk/src/target/u-boot/patches/series
===================================================================
--- trunk/src/target/u-boot/patches/series	2007-02-24 16:00:11 UTC (rev 1105)
+++ trunk/src/target/u-boot/patches/series	2007-02-24 19:37:46 UTC (rev 1106)
@@ -55,10 +55,10 @@
 preboot-override.patch
 lowlevel_foo.patch
 
-# those have to be implemented fully
-uboot-dfu.patch
-
 # move these later, once the dust has settled
 default-env.patch
 console-ansi.patch
 boot-menu.patch
+
+# those have to be implemented fully
+uboot-dfu.patch

Modified: trunk/src/target/u-boot/patches/uboot-dfu.patch
===================================================================
--- trunk/src/target/u-boot/patches/uboot-dfu.patch	2007-02-24 16:00:11 UTC (rev 1105)
+++ trunk/src/target/u-boot/patches/uboot-dfu.patch	2007-02-24 19:37:46 UTC (rev 1106)
@@ -1,8 +1,8 @@
 Index: u-boot/drivers/usbdcore_ep0.c
 ===================================================================
---- u-boot.orig/drivers/usbdcore_ep0.c	2007-02-24 03:59:30.000000000 +0100
-+++ u-boot/drivers/usbdcore_ep0.c	2007-02-24 04:03:05.000000000 +0100
-@@ -42,11 +42,16 @@
+--- u-boot.orig/drivers/usbdcore_ep0.c	2007-02-24 17:12:47.000000000 +0100
++++ u-boot/drivers/usbdcore_ep0.c	2007-02-24 17:12:49.000000000 +0100
+@@ -42,10 +42,15 @@
   */
  
  #include <common.h>
@@ -11,15 +11,13 @@
  #if defined(CONFIG_USB_DEVICE)
  #include "usbdcore.h"
  
--#if 0
 +#ifdef CONFIG_USBD_DFU
 +#include <usb_dfu.h>
 +#endif
 +
-+#if 1
+ #if 0
  #define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
  #else
- #define dbg_ep0(lvl,fmt,args...)
 @@ -213,7 +218,7 @@
  			urb->buffer = device_descriptor;
  			urb->actual_length = MIN(sizeof(*device_descriptor), max);
@@ -90,8 +88,8 @@
 Index: u-boot/drivers/usbdfu.c
 ===================================================================
 --- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ u-boot/drivers/usbdfu.c	2007-02-24 04:03:05.000000000 +0100
-@@ -0,0 +1,553 @@
++++ u-boot/drivers/usbdfu.c	2007-02-24 20:28:50.000000000 +0100
+@@ -0,0 +1,694 @@
 +/*
 + * (C) 2007 by OpenMoko, Inc.
 + * Author: Harald Welte <laforge at openmoko.org>
@@ -121,34 +119,112 @@
 +#include <config.h>
 +#if defined(CONFIG_USBD_DFU)
 +
-+//#define DEBUG
++#define DEBUG
 +
 +#include <common.h>
 +DECLARE_GLOBAL_DATA_PTR;
 +
++#include <malloc.h>
 +#include <linux/types.h>
++#include <linux/list.h>
 +#include <asm/errno.h>
 +#include <usbdcore.h>
 +#include <usb_dfu.h>
 +#include <usb_dfu_descriptors.h>
 +
++#include <nand.h>
++#include <jffs2/load_kernel.h>
++int mtdparts_init(void);
++extern struct list_head devices;
++
 +#include "usbdcore_s3c2410.h"
 +
 +#define RET_NOTHING	0
 +#define RET_ZLP		1
 +#define RET_STALL	2
 +
-+#define LOAD_ADDR 0x32000000
++struct dnload_state {
++	unsigned char *buf;	/* pointer to allocated erase page buffer */
++	unsigned char *ptr;	/* pointer to next empty byte in buffer */
++	struct part_info  *part;	/* partition */
++	unsigned int off;	/* offset of current erase page in flash chip */
++	nand_info_t *nand;
++	nand_erase_options_t erase_opts;
++};
 +
-+static char *ptr;
++static struct dnload_state _dnstate;
 +
++static struct part_info *get_partition(int idx)
++{
++	struct mtd_device *dev;
++	struct part_info *part;
++	struct list_head *pentry;
++	int i;
++
++	if (mtdparts_init() < 0)
++		return NULL;
++
++	dev = list_entry(devices.next, struct mtd_device, link);
++	i = 0;
++	list_for_each(pentry, &dev->parts) {
++		if (i == idx)  {
++			part = list_entry(pentry, struct part_info, link);
++			return part;
++		}
++		i++;
++	}
++
++	return NULL;
++}
++
++#define LOAD_ADDR ((unsigned char *)0x32000000)
++
++static int erase_flash_verify(struct urb *urb, struct dnload_state *ds)
++{
++	struct usb_device_instance *dev = urb->device;
++	unsigned long size = ds->nand->erasesize;
++	int rc;
++
++	/* we have finished one eraseblock, flash it */
++	memset(&ds->erase_opts, 0, sizeof(ds->erase_opts));
++	ds->erase_opts.offset = ds->off;
++	ds->erase_opts.length = size;
++	//ds->erase_opts.jffs2
++	//ds->erase_opts.quiet
++	debug("Erasing 0x%x bytes @ offset 0x%x\n",
++		ds->erase_opts.length, ds->erase_opts.offset);
++	rc = nand_erase_opts(ds->nand, &ds->erase_opts);
++	if (rc) {
++		debug("Error erasing\n");
++	    	dev->dfu_state = DFU_STATE_dfuERROR;
++		dev->dfu_status = DFU_STATUS_errERASE;
++		return RET_STALL;
++	}
++	debug("Writing 0x%x bytes @ offset 0x%x\n", size, ds->off);
++	rc = nand_write(ds->nand, ds->off, &size, ds->buf);
++	if (rc) {
++		debug("Error writing\n");
++  		dev->dfu_state = DFU_STATE_dfuERROR;
++		dev->dfu_status = DFU_STATUS_errWRITE;
++		return RET_STALL;
++	}
++	ds->off += ds->nand->erasesize;
++	ds->ptr = ds->buf;
++
++	/* FIXME: verify! */
++	return RET_NOTHING;
++}
++
 +static int handle_dnload(struct urb *urb, u_int16_t val, u_int16_t len, int first)
 +{
 +	struct usb_device_instance *dev = urb->device;
++	struct dnload_state *ds = &_dnstate;
++	int actual_len = len;
++	unsigned long size;
++	int rc;
++
 +	debug("download ");
 +
-+	int i;
-+
 +	if (len > CONFIG_USBD_DFU_XFER_SIZE) {
 +		/* Too big. Not that we'd really care, but it's a
 +		 * DFU protocol violation */
@@ -170,31 +246,93 @@
 +		debug("zero-size write -> MANIFEST_SYNC ");
 +		//flash_page(p);
 +		dev->dfu_state = DFU_STATE_dfuMANIFEST_SYNC;
++		dev->dfu_status = DFU_STATUS_errADDRESS;
++
++		/* cleanup */
++		switch (dev->alternate) {
++		case 0:
++			break;
++		default:
++			if (ds->ptr > ds->buf)
++				rc = erase_flash_verify(urb, ds);
++			free(ds->buf);
++			ds->nand = NULL;
++			break;
++		}
++		ds->buf = ds->ptr = NULL;
++
 +		return RET_ZLP;
 +	}
-+	if (ptr + len > LOAD_ADDR + 0x200000) {
-+		debug("end of write exceeds flash end ");
-+		dev->dfu_state = DFU_STATE_dfuERROR;
-+		dev->dfu_status = DFU_STATUS_errADDRESS;
-+		return RET_STALL;
-+	}
 +
++
 +	if (urb->actual_length != len) {
-+		debug("urb->actual_length(%u) != len(%u) ?!?\n",
++		debug("urb->actual_length(%u) != len(%u) ?!? ",
 +			urb->actual_length, len);
++	    	dev->dfu_state = DFU_STATE_dfuERROR;
++		dev->dfu_status = DFU_STATUS_errADDRESS;
 +		return RET_STALL;
 +	}
 +
++	if (first) {
++		/* initialize pointer to memory buffer */
++		switch (dev->alternate) {
++		case 0:
++			ds->buf = ds->ptr = LOAD_ADDR;
++			break;
++		default:
++			ds->part = get_partition(dev->alternate - 1);
++			if (!ds->part) {
++				printf("DFU: unable to find partition %u\b");
++	    			dev->dfu_state = DFU_STATE_dfuERROR;
++				dev->dfu_status = DFU_STATUS_errADDRESS;
++				return RET_STALL;
++			}
++			ds->nand = &nand_info[ds->part->dev->id->num];
++			ds->ptr = ds->buf = malloc(ds->nand->erasesize);
++			ds->off = ds->part->offset;
++			if (!ds->buf) {
++				printf("DFU: can't allocate %u bytes\n", ds->nand->erasesize);
++	    			dev->dfu_state = DFU_STATE_dfuERROR;
++				dev->dfu_status = DFU_STATUS_errADDRESS;
++				return RET_STALL;
++			}
++			printf("Starting DFU DOWNLOAD to partition '%s'\n",
++				ds->part->name);
++			break;
++		}
++	}
++
 +	/* actually write the data somewhere */
 +	switch (dev->alternate) {
 +	case 0:
-+		if (first)
-+			ptr = LOAD_ADDR;
-+		memcpy(ptr, urb->buffer, len);
-+		ptr += len;
++		memcpy(ds->ptr, urb->buffer, len);
++		ds->ptr += len;
 +		break;
 +	default:
-+		debug("[yet] unsupported altsetting %u\n", dev->alternate);
++		size = ds->nand->erasesize;
++		if (ds->buf + size - ds->ptr < len)
++			actual_len = len;
++
++		memcpy(ds->ptr, urb->buffer, actual_len);
++		ds->ptr += actual_len;
++
++		/* check partition end */
++		if (ds->off + (ds->ptr - ds->buf) > ds->part->offset + ds->part->size) {
++			debug("end of write exceeds flash end ");
++			dev->dfu_state = DFU_STATE_dfuERROR;
++			dev->dfu_status = DFU_STATUS_errADDRESS;
++			return RET_STALL;
++		}
++
++		if (ds->ptr >= ds->buf + size) {
++			rc = erase_flash_verify(urb, ds);
++			if (rc)
++				return rc;
++			/* copy remainder of data into buffer */
++			memcpy(ds->ptr, urb->buffer + actual_len,
++			       len - actual_len);
++			ds->ptr += (len - actual_len);
++		}
 +		break;
 +	}
 +
@@ -204,6 +342,7 @@
 +static int handle_upload(struct urb *urb, u_int16_t val, u_int16_t len, int first)
 +{
 +	struct usb_device_instance *dev = urb->device;
++	struct dnload_state *ds = &_dnstate;
 +	debug("upload(val=0x%02x, len=%u, first=%u) ", val, len, first);
 +
 +	if (len > CONFIG_USBD_DFU_XFER_SIZE) {
@@ -211,12 +350,12 @@
 +		dev->dfu_state = DFU_STATE_dfuERROR;
 +		dev->dfu_status = DFU_STATUS_errADDRESS;
 +		//udc_ep0_send_stall();
-+		debug("Error: Transfer size > CONFIG_USBD_DFU_XFER_SIZE\n");
++		debug("Error: Transfer size > CONFIG_USBD_DFU_XFER_SIZE ");
 +		return -EINVAL;
 +	}
 +
 +	if (first) {
-+		ptr = LOAD_ADDR;
++		ds->ptr = LOAD_ADDR;
 +		/* the first of many upload requests  */
 +		switch (dev->alternate) {
 +		case 0:
@@ -241,12 +380,12 @@
 +	}
 +
 +
-+	if (ptr + len > LOAD_ADDR + 0x200000)
-+		len = (char *)(LOAD_ADDR + 0x200000) - ptr;
++	if (ds->ptr + len > LOAD_ADDR + 0x200000)
++		len = (LOAD_ADDR + 0x200000) - ds->ptr;
 +
-+	urb->buffer = ptr;
++	urb->buffer = ds->ptr;
 +	urb->actual_length = len;
-+	ptr+= len;
++	ds->ptr+= len;
 +
 +	printf("returning len=%u\n", len);
 +	return len;
@@ -255,10 +394,10 @@
 +static void handle_getstatus(struct urb *urb, int max)
 +{
 +	struct usb_device_instance *dev = urb->device;
-+	struct dfu_status *dstat = urb->buffer;
++	struct dfu_status *dstat = (struct dfu_status *) urb->buffer;
 +	u_int32_t fsr = 0;//AT91F_MC_EFC_GetStatus(AT91C_BASE_MC);
 +
-+	debug("getstatus(fsr=0x%08x) ", fsr);
++	debug("getstatus ");
 +
 +	if (!urb->buffer || urb->buffer_length < sizeof(*dstat)) {
 +		debug("invalid urb! ");
@@ -596,7 +735,7 @@
 +			handle_getstatus(urb, len);
 +			break;
 +		case USB_REQ_DFU_GETSTATE:
-+			handle_getstate(dev, len);
++			handle_getstate(urb, len);
 +			break;
 +		case USB_REQ_DFU_CLRSTATUS:
 +			dev->dfu_state = DFU_STATE_dfuIDLE;
@@ -647,8 +786,8 @@
 +#endif /* CONFIG_USBD_DFU */
 Index: u-boot/drivers/Makefile
 ===================================================================
---- u-boot.orig/drivers/Makefile	2007-02-24 03:59:30.000000000 +0100
-+++ u-boot/drivers/Makefile	2007-02-24 04:03:05.000000000 +0100
+--- u-boot.orig/drivers/Makefile	2007-02-24 17:12:47.000000000 +0100
++++ u-boot/drivers/Makefile	2007-02-24 17:12:49.000000000 +0100
 @@ -46,7 +46,7 @@
  	  sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
  	  status_led.o sym53c8xx.o ahci.o \
@@ -660,8 +799,8 @@
  	  pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o	\
 Index: u-boot/drivers/usbdcore.c
 ===================================================================
---- u-boot.orig/drivers/usbdcore.c	2007-02-24 03:58:21.000000000 +0100
-+++ u-boot/drivers/usbdcore.c	2007-02-24 04:03:05.000000000 +0100
+--- u-boot.orig/drivers/usbdcore.c	2007-02-24 17:12:47.000000000 +0100
++++ u-boot/drivers/usbdcore.c	2007-02-24 17:12:49.000000000 +0100
 @@ -31,6 +31,7 @@
  
  #include <malloc.h>
@@ -721,8 +860,8 @@
  	case DEVICE_ADDRESS_ASSIGNED:
 Index: u-boot/drivers/usbtty.c
 ===================================================================
---- u-boot.orig/drivers/usbtty.c	2007-02-24 03:59:29.000000000 +0100
-+++ u-boot/drivers/usbtty.c	2007-02-24 04:03:05.000000000 +0100
+--- u-boot.orig/drivers/usbtty.c	2007-02-24 17:12:47.000000000 +0100
++++ u-boot/drivers/usbtty.c	2007-02-24 17:12:49.000000000 +0100
 @@ -31,6 +31,8 @@
  #include "usbtty.h"
  #include "usb_cdc_acm.h"
@@ -779,8 +918,8 @@
  	memset (bus_instance, 0, sizeof (struct usb_bus_instance));
 Index: u-boot/include/configs/neo1973.h
 ===================================================================
---- u-boot.orig/include/configs/neo1973.h	2007-02-24 04:03:04.000000000 +0100
-+++ u-boot/include/configs/neo1973.h	2007-02-24 04:03:05.000000000 +0100
+--- u-boot.orig/include/configs/neo1973.h	2007-02-24 17:12:47.000000000 +0100
++++ u-boot/include/configs/neo1973.h	2007-02-24 17:12:49.000000000 +0100
 @@ -182,6 +182,10 @@
  #define CONFIG_USBD_MANUFACTURER	"OpenMoko, Inc"
  #define CONFIG_USBD_PRODUCT_NAME	"Neo1973 Bootloader " U_BOOT_VERSION
@@ -795,7 +934,7 @@
 Index: u-boot/include/usb_dfu.h
 ===================================================================
 --- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ u-boot/include/usb_dfu.h	2007-02-24 04:03:05.000000000 +0100
++++ u-boot/include/usb_dfu.h	2007-02-24 17:12:49.000000000 +0100
 @@ -0,0 +1,91 @@
 +#ifndef _DFU_H
 +#define _DFU_H
@@ -891,7 +1030,7 @@
 Index: u-boot/include/usb_dfu_descriptors.h
 ===================================================================
 --- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ u-boot/include/usb_dfu_descriptors.h	2007-02-24 04:03:05.000000000 +0100
++++ u-boot/include/usb_dfu_descriptors.h	2007-02-24 17:12:49.000000000 +0100
 @@ -0,0 +1,94 @@
 +#ifndef _USB_DFU_H
 +#define _USB_DFU_H
@@ -989,8 +1128,8 @@
 +#endif /* _USB_DFU_H */
 Index: u-boot/include/usbdcore.h
 ===================================================================
---- u-boot.orig/include/usbdcore.h	2007-02-24 03:59:29.000000000 +0100
-+++ u-boot/include/usbdcore.h	2007-02-24 04:03:05.000000000 +0100
+--- u-boot.orig/include/usbdcore.h	2007-02-24 17:12:47.000000000 +0100
++++ u-boot/include/usbdcore.h	2007-02-24 17:12:49.000000000 +0100
 @@ -33,6 +33,7 @@
  
  #include <common.h>





More information about the commitlog mailing list