summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Hermann <uwe@debian.org>2008-12-28 05:47:51 +0100
committerAndrej Shadura <andrewsh@debian.org>2008-12-28 05:47:51 +0100
commitf9a2b90ffbd7f69e59ac8b5c2f1f6d3092313801 (patch)
treeac945c56ede6a03847e7eec16f3c63e32599b742
parente1b659b4b5702eaa32ed6ff594ab555044255a71 (diff)
Import Upstream version 0.0+r4880
-rw-r--r--configure.ac1
-rw-r--r--doc/dfu-util.1115
-rw-r--r--src/commands.c2
-rw-r--r--src/main.c98
-rw-r--r--src/sam7dfu.c13
5 files changed, 185 insertions, 44 deletions
diff --git a/configure.ac b/configure.ac
index 593a909..9f141c7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,6 @@ AC_CONFIG_AUX_DIR(m4)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
#AC_CONFIG_SRCDIR([src/atmel.c])
AM_CONFIG_HEADER([config.h])
-AC_C_BIGENDIAN
AM_MAINTAINER_MODE
diff --git a/doc/dfu-util.1 b/doc/dfu-util.1
new file mode 100644
index 0000000..3ccf044
--- /dev/null
+++ b/doc/dfu-util.1
@@ -0,0 +1,115 @@
+.TH DFU-UTIL 1 "February 29, 2008"
+.SH NAME
+dfu-util \- Device firmware update (DFU) USB programmer
+.SH SYNOPSIS
+.B dfu-util \fR[\fB\-ldpciatUDRhV\fR]
+.SH DESCRIPTION
+.B dfu-util
+is a program that implements the host (PC) side of the USB DFU
+(Universal Serial Bus Device Firmware Upgrade) protocol.
+.sp
+In the OpenMoko project (for example), this program is used to communicate
+with the specially enhanced u-boot boot loader, which implements the DFU
+device side.
+.SH OPTIONS
+.TP
+.B "\-l, \-\-list"
+List the currently attached DFU capable USB devices.
+.TP
+.BR "\-d, \-\-device" " VENDOR:PRODUCT"
+Specify vendor/product ID of the DFU device. Both
+.B VENDOR
+and
+.B PRODUCT
+are hex-numbers which must start with
+.BR 0x .
+Example:
+.sp
+.B " $ dfu-util --device 0x1457:0x5119"
+.sp
+If you only have one standards-compliant DFU device attached to your PC,
+this is optional. However, as soon as you have multiple DFU devices,
+dfu-util will detect this and abort, asking you to specify which device
+it shall use.
+.TP
+.BR "\-p, \-\-path" " BUS-PORT. ... .PORT"
+Specify the path to the DFU device.
+.TP
+.BR "\-c, \-\-cfg" " CONFIG-NR"
+Specify the configuration of the DFU device.
+.TP
+.BR "\-i, \-\-intf" " INTF-NR"
+Specify the DFU interface number.
+.TP
+.BR "\-a, \-\-alt" " ALT"
+Specify the altsetting of the DFU interface by name or by number.
+.TP
+.B "\-t, \-\-transfer-size"
+Specify the number of bytes per USB transfer. If you don't supply this
+option, the maximum possible size for your combination of host OS and
+USB device is chosen (for optimal performance).
+.TP
+.BR "\-U, \-\-upload" " FILE"
+Read firmware from device into
+.BR FILE .
+.sp
+.B Note:
+Upload support is currently broken.
+.TP
+.BR "\-D, \-\-download" " FILE"
+Write firmware from
+.B FILE
+into device.
+.TP
+.B "\-R, \-\-reset"
+Issue USB reset signalling once we're finished.
+.TP
+.B "\-h, \-\-help"
+Show a help text and exit.
+.TP
+.B "\-V, \-\-version"
+Show version information and exit.
+.SH EXAMPLES
+Here are some examples for the usage of dfu-util in the OpenMoko project
+(working with the Neo1973 hardware):
+.PP
+Flashing the rootfs:
+.br
+.B " $ dfu-util -a rootfs -R -D /path/to/openmoko-devel-image.jffs2"
+.PP
+Flashing the kernel:
+.br
+.B " $ dfu-util -a kernel -R -D /path/to/uImage"
+.PP
+Flashing the bootloader:
+.br
+.B " $ dfu-util -a u-boot -R -D /path/to/u-boot.bin"
+.PP
+Copying a kernel into RAM:
+.br
+.B " $ dfu-util -a 0 -R -D /path/to/uImage"
+.sp
+Once this has finished, the kernel will be available at the default load
+address of 0x32000000 in Neo1973 RAM.
+.sp
+.B Note:
+You cannot transfer more than 2MB of data into RAM using this method.
+.SH BUGS
+Please see
+.B http://wiki.openmoko.org/wiki/Dfu-util
+for some limitations and bugs in the current dfu-util code.
+.PP
+Please report any further bugs at
+.B http://bugzilla.openmoko.org
+or on the openmoko-kernel mailing list at
+.BR openmoko-kernel@lists.openmoko.org .
+.SH LICENCE
+.B dfu-util
+is covered by the GNU General Public License (GPL), version 2 or later.
+.SH AUTHORS
+Weston Schmidt <weston_schmidt@yahoo.com>
+.br
+Harald Welte <hwelte@hmw-consulting.de>
+.PP
+This manual page was written by Uwe Hermann <uwe@hermann-uwe.de>.
+It is licensed under the terms of the GNU GPL (version 2 or later).
diff --git a/src/commands.c b/src/commands.c
index e782be6..929db6b 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -340,7 +340,7 @@ static int execute_upload( struct usb_dev_handle *device,
if ( 0 > sam7dfu_do_upload(device, interface, 256, /* FIXME */
args.com_flash_data.file) )
{
- fprintf( stderr, "Download failed.\n" );
+ fprintf( stderr, "Upload failed.\n" );
return -1;
}
}
diff --git a/src/main.c b/src/main.c
index c6836ca..4eb7255 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,7 +1,7 @@
/*
* dfu-util
*
- * (C) 2007 by OpenMoko, Inc.
+ * (C) 2007-2008 by OpenMoko, Inc.
* Written by Harald Welte <laforge@openmoko.org>
*
* Based on existing code of dfu-programmer-0.4
@@ -26,8 +26,6 @@
#include <getopt.h>
#include <usb.h>
#include <errno.h>
-#include <byteswap.h>
-#include <endian.h>
#include "dfu.h"
#include "usb_dfu.h"
@@ -41,17 +39,13 @@
#include <usbpath.h>
#endif
-/* define a portable macro for swapping a 16bit word */
-#if defined(WORDS_BIGENDIAN)
-# if defined(__APPLE__) && defined (OSX)
-# include <libkern/OSByteOrder.h>
-# define LE2CPU16(x) OSSwapInt16(x)
-# else
-# define LE2CPU16(x) bswap_16(x)
-# endif
-#else
-# define LE2CPU16(x) (x)
-#endif
+/* define a portable function for reading a 16bit little-endian word */
+unsigned short get_int16_le(const void *p)
+{
+ const unsigned char *cp = p;
+
+ return ( cp[0] ) | ( ((unsigned short)cp[1]) << 8 );
+}
int debug;
static int verbose = 0;
@@ -168,15 +162,20 @@ static int print_dfu_if(struct dfu_if *dfu_if, void *v)
int if_name_str_idx;
char name[MAX_STR_LEN+1] = "UNDEFINED";
- if_name_str_idx = dev->config[dfu_if->configuration].interface[dfu_if->interface].altsetting[dfu_if->altsetting].iInterface;
+ if_name_str_idx = dev->config[dfu_if->configuration]
+ .interface[dfu_if->interface]
+ .altsetting[dfu_if->altsetting].iInterface;
if (if_name_str_idx) {
if (!dfu_if->dev_handle)
dfu_if->dev_handle = usb_open(dfu_if->dev);
if (dfu_if->dev_handle)
- usb_get_string_simple(dfu_if->dev_handle, if_name_str_idx, name, MAX_STR_LEN);
+ usb_get_string_simple(dfu_if->dev_handle,
+ if_name_str_idx, name,
+ MAX_STR_LEN);
}
- printf("Found %s: [0x%04x:0x%04x] devnum=%u, cfg=%u, intf=%u, alt=%u, name=\"%s\"\n",
+ printf("Found %s: [0x%04x:0x%04x] devnum=%u, cfg=%u, intf=%u, "
+ "alt=%u, name=\"%s\"\n",
dfu_if->flags & DFU_IFF_DFU ? "DFU" : "Runtime",
dev->descriptor.idVendor, dev->descriptor.idProduct,
dev->devnum, dfu_if->configuration, dfu_if->interface,
@@ -434,7 +433,7 @@ int main(int argc, char **argv)
int page_size = getpagesize();
int ret;
- printf("dfu-util - (C) 2007 by OpenMoko Inc.\n"
+ printf("dfu-util - (C) 2007-2008 by OpenMoko Inc.\n"
"This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n");
memset(dif, 0, sizeof(*dif));
@@ -446,7 +445,8 @@ int main(int argc, char **argv)
while (1) {
int c, option_index = 0;
- c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:R", opts, &option_index);
+ c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:R", opts,
+ &option_index);
if (c == -1)
break;
@@ -581,43 +581,53 @@ int main(int argc, char **argv)
printf("Claiming USB DFU Runtime Interface...\n");
if (usb_claim_interface(_rt_dif.dev_handle, _rt_dif.interface) < 0) {
- fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror());
+ fprintf(stderr, "Cannot claim interface: %s\n",
+ usb_strerror());
exit(1);
}
printf("Determining device status: ");
if (dfu_get_status(_rt_dif.dev_handle, _rt_dif.interface, &status ) < 0) {
- fprintf(stderr, "error get_status: %s\n", usb_strerror());
+ fprintf(stderr, "error get_status: %s\n",
+ usb_strerror());
exit(1);
}
- printf("state = %s, status = %d\n", dfu_state_to_string(status.bState), status.bStatus);
+ printf("state = %s, status = %d\n",
+ dfu_state_to_string(status.bState), status.bStatus);
switch (status.bState) {
case DFU_STATE_appIDLE:
case DFU_STATE_appDETACH:
- printf("Device really in Runtime Mode, send DFU detach request...\n");
- if (dfu_detach(_rt_dif.dev_handle, _rt_dif.interface, 1000) < 0) {
- fprintf(stderr, "error detaching: %s\n", usb_strerror());
+ printf("Device really in Runtime Mode, send DFU "
+ "detach request...\n");
+ if (dfu_detach(_rt_dif.dev_handle,
+ _rt_dif.interface, 1000) < 0) {
+ fprintf(stderr, "error detaching: %s\n",
+ usb_strerror());
exit(1);
break;
}
printf("Resetting USB...\n");
ret = usb_reset(_rt_dif.dev_handle);
if (ret < 0 && ret != -ENODEV)
- fprintf(stderr, "error resetting after detach: %s\n",
+ fprintf(stderr,
+ "error resetting after detach: %s\n",
usb_strerror());
sleep(2);
break;
case DFU_STATE_dfuERROR:
printf("dfuERROR, clearing status\n");
- if (dfu_clear_status(_rt_dif.dev_handle, _rt_dif.interface) < 0) {
- fprintf(stderr, "error clear_status: %s\n", usb_strerror());
+ if (dfu_clear_status(_rt_dif.dev_handle,
+ _rt_dif.interface) < 0) {
+ fprintf(stderr, "error clear_status: %s\n",
+ usb_strerror());
exit(1);
break;
}
break;
default:
- fprintf(stderr, "WARNING: Runtime device already in DFU state ?!?\n");
+ fprintf(stderr, "WARNING: Runtime device already "
+ "in DFU state ?!?\n");
goto dfustate;
break;
}
@@ -646,9 +656,9 @@ int main(int argc, char **argv)
fprintf(stderr, "Lost device after RESET?\n");
exit(1);
} else if (num_devs > 1) {
- fprintf(stderr, "More than one DFU capable USB device found, "
- "you might try `--list' and then disconnect all but one "
- "device\n");
+ fprintf(stderr, "More than one DFU capable USB "
+ "device found, you might try `--list' and "
+ "then disconnect all but one device\n");
exit(1);
}
if (!get_first_dfu_device(dif))
@@ -657,7 +667,8 @@ int main(int argc, char **argv)
printf("Opening USB Device...\n");
dif->dev_handle = usb_open(dif->dev);
if (!dif->dev_handle) {
- fprintf(stderr, "Cannot open device: %s\n", usb_strerror());
+ fprintf(stderr, "Cannot open device: %s\n",
+ usb_strerror());
exit(1);
}
} else {
@@ -690,7 +701,8 @@ dfustate:
exit(1);
} else if (num_ifs == 1) {
if (!get_first_dfu_if(dif)) {
- fprintf(stderr, "Can't find the single available DFU IF\n");
+ fprintf(stderr, "Can't find the single available "
+ "DFU IF\n");
exit(1);
}
} else if (num_ifs > 1 && !dif->flags & (DFU_IFF_IFACE|DFU_IFF_ALT)) {
@@ -703,13 +715,15 @@ dfustate:
#if 0
printf("Setting Configuration %u...\n", dif->configuration);
if (usb_set_configuration(dif->dev_handle, dif->configuration) < 0) {
- fprintf(stderr, "Cannot set configuration: %s\n", usb_strerror());
+ fprintf(stderr, "Cannot set configuration: %s\n",
+ usb_strerror());
exit(1);
}
#endif
printf("Claiming USB DFU Interface...\n");
if (usb_claim_interface(dif->dev_handle, dif->interface) < 0) {
- fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror());
+ fprintf(stderr, "Cannot claim interface: %s\n",
+ usb_strerror());
exit(1);
}
@@ -726,7 +740,8 @@ status_again:
fprintf(stderr, "error get_status: %s\n", usb_strerror());
exit(1);
}
- printf("state = %s, status = %d\n", dfu_state_to_string(status.bState), status.bStatus);
+ printf("state = %s, status = %d\n",
+ dfu_state_to_string(status.bState), status.bStatus);
switch (status.bState) {
case DFU_STATE_appIDLE:
@@ -737,7 +752,8 @@ status_again:
case DFU_STATE_dfuERROR:
printf("dfuERROR, clearing status\n");
if (dfu_clear_status(dif->dev_handle, dif->interface) < 0) {
- fprintf(stderr, "error clear_status: %s\n", usb_strerror());
+ fprintf(stderr, "error clear_status: %s\n",
+ usb_strerror());
exit(1);
}
goto status_again;
@@ -746,7 +762,8 @@ status_again:
case DFU_STATE_dfuUPLOAD_IDLE:
printf("aborting previous incomplete transfer\n");
if (dfu_abort(dif->dev_handle, dif->interface) < 0) {
- fprintf(stderr, "can't send DFU_ABORT: %s\n", usb_strerror());
+ fprintf(stderr, "can't send DFU_ABORT: %s\n",
+ usb_strerror());
exit(1);
}
goto status_again;
@@ -765,8 +782,7 @@ status_again:
"descriptor: %s\n", usb_strerror());
transfer_size = page_size;
} else {
- func_dfu.wTransferSize = LE2CPU16(func_dfu.wTransferSize);
- transfer_size = func_dfu.wTransferSize;
+ transfer_size = get_int16_le(&func_dfu.wTransferSize);
}
}
diff --git a/src/sam7dfu.c b/src/sam7dfu.c
index 536b2e1..e309bc7 100644
--- a/src/sam7dfu.c
+++ b/src/sam7dfu.c
@@ -1,5 +1,7 @@
/* This is supposed to be a "real" DFU implementation, just as specified in the
* USB DFU 1.0 Spec. Not overloaded like the Atmel one...
+ *
+ * (C) 2007-2008 by Harald Welte <laforge@gnumonks.org>
*/
#include <stdio.h>
@@ -36,6 +38,10 @@ int sam7dfu_do_upload(struct usb_dev_handle *usb_handle, int interface,
goto out_free;
}
+ printf("bytes_per_hash=%u\n", xfer_size);
+ printf("Starting upload: [");
+ fflush(stdout);
+
while (1) {
int rc, write_rc;
rc = dfu_upload(usb_handle, interface, xfer_size, buf);
@@ -45,7 +51,7 @@ int sam7dfu_do_upload(struct usb_dev_handle *usb_handle, int interface,
}
write_rc = write(fd, buf, rc);
if (write_rc < rc) {
- fprintf(stderr, "Short write: %s\n",
+ fprintf(stderr, "Short file write: %s\n",
strerror(errno));
ret = total_bytes;
goto out_close;
@@ -56,9 +62,14 @@ int sam7dfu_do_upload(struct usb_dev_handle *usb_handle, int interface,
ret = total_bytes;
goto out_close;
}
+ putchar('#');
+ fflush(stdout);
}
ret = 0;
+ printf("] finished!\n");
+ fflush(stdout);
+
out_close:
close(fd);
out_free: