diff -Nru dfu-util-0.4/ChangeLog dfu-util-0.5/ChangeLog --- dfu-util-0.4/ChangeLog 2011-07-20 11:52:03.000000000 +0000 +++ dfu-util-0.5/ChangeLog 2011-11-01 15:43:16.000000000 +0000 @@ -1,3 +1,11 @@ +0.5: + o DfuSe extension support for ST devices (Tormod Volden) + o Add initial support for bitWillDetach flag from DFU 1.1 (Tormod + Volden) + o Internal cleanup and some manual page fixes (Tormod Volden) + +2011-11-02: Stefan Schmidt + 0.4: o Rework to use libusb-1.0 (Stefan Schmidt) o DFU suffix support (Tormod Volden, Stefan Schmidt) diff -Nru dfu-util-0.4/configure dfu-util-0.5/configure --- dfu-util-0.4/configure 2011-07-19 15:14:06.000000000 +0000 +++ dfu-util-0.5/configure 2011-11-01 15:43:27.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for dfu-util 0.4. +# Generated by GNU Autoconf 2.68 for dfu-util 0.5. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -557,8 +557,8 @@ # Identity of this package. PACKAGE_NAME='dfu-util' PACKAGE_TARNAME='dfu-util' -PACKAGE_VERSION='0.4' -PACKAGE_STRING='dfu-util 0.4' +PACKAGE_VERSION='0.5' +PACKAGE_STRING='dfu-util 0.5' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1255,7 +1255,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures dfu-util 0.4 to adapt to many kinds of systems. +\`configure' configures dfu-util 0.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1321,7 +1321,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of dfu-util 0.4:";; + short | recursive ) echo "Configuration of dfu-util 0.5:";; esac cat <<\_ACEOF @@ -1419,7 +1419,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -dfu-util configure 0.4 +dfu-util configure 0.5 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1838,7 +1838,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by dfu-util $as_me 0.4, which was +It was created by dfu-util $as_me 0.5, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2653,7 +2653,7 @@ # Define the identity of the package. PACKAGE=dfu-util - VERSION=0.4 + VERSION=0.5 cat >>confdefs.h <<_ACEOF @@ -5144,7 +5144,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by dfu-util $as_me 0.4, which was +This file was extended by dfu-util $as_me 0.5, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5210,7 +5210,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -dfu-util config.status 0.4 +dfu-util config.status 0.5 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff -Nru dfu-util-0.4/configure.ac dfu-util-0.5/configure.ac --- dfu-util-0.4/configure.ac 2011-07-19 15:13:31.000000000 +0000 +++ dfu-util-0.5/configure.ac 2011-11-01 15:39:22.000000000 +0000 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([dfu-util],[0.4]) +AC_INIT([dfu-util],[0.5]) AC_CONFIG_AUX_DIR(m4) AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) AM_CONFIG_HEADER([config.h]) diff -Nru dfu-util-0.4/d/changelog dfu-util-0.5/d/changelog --- dfu-util-0.4/d/changelog 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/d/changelog 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -dfu-util (0.3-1) unstable; urgency=low - - * New upstream release. - * Standards-Version: 3.9.1 (no changes required). - * debian/rules: Drop obsolete dfu-util_static removal, it's gone upstream. - * debian/patches/00_upload_fixes.patch: Drop, merged upstream. - * debian/copyright: Small updates. - - -- Uwe Hermann Fri, 31 Dec 2010 22:32:52 +0100 - -dfu-util (0.1-1) unstable; urgency=low - - * New upstream release. - + Now states that only DFU 1.0 is supported (Closes: #569938). - * debian/control: - + Standards-Version: 3.9.0 (no changes required). - + Updated to new upstream homepage. - + Drop dependency on autoconf/automake, we no longer build from svn. - * debian/copyright: Various updates. - * debian/watch: Add proper URLs now, we no longer track svn snapshots. - * Fix "odd exit w/ upload; no error handling w/ download" (Closes: #582956). - Thanks C. Scott Ananian for the patch! - - -- Uwe Hermann Sat, 24 Jul 2010 15:46:44 +0200 - -dfu-util (0.0+r4880-1) unstable; urgency=low - - * Acknowledge NMU (Closes: #469892). Thanks Riku Voipio . - * New upstream release. - + This should also fix some broken behaviour on big-endian architectures. - * debian/control: - + Standards-Version: 3.8.0 (no changes required). - + Small description fix to silence bogus lintian warning. - * debian/copyright: Updates. - * debian/dfu-util.1: Dropped, now included upstream. - * debian/watch: Add dummy file to silence lintian (we track svn revisions). - * debian/rules: Remove generated files from diff. - - -- Uwe Hermann Sun, 28 Dec 2008 05:47:51 +0100 - -dfu-util (0.0+r4067-3.1) unstable; urgency=low - - * Non-maintainer upload. - * 0 day NMU for RC bug - * Add pkg-config to build-depends and verify with pbuilder that it works, - closes: #469892 , thanks Sebastian Bober sbober servercare.de - - -- Riku Voipio Wed, 28 May 2008 18:08:17 +0300 - -dfu-util (0.0+r4067-3) unstable; urgency=low - - * Add missing autoconf/automake build dependencies (Closes: #468791). - * I wrote a manpage, as there is none upstream. - - -- Uwe Hermann Sat, 01 Mar 2008 16:40:04 +0100 - -dfu-util (0.0+r4067-2) unstable; urgency=low - - * Do not install the dfu-util_static binary, it's not needed in Debian. - * debian/copyright: Convert to the machine-readable format described at - http://wiki.debian.org/Proposals/CopyrightFormat. - - -- Uwe Hermann Wed, 27 Feb 2008 21:24:42 +0100 - -dfu-util (0.0+r4067-1) unstable; urgency=low - - * Initial release (Closes: #465896). - - -- Uwe Hermann Wed, 27 Feb 2008 16:45:28 +0100 diff -Nru dfu-util-0.4/d/compat dfu-util-0.5/d/compat --- dfu-util-0.4/d/compat 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/d/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -7 diff -Nru dfu-util-0.4/d/control dfu-util-0.5/d/control --- dfu-util-0.4/d/control 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/d/control 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -Source: dfu-util -Section: electronics -Priority: extra -Maintainer: Uwe Hermann -Build-Depends: cdbs, debhelper (>= 7.0.50~), autotools-dev, libusb-dev, pkg-config -Standards-Version: 3.9.1 -Homepage: http://dfu-util.gnumonks.org/ - -Package: dfu-util -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: Device firmware update (DFU 1.0) USB programmer - dfu-util is a program that implements the host (PC) side of the USB DFU 1.0 - (Universal Serial Bus Device Firmware Upgrade) protocol. - . - Note: At this point only DFU version 1.0 is supported! - . - In the OpenMoko project (for example), this program is used to communicate - with the specially enhanced bootloader u-boot, which implements the DFU - device side. - diff -Nru dfu-util-0.4/d/copyright dfu-util-0.5/d/copyright --- dfu-util-0.4/d/copyright 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/d/copyright 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -This package was debianized by Uwe Hermann on -Fri, 15 Feb 2008 12:51:18 +0100. - -It was downloaded from: - - http://dfu-util.gnumonks.org/ - -Upstream authors: - - Weston Schmidt - Harald Welte - Stefan Schmidt - Tormod Volden - -------------------------------------------------------------------------------- - -Files: * -Copyright: © 2005-2007 Weston Schmidt - © 2006-2008 Harald Welte - © 2007-2008 OpenMoko, Inc. - © 2010 Tormod Volden -License: GPL-2+ - -On Debian systems, the complete text of the GNU General -Public License can be found in `/usr/share/common-licenses/GPL-2'. - -------------------------------------------------------------------------------- - -Files: debian/* -Copyright: © 2008-2010 Uwe Hermann -License: GPL-2+ - The Debian packaging is © 2008-2010, Uwe Hermann and - is licensed under the GPL (version 2 or later), see above. - diff -Nru dfu-util-0.4/d/docs dfu-util-0.5/d/docs --- dfu-util-0.4/d/docs 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/d/docs 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -README -TODO diff -Nru dfu-util-0.4/d/rules dfu-util-0.5/d/rules --- dfu-util-0.4/d/rules 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/d/rules 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -#!/usr/bin/make -f - -include /usr/share/cdbs/1/rules/debhelper.mk -include /usr/share/cdbs/1/class/autotools.mk -include /usr/share/cdbs/1/rules/utils.mk - -DEB_INSTALL_MANPAGES_dfu-util := doc/dfu-util.1 - -common-binary-post-install-arch:: list-missing - diff -Nru dfu-util-0.4/d/source/format dfu-util-0.5/d/source/format --- dfu-util-0.4/d/source/format 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/d/source/format 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -3.0 (quilt) diff -Nru dfu-util-0.4/d/watch dfu-util-0.5/d/watch --- dfu-util-0.4/d/watch 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/d/watch 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -version=3 -http://dfu-util.gnumonks.org/releases/dfu-util-(.*)\.tar\.gz diff -Nru dfu-util-0.4/debian/changelog dfu-util-0.5/debian/changelog --- dfu-util-0.4/debian/changelog 2011-08-31 21:16:03.000000000 +0000 +++ dfu-util-0.5/debian/changelog 2011-12-26 19:18:31.000000000 +0000 @@ -1,3 +1,9 @@ +dfu-util (0.5-1) unstable; urgency=low + + * New upstream release. + + -- Uwe Hermann Mon, 26 Dec 2011 20:18:19 +0100 + dfu-util (0.4-1) unstable; urgency=low * New upstream release. diff -Nru dfu-util-0.4/debian/copyright dfu-util-0.5/debian/copyright --- dfu-util-0.4/debian/copyright 2011-08-31 21:09:40.000000000 +0000 +++ dfu-util-0.5/debian/copyright 2011-12-26 19:18:54.000000000 +0000 @@ -27,8 +27,8 @@ ------------------------------------------------------------------------------- Files: debian/* -Copyright: © 2008-2010 Uwe Hermann +Copyright: © 2008-2011 Uwe Hermann License: GPL-2+ - The Debian packaging is © 2008-2010, Uwe Hermann and + The Debian packaging is © 2008-2011, Uwe Hermann and is licensed under the GPL (version 2 or later), see above. diff -Nru dfu-util-0.4/debian/dd/changelog dfu-util-0.5/debian/dd/changelog --- dfu-util-0.4/debian/dd/changelog 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/changelog 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -dfu-util (0.4-1) unstable; urgency=low - - * Initial release (Closes: #nnnn) - - -- Uwe Hermann Wed, 31 Aug 2011 23:10:05 +0200 diff -Nru dfu-util-0.4/debian/dd/compat dfu-util-0.5/debian/dd/compat --- dfu-util-0.4/debian/dd/compat 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -8 diff -Nru dfu-util-0.4/debian/dd/control dfu-util-0.5/debian/dd/control --- dfu-util-0.4/debian/dd/control 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/control 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -Source: dfu-util -Section: unknown -Priority: extra -Maintainer: Uwe Hermann -Build-Depends: cdbs, debhelper (>= 8.0.0), autotools-dev -Standards-Version: 3.9.2 -Homepage: -#Vcs-Git: git://git.debian.org/collab-maint/dfu-util.git -#Vcs-Browser: http://git.debian.org/?p=collab-maint/dfu-util.git;a=summary - -Package: dfu-util -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: - diff -Nru dfu-util-0.4/debian/dd/copyright dfu-util-0.5/debian/dd/copyright --- dfu-util-0.4/debian/dd/copyright 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/copyright 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -Format: http://dep.debian.net/deps/dep5 -Upstream-Name: dfu-util -Source: - -Files: * -Copyright: - -License: GPL-3.0+ - -Files: debian/* -Copyright: 2011 Uwe Hermann -License: GPL-3.0+ - -License: GPL-3.0+ - 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 3 of the License, or - (at your option) any later version. - . - This package 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, see . - . - On Debian systems, the complete text of the GNU General - Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". - -# Please also look if there are files or directories which have a -# different copyright/license attached and list them here. diff -Nru dfu-util-0.4/debian/dd/dfu-util.cron.d.ex dfu-util-0.5/debian/dd/dfu-util.cron.d.ex --- dfu-util-0.4/debian/dd/dfu-util.cron.d.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/dfu-util.cron.d.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -# -# Regular cron jobs for the dfu-util package -# -0 4 * * * root [ -x /usr/bin/dfu-util_maintenance ] && /usr/bin/dfu-util_maintenance diff -Nru dfu-util-0.4/debian/dd/dfu-util.default.ex dfu-util-0.5/debian/dd/dfu-util.default.ex --- dfu-util-0.4/debian/dd/dfu-util.default.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/dfu-util.default.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# Defaults for dfu-util initscript -# sourced by /etc/init.d/dfu-util -# installed at /etc/default/dfu-util by the maintainer scripts - -# -# This is a POSIX shell fragment -# - -# Additional options that are passed to the Daemon. -DAEMON_OPTS="" diff -Nru dfu-util-0.4/debian/dd/dfu-util.doc-base.EX dfu-util-0.5/debian/dd/dfu-util.doc-base.EX --- dfu-util-0.4/debian/dd/dfu-util.doc-base.EX 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/dfu-util.doc-base.EX 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -Document: dfu-util -Title: Debian dfu-util Manual -Author: -Abstract: This manual describes what dfu-util is - and how it can be used to - manage online manuals on Debian systems. -Section: unknown - -Format: debiandoc-sgml -Files: /usr/share/doc/dfu-util/dfu-util.sgml.gz - -Format: postscript -Files: /usr/share/doc/dfu-util/dfu-util.ps.gz - -Format: text -Files: /usr/share/doc/dfu-util/dfu-util.text.gz - -Format: HTML -Index: /usr/share/doc/dfu-util/html/index.html -Files: /usr/share/doc/dfu-util/html/*.html diff -Nru dfu-util-0.4/debian/dd/docs dfu-util-0.5/debian/dd/docs --- dfu-util-0.4/debian/dd/docs 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/docs 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -DEVICES.txt -README -TODO diff -Nru dfu-util-0.4/debian/dd/emacsen-install.ex dfu-util-0.5/debian/dd/emacsen-install.ex --- dfu-util-0.4/debian/dd/emacsen-install.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/emacsen-install.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -#! /bin/sh -e -# /usr/lib/emacsen-common/packages/install/dfu-util - -# Written by Jim Van Zandt , borrowing heavily -# from the install scripts for gettext by Santiago Vila -# and octave by Dirk Eddelbuettel . - -FLAVOR=$1 -PACKAGE=dfu-util - -if [ ${FLAVOR} = emacs ]; then exit 0; fi - -echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR} - -#FLAVORTEST=`echo $FLAVOR | cut -c-6` -#if [ ${FLAVORTEST} = xemacs ] ; then -# SITEFLAG="-no-site-file" -#else -# SITEFLAG="--no-site-file" -#fi -FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile" - -ELDIR=/usr/share/emacs/site-lisp/${PACKAGE} -ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE} - -# Install-info-altdir does not actually exist. -# Maybe somebody will write it. -if test -x /usr/sbin/install-info-altdir; then - echo install/${PACKAGE}: install Info links for ${FLAVOR} - install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/share/info/${PACKAGE}.info.gz -fi - -install -m 755 -d ${ELCDIR} -cd ${ELDIR} -FILES=`echo *.el` -cp ${FILES} ${ELCDIR} -cd ${ELCDIR} - -cat << EOF > path.el -(setq load-path (cons "." load-path) byte-compile-warnings nil) -EOF -${FLAVOR} ${FLAGS} ${FILES} -rm -f *.el path.el - -exit 0 diff -Nru dfu-util-0.4/debian/dd/emacsen-remove.ex dfu-util-0.5/debian/dd/emacsen-remove.ex --- dfu-util-0.4/debian/dd/emacsen-remove.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/emacsen-remove.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -#!/bin/sh -e -# /usr/lib/emacsen-common/packages/remove/dfu-util - -FLAVOR=$1 -PACKAGE=dfu-util - -if [ ${FLAVOR} != emacs ]; then - if test -x /usr/sbin/install-info-altdir; then - echo remove/${PACKAGE}: removing Info links for ${FLAVOR} - install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/share/info/dfu-util.info.gz - fi - - echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR} - rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE} -fi diff -Nru dfu-util-0.4/debian/dd/emacsen-startup.ex dfu-util-0.5/debian/dd/emacsen-startup.ex --- dfu-util-0.4/debian/dd/emacsen-startup.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/emacsen-startup.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -;; -*-emacs-lisp-*- -;; -;; Emacs startup file, e.g. /etc/emacs/site-start.d/50dfu-util.el -;; for the Debian dfu-util package -;; -;; Originally contributed by Nils Naumann -;; Modified by Dirk Eddelbuettel -;; Adapted for dh-make by Jim Van Zandt - -;; The dfu-util package follows the Debian/GNU Linux 'emacsen' policy and -;; byte-compiles its elisp files for each 'emacs flavor' (emacs19, -;; xemacs19, emacs20, xemacs20...). The compiled code is then -;; installed in a subdirectory of the respective site-lisp directory. -;; We have to add this to the load-path: -(let ((package-dir (concat "/usr/share/" - (symbol-name flavor) - "/site-lisp/dfu-util"))) -;; If package-dir does not exist, the dfu-util package must have -;; removed but not purged, and we should skip the setup. - (when (file-directory-p package-dir) - (setq load-path (cons package-dir load-path)) - (autoload 'dfu-util-mode "dfu-util-mode" - "Major mode for editing dfu-util files." t) - (add-to-list 'auto-mode-alist '("\\.dfu-util$" . dfu-util-mode)))) - diff -Nru dfu-util-0.4/debian/dd/init.d.ex dfu-util-0.5/debian/dd/init.d.ex --- dfu-util-0.4/debian/dd/init.d.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/init.d.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: dfu-util -# Required-Start: $network $local_fs -# Required-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: -# Description: -# <...> -# <...> -### END INIT INFO - -# Author: Uwe Hermann - -# PATH should only include /usr/* if it runs after the mountnfs.sh script -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC=dfu-util # Introduce a short description here -NAME=dfu-util # Introduce the short server's name here -DAEMON=/usr/sbin/dfu-util # Introduce the server's location here -DAEMON_ARGS="" # Arguments to run the daemon with -PIDFILE=/var/run/$NAME.pid -SCRIPTNAME=/etc/init.d/$NAME - -# Exit if the package is not installed -[ -x $DAEMON ] || exit 0 - -# Read configuration variable file if it is present -[ -r /etc/default/$NAME ] && . /etc/default/$NAME - -# Load the VERBOSE setting and other rcS variables -. /lib/init/vars.sh - -# Define LSB log_* functions. -# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. -. /lib/lsb/init-functions - -# -# Function that starts the daemon/service -# -do_start() -{ - # Return - # 0 if daemon has been started - # 1 if daemon was already running - # 2 if daemon could not be started - start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ - || return 1 - start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ - $DAEMON_ARGS \ - || return 2 - # Add code here, if necessary, that waits for the process to be ready - # to handle requests from services started subsequently which depend - # on this one. As a last resort, sleep for some time. -} - -# -# Function that stops the daemon/service -# -do_stop() -{ - # Return - # 0 if daemon has been stopped - # 1 if daemon was already stopped - # 2 if daemon could not be stopped - # other if a failure occurred - start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME - RETVAL="$?" - [ "$RETVAL" = 2 ] && return 2 - # Wait for children to finish too if this is a daemon that forks - # and if the daemon is only ever run from this initscript. - # If the above conditions are not satisfied then add some other code - # that waits for the process to drop all resources that could be - # needed by services started subsequently. A last resort is to - # sleep for some time. - start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON - [ "$?" = 2 ] && return 2 - # Many daemons don't delete their pidfiles when they exit. - rm -f $PIDFILE - return "$RETVAL" -} - -# -# Function that sends a SIGHUP to the daemon/service -# -do_reload() { - # - # If the daemon can reload its configuration without - # restarting (for example, when it is sent a SIGHUP), - # then implement that here. - # - start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME - return 0 -} - -case "$1" in - start) - [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME" - do_start - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - stop) - [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" - do_stop - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - status) - status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? - ;; - #reload|force-reload) - # - # If do_reload() is not implemented then leave this commented out - # and leave 'force-reload' as an alias for 'restart'. - # - #log_daemon_msg "Reloading $DESC" "$NAME" - #do_reload - #log_end_msg $? - #;; - restart|force-reload) - # - # If the "reload" option is implemented then remove the - # 'force-reload' alias - # - log_daemon_msg "Restarting $DESC" "$NAME" - do_stop - case "$?" in - 0|1) - do_start - case "$?" in - 0) log_end_msg 0 ;; - 1) log_end_msg 1 ;; # Old process is still running - *) log_end_msg 1 ;; # Failed to start - esac - ;; - *) - # Failed to stop - log_end_msg 1 - ;; - esac - ;; - *) - #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 - echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 - exit 3 - ;; -esac - -: diff -Nru dfu-util-0.4/debian/dd/manpage.1.ex dfu-util-0.5/debian/dd/manpage.1.ex --- dfu-util-0.4/debian/dd/manpage.1.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/manpage.1.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -.\" Hey, EMACS: -*- nroff -*- -.\" First parameter, NAME, should be all caps -.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection -.\" other parameters are allowed: see man(7), man(1) -.TH DFU-UTIL SECTION "August 31, 2011" -.\" Please adjust this date whenever revising the manpage. -.\" -.\" Some roff macros, for reference: -.\" .nh disable hyphenation -.\" .hy enable hyphenation -.\" .ad l left justify -.\" .ad b justify to both left and right margins -.\" .nf disable filling -.\" .fi enable filling -.\" .br insert line break -.\" .sp insert n+1 empty lines -.\" for manpage-specific macros, see man(7) -.SH NAME -dfu-util \- program to do something -.SH SYNOPSIS -.B dfu-util -.RI [ options ] " files" ... -.br -.B bar -.RI [ options ] " files" ... -.SH DESCRIPTION -This manual page documents briefly the -.B dfu-util -and -.B bar -commands. -.PP -.\" TeX users may be more comfortable with the \fB\fP and -.\" \fI\fP escape sequences to invode bold face and italics, -.\" respectively. -\fBdfu-util\fP is a program that... -.SH OPTIONS -These programs follow the usual GNU command line syntax, with long -options starting with two dashes (`-'). -A summary of options is included below. -For a complete description, see the Info files. -.TP -.B \-h, \-\-help -Show summary of options. -.TP -.B \-v, \-\-version -Show version of program. -.SH SEE ALSO -.BR bar (1), -.BR baz (1). -.br -The programs are documented fully by -.IR "The Rise and Fall of a Fooish Bar" , -available via the Info system. -.SH AUTHOR -dfu-util was written by . -.PP -This manual page was written by Uwe Hermann , -for the Debian project (and may be used by others). diff -Nru dfu-util-0.4/debian/dd/manpage.sgml.ex dfu-util-0.5/debian/dd/manpage.sgml.ex --- dfu-util-0.4/debian/dd/manpage.sgml.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/manpage.sgml.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ - manpage.1'. You may view - the manual page with: `docbook-to-man manpage.sgml | nroff -man | - less'. A typical entry in a Makefile or Makefile.am is: - -manpage.1: manpage.sgml - docbook-to-man $< > $@ - - - The docbook-to-man binary is found in the docbook-to-man package. - Please remember that if you create the nroff version in one of the - debian/rules file targets (such as build), you will need to include - docbook-to-man in your Build-Depends control field. - - --> - - - FIRSTNAME"> - SURNAME"> - - August 31, 2011"> - - SECTION"> - uwe@debian.org"> - - DFU-UTIL"> - - - Debian"> - GNU"> - GPL"> -]> - - - -
- &dhemail; -
- - &dhfirstname; - &dhsurname; - - - 2003 - &dhusername; - - &dhdate; -
- - &dhucpackage; - - &dhsection; - - - &dhpackage; - - program to do something - - - - &dhpackage; - - - - - - - - DESCRIPTION - - This manual page documents briefly the - &dhpackage; and bar - commands. - - This manual page was written for the &debian; distribution - because the original program does not have a manual page. - Instead, it has documentation in the &gnu; - Info format; see below. - - &dhpackage; is a program that... - - - - OPTIONS - - These programs follow the usual &gnu; command line syntax, - with long options starting with two dashes (`-'). A summary of - options is included below. For a complete description, see the - Info files. - - - - - - - - Show summary of options. - - - - - - - - Show version of program. - - - - - - SEE ALSO - - bar (1), baz (1). - - The programs are documented fully by The Rise and - Fall of a Fooish Bar available via the - Info system. - - - AUTHOR - - This manual page was written by &dhusername; &dhemail; for - the &debian; system (and may be used by others). Permission is - granted to copy, distribute and/or modify this document under - the terms of the &gnu; General Public License, Version 2 any - later version published by the Free Software Foundation. - - - On Debian systems, the complete text of the GNU General Public - License can be found in /usr/share/common-licenses/GPL. - - - -
- - diff -Nru dfu-util-0.4/debian/dd/manpage.xml.ex dfu-util-0.5/debian/dd/manpage.xml.ex --- dfu-util-0.4/debian/dd/manpage.xml.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/manpage.xml.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,291 +0,0 @@ - -.
will be generated. You may view the -manual page with: nroff -man .
| less'. A typical entry -in a Makefile or Makefile.am is: - -DB2MAN = /usr/share/sgml/docbook/stylesheet/xsl/docbook-xsl/manpages/docbook.xsl -XP = xsltproc -''-nonet -''-param man.charmap.use.subset "0" - -manpage.1: manpage.xml - $(XP) $(DB2MAN) $< - -The xsltproc binary is found in the xsltproc package. The XSL files are in -docbook-xsl. A description of the parameters you can use can be found in the -docbook-xsl-doc-* packages. Please remember that if you create the nroff -version in one of the debian/rules file targets (such as build), you will need -to include xsltproc and docbook-xsl in your Build-Depends control field. -Alternatively use the xmlto command/package. That will also automatically -pull in xsltproc and docbook-xsl. - -Notes for using docbook2x: docbook2x-man does not automatically create the -AUTHOR(S) and COPYRIGHT sections. In this case, please add them manually as - ... . - -To disable the automatic creation of the AUTHOR(S) and COPYRIGHT sections -read /usr/share/doc/docbook-xsl/doc/manpages/authors.html. This file can be -found in the docbook-xsl-doc-html package. - -Validation can be done using: `xmllint -''-noout -''-valid manpage.xml` - -General documentation about man-pages and man-page-formatting: -man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/ - ---> - - - - - - - - - - - - - -]> - - - - &dhtitle; - &dhpackage; - - - &dhfirstname; - &dhsurname; - Wrote this manpage for the Debian system. -
- &dhemail; -
-
-
- - 2007 - &dhusername; - - - This manual page was written for the Debian system - (and may be used by others). - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU General Public License, - Version 2 or (at your option) any later version published by - the Free Software Foundation. - On Debian systems, the complete text of the GNU General Public - License can be found in - /usr/share/common-licenses/GPL. - -
- - &dhucpackage; - &dhsection; - - - &dhpackage; - program to do something - - - - &dhpackage; - - - - - - - - - this - - - - - - - - this - that - - - - - &dhpackage; - - - - - - - - - - - - - - - - - - - DESCRIPTION - This manual page documents briefly the - &dhpackage; and bar - commands. - This manual page was written for the Debian distribution - because the original program does not have a manual page. - Instead, it has documentation in the GNU - info - 1 - format; see below. - &dhpackage; is a program that... - - - OPTIONS - The program follows the usual GNU command line syntax, - with long options starting with two dashes (`-'). A summary of - options is included below. For a complete description, see the - - info - 1 - files. - - - - - - - Does this and that. - - - - - - - Show summary of options. - - - - - - - Show version of program. - - - - - - FILES - - - /etc/foo.conf - - The system-wide configuration file to control the - behaviour of &dhpackage;. See - - foo.conf - 5 - for further details. - - - - ${HOME}/.foo.conf - - The per-user configuration file to control the - behaviour of &dhpackage;. See - - foo.conf - 5 - for further details. - - - - - - ENVIONMENT - - - FOO_CONF - - If used, the defined file is used as configuration - file (see also ). - - - - - - DIAGNOSTICS - The following diagnostics may be issued - on stderr: - - - Bad configuration file. Exiting. - - The configuration file seems to contain a broken configuration - line. Use the option, to get more info. - - - - - &dhpackage; provides some return codes, that can - be used in scripts: - - Code - Diagnostic - - 0 - Program exited successfully. - - - 1 - The configuration file seems to be broken. - - - - - - BUGS - The program is currently limited to only work - with the foobar library. - The upstreams BTS can be found - at . - - - SEE ALSO - - - bar - 1 - , - baz - 1 - , - foo.conf - 5 - - The programs are documented fully by The Rise and - Fall of a Fooish Bar available via the - info - 1 - system. - -
- diff -Nru dfu-util-0.4/debian/dd/menu.ex dfu-util-0.5/debian/dd/menu.ex --- dfu-util-0.4/debian/dd/menu.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/menu.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -?package(dfu-util):needs="X11|text|vc|wm" section="Applications/see-menu-manual"\ - title="dfu-util" command="/usr/bin/dfu-util" diff -Nru dfu-util-0.4/debian/dd/postinst.ex dfu-util-0.5/debian/dd/postinst.ex --- dfu-util-0.4/debian/dd/postinst.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/postinst.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -#!/bin/sh -# postinst script for dfu-util -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `configure' -# * `abort-upgrade' -# * `abort-remove' `in-favour' -# -# * `abort-remove' -# * `abort-deconfigure' `in-favour' -# `removing' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - configure) - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 diff -Nru dfu-util-0.4/debian/dd/postrm.ex dfu-util-0.5/debian/dd/postrm.ex --- dfu-util-0.4/debian/dd/postrm.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/postrm.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -#!/bin/sh -# postrm script for dfu-util -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `remove' -# * `purge' -# * `upgrade' -# * `failed-upgrade' -# * `abort-install' -# * `abort-install' -# * `abort-upgrade' -# * `disappear' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - ;; - - *) - echo "postrm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 diff -Nru dfu-util-0.4/debian/dd/preinst.ex dfu-util-0.5/debian/dd/preinst.ex --- dfu-util-0.4/debian/dd/preinst.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/preinst.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -#!/bin/sh -# preinst script for dfu-util -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `install' -# * `install' -# * `upgrade' -# * `abort-upgrade' -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - install|upgrade) - ;; - - abort-upgrade) - ;; - - *) - echo "preinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 diff -Nru dfu-util-0.4/debian/dd/prerm.ex dfu-util-0.5/debian/dd/prerm.ex --- dfu-util-0.4/debian/dd/prerm.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/prerm.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -#!/bin/sh -# prerm script for dfu-util -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `remove' -# * `upgrade' -# * `failed-upgrade' -# * `remove' `in-favour' -# * `deconfigure' `in-favour' -# `removing' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - remove|upgrade|deconfigure) - ;; - - failed-upgrade) - ;; - - *) - echo "prerm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 diff -Nru dfu-util-0.4/debian/dd/README.Debian dfu-util-0.5/debian/dd/README.Debian --- dfu-util-0.4/debian/dd/README.Debian 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/README.Debian 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -dfu-util for Debian -------------------- - - - - -- Uwe Hermann Wed, 31 Aug 2011 23:10:05 +0200 diff -Nru dfu-util-0.4/debian/dd/README.source dfu-util-0.5/debian/dd/README.source --- dfu-util-0.4/debian/dd/README.source 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/README.source 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -dfu-util for Debian -------------------- - - - - - - diff -Nru dfu-util-0.4/debian/dd/rules dfu-util-0.5/debian/dd/rules --- dfu-util-0.4/debian/dd/rules 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/rules 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -#!/usr/bin/make -f - -include /usr/share/cdbs/1/rules/debhelper.mk -include /usr/share/cdbs/1/class/autotools.mk - - -# Add here any variable or target overrides you need. diff -Nru dfu-util-0.4/debian/dd/source/format dfu-util-0.5/debian/dd/source/format --- dfu-util-0.4/debian/dd/source/format 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/source/format 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -3.0 (quilt) diff -Nru dfu-util-0.4/debian/dd/watch.ex dfu-util-0.5/debian/dd/watch.ex --- dfu-util-0.4/debian/dd/watch.ex 2011-08-31 21:10:06.000000000 +0000 +++ dfu-util-0.5/debian/dd/watch.ex 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# Example watch control file for uscan -# Rename this file to "watch" and then you can run the "uscan" command -# to check for upstream updates and more. -# See uscan(1) for format - -# Compulsory line, this is a version 3 file -version=3 - -# Uncomment to examine a Webpage -# -#http://www.example.com/downloads.php dfu-util-(.*)\.tar\.gz - -# Uncomment to examine a Webserver directory -#http://www.example.com/pub/dfu-util-(.*)\.tar\.gz - -# Uncommment to examine a FTP server -#ftp://ftp.example.com/pub/dfu-util-(.*)\.tar\.gz debian uupdate - -# Uncomment to find new files on sourceforge, for devscripts >= 2.9 -# http://sf.net/dfu-util/dfu-util-(.*)\.tar\.gz - -# Uncomment to find new files on GooglePages -# http://example.googlepages.com/foo.html dfu-util-(.*)\.tar\.gz diff -Nru dfu-util-0.4/doc/dfu-util.1 dfu-util-0.5/doc/dfu-util.1 --- dfu-util-0.4/doc/dfu-util.1 2011-07-19 15:20:21.000000000 +0000 +++ dfu-util-0.5/doc/dfu-util.1 2011-10-31 09:00:32.000000000 +0000 @@ -5,7 +5,7 @@ .B dfu-util \fR[\fB\-ldpciatUDRhvV\fR] .SH DESCRIPTION .B dfu-util -is a program that implements the host (PC) side of the USB DFU +is a program that implements the host (computer) 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 @@ -21,11 +21,10 @@ .B VENDOR and .B PRODUCT -are hex-numbers which must start with -.BR 0x . +are hexadecimal numbers (no prefix needed). Example: .sp -.B " $ dfu-util --device 0x1457:0x5119" +.B " $ dfu-util --device 1457:51ab" .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, @@ -62,7 +61,11 @@ into device. .TP .B "\-R, \-\-reset" -Issue USB reset signalling once we're finished. +Issue USB reset signalling once we are finished. +.TP +.B "\-s, \-\-dfuse-address" +Specify target address for raw binary download/upload on DfuSe devices. +Do not use this for downloading DfuSe files. .TP .B "\-h, \-\-help" Show a help text and exit. diff -Nru dfu-util-0.4/src/dfu.h dfu-util-0.5/src/dfu.h --- dfu-util-0.4/src/dfu.h 2011-07-18 18:29:44.000000000 +0000 +++ dfu-util-0.5/src/dfu.h 2011-09-06 17:49:17.000000000 +0000 @@ -96,6 +96,7 @@ u_int8_t configuration; u_int8_t interface; u_int8_t altsetting; + unsigned char *alt_name; int bus; u_int8_t devnum; const char *path; diff -Nru dfu-util-0.4/src/dfuse.c dfu-util-0.5/src/dfuse.c --- dfu-util-0.4/src/dfuse.c 1970-01-01 00:00:00.000000000 +0000 +++ dfu-util-0.5/src/dfuse.c 2011-10-31 09:00:32.000000000 +0000 @@ -0,0 +1,589 @@ +/* This implements the ST Microsystems DFU extensions (DfuSe) + * as per the DfuSe 1.1a specification (Document UM0391) + * + * (C) 2010-2011 Tormod Volden + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "dfu.h" +#include "usb_dfu.h" +#include "dfu_file.h" +#include "dfuse.h" +#include "dfuse_mem.h" + +/* ugly hack for Win32 */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define DFU_TIMEOUT 5000 + +extern int verbose; +static unsigned int last_erased = 0; +static struct memsegment *mem_layout; + +unsigned int quad2uint(unsigned char *p) +{ + return (*p + (*(p + 1) << 8) + (*(p + 2) << 16) + (*(p + 3) << 24)); +} + +/* DFU_UPLOAD request for DfuSe 1.1a */ +int dfuse_upload(struct dfu_if *dif, const unsigned short length, + unsigned char *data, unsigned short transaction) +{ + int status; + + status = libusb_control_transfer(dif->dev_handle, + /* bmRequestType */ LIBUSB_ENDPOINT_IN | + LIBUSB_REQUEST_TYPE_CLASS | + LIBUSB_RECIPIENT_INTERFACE, + /* bRequest */ DFU_UPLOAD, + /* wValue */ transaction, + /* wIndex */ dif->interface, + /* Data */ data, + /* wLength */ length, + DFU_TIMEOUT); + if (status < 0) { + fprintf(stderr, "%s: libusb_control_msg returned %d\n", + __FUNCTION__, status); + } + return status; +} + +/* DFU_DNLOAD request for DfuSe 1.1a */ +int dfuse_download(struct dfu_if *dif, const unsigned short length, + unsigned char *data, unsigned short transaction) +{ + int status; + + status = libusb_control_transfer(dif->dev_handle, + /* bmRequestType */ LIBUSB_ENDPOINT_OUT | + LIBUSB_REQUEST_TYPE_CLASS | + LIBUSB_RECIPIENT_INTERFACE, + /* bRequest */ DFU_DNLOAD, + /* wValue */ transaction, + /* wIndex */ dif->interface, + /* Data */ data, + /* wLength */ length, + DFU_TIMEOUT); + if (status < 0) { + fprintf(stderr, "%s: libusb_control_transfer returned %d\n", + __FUNCTION__, status); + } + return status; +} + +/* DfuSe only commands */ +int dfuse_special_command(struct dfu_if *dif, unsigned int address, + enum dfuse_command command) +{ + unsigned char buf[5]; + int length; + int ret; + struct dfu_status dst; + + if (command == ERASE_PAGE) { + struct memsegment *segment; + int page_size; + + segment = find_segment(mem_layout, address); + if (!segment || !(segment->memtype & DFUSE_ERASABLE)) { + fprintf(stderr, + "Error: Page at 0x%08x can not be erased\n", + address); + exit(1); + } + page_size = segment->pagesize; + if (verbose > 1) + printf("Erasing page size %i at address 0x%08x, page " + "starting at 0x%08x\n", page_size, address, + address & ~(page_size - 1)); + buf[0] = 0x41; /* Erase command */ + length = 5; + last_erased = address; + } else if (command == SET_ADDRESS) { + if (verbose > 2) + printf(" Setting address pointer to 0x%08x\n", + address); + buf[0] = 0x21; /* Set Address Pointer command */ + length = 5; + } else if (command == MASS_ERASE) { + buf[0] = 0x41; /* Mass erase command when length = 1 */ + length = 1; + } else { + fprintf(stderr, "Error: Non-supported special command %d\n", + command); + exit(1); + } + buf[1] = address & 0xff; + buf[2] = (address >> 8) & 0xff; + buf[3] = (address >> 16) & 0xff; + buf[4] = (address >> 24) & 0xff; + + ret = dfuse_download(dif, length, buf, 0); + if (ret < 0) { + fprintf(stderr, "Error during special command download\n"); + exit(1); + } + ret = dfu_get_status(dif->dev_handle, dif->interface, &dst); + if (ret < 0) { + fprintf(stderr, "Error during special command get_status\n"); + exit(1); + } + if (dst.bState != DFU_STATE_dfuDNBUSY) { + fprintf(stderr, "Error: Wrong state after command download\n"); + exit(1); + } + /* wait while command is executed */ + usleep(dst.bwPollTimeout * 1000); + + ret = dfu_get_status(dif->dev_handle, dif->interface, &dst); + if (ret < 0) { + fprintf(stderr, "Error during second get_status\n"); + exit(1); + } + if (dst.bStatus != DFU_STATUS_OK) { + fprintf(stderr, "Error: Command not correctly executed\n"); + exit(1); + } + usleep(dst.bwPollTimeout * 1000); + + ret = dfu_abort(dif->dev_handle, dif->interface); + if (ret < 0) { + fprintf(stderr, "Error sending dfu abort request\n"); + exit(1); + } + ret = dfu_get_status(dif->dev_handle, dif->interface, &dst); + if (ret < 0) { + fprintf(stderr, "Error during abort get_status\n"); + exit(1); + } + if (dst.bState != DFU_STATE_dfuIDLE) { + fprintf(stderr, "Error: Failed to enter idle state on abort\n"); + exit(1); + } + usleep(dst.bwPollTimeout * 1000); + return ret; +} + +int dfuse_do_upload(struct dfu_if *dif, int xfer_size, struct dfu_file file, + unsigned int dfuse_address) +{ + int total_bytes = 0; + int upload_limit = 0; + unsigned char *buf; + int transaction; + int ret; + + buf = malloc(xfer_size); + if (!buf) + return -ENOMEM; + + if (dfuse_address) { + struct memsegment *segment; + + mem_layout = parse_memory_layout((char *)dif->alt_name); + if (!mem_layout) { + fprintf(stderr, + "Error: Failed to parse memory layout\n"); + exit(1); + } + segment = find_segment(mem_layout, dfuse_address); + if (!segment || !(segment->memtype & DFUSE_READABLE)) { + fprintf(stderr, + "Error: Page at 0x%08x is not readable\n", + dfuse_address); + exit(1); + } + upload_limit = segment->end - dfuse_address + 1; + printf("Limiting upload to end of memory segment, %i bytes\n", + upload_limit); + dfuse_special_command(dif, dfuse_address, SET_ADDRESS); + } else { + upload_limit = 0x4000; /* Should be safe for most devices */ + printf("Limiting default upload to %i bytes\n", upload_limit); + } + + printf("bytes_per_hash=%u\n", xfer_size); + printf("Starting upload: ["); + fflush(stdout); + + transaction = 2; + while (1) { + int rc, write_rc; + rc = dfuse_upload(dif, xfer_size, buf, transaction++); + if (rc < 0) { + ret = rc; + goto out_free; + } + write_rc = write(file.fd, buf, rc); + if (write_rc < rc) { + fprintf(stderr, "Short file write: %s\n", + strerror(errno)); + ret = -1; + goto out_free; + } + total_bytes += rc; + if (rc < xfer_size || total_bytes >= upload_limit) { + /* last block, return successfully */ + ret = total_bytes; + break; + } + putchar('#'); + fflush(stdout); + } + + printf("] finished!\n"); + fflush(stdout); + + out_free: + free(buf); + + return ret; +} + +int dfuse_dnload_chunk(struct dfu_if *dif, unsigned char *data, int size, + int transaction) +{ + int bytes_sent; + struct dfu_status dst; + int ret; + + ret = dfuse_download(dif, size, size ? data : NULL, transaction); + if (ret < 0) { + fprintf(stderr, "Error during download\n"); + return ret; + } + bytes_sent = ret; + + do { + ret = dfu_get_status(dif->dev_handle, dif->interface, &dst); + if (ret < 0) { + fprintf(stderr, "Error during download get_status\n"); + return ret; + } + usleep(dst.bwPollTimeout * 1000); + } while (dst.bState != DFU_STATE_dfuDNLOAD_IDLE && + dst.bState != DFU_STATE_dfuERROR); + + if (dst.bStatus != DFU_STATUS_OK) { + printf(" failed!\n"); + printf("state(%u) = %s, status(%u) = %s\n", dst.bState, + dfu_state_to_string(dst.bState), dst.bStatus, + dfu_status_to_string(dst.bStatus)); + return -1; + } + return bytes_sent; +} + +/* Writes an element of any size to the device, taking care of page erases */ +/* returns 0 on success, otherwise -EINVAL */ +int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddress, + unsigned int dwElementSize, unsigned char *data, + int xfer_size) +{ + int p; + int ret; + struct memsegment *segment; + + /* Check at least that we can write to the last address */ + segment = + find_segment(mem_layout, dwElementAddress + dwElementSize - 1); + if (!segment || !(segment->memtype & DFUSE_WRITEABLE)) { + fprintf(stderr, "Error: Last page at 0x%08x is not writeable\n", + dwElementAddress + dwElementSize - 1); + exit(1); + } + + for (p = 0; p < dwElementSize; p += xfer_size) { + int page_size; + unsigned int erase_address; + unsigned int address = dwElementAddress + p; + int chunk_size = xfer_size; + + segment = find_segment(mem_layout, address); + if (!segment || !(segment->memtype & DFUSE_WRITEABLE)) { + fprintf(stderr, + "Error: Page at 0x%08x is not writeable\n", + address); + exit(1); + } + page_size = segment->pagesize; + + /* check if this is the last chunk */ + if (p + chunk_size > dwElementSize) + chunk_size = dwElementSize - p; + + /* Erase only for flash memory downloads */ + if (segment->memtype & DFUSE_ERASABLE) { + /* erase all involved pages */ + for (erase_address = address; + erase_address < address + chunk_size; + erase_address += page_size) + if ((erase_address & ~(page_size - 1)) != + (last_erased & ~(page_size - 1))) + dfuse_special_command(dif, + erase_address, + ERASE_PAGE); + + if (((address + chunk_size - 1) & ~(page_size - 1)) != + (last_erased & ~(page_size - 1))) { + if (verbose > 2) + printf(" Chunk wraps over to next page" + "\n"); + dfuse_special_command(dif, + address + chunk_size - 1, + ERASE_PAGE); + } + } + + if (verbose) + printf(" Download from image offset " + "%08x to memory %08x-%08x, size %i\n", + p, address, address + chunk_size - 1, + chunk_size); + dfuse_special_command(dif, address, SET_ADDRESS); + + /* transaction = 2 for no address offset */ + ret = dfuse_dnload_chunk(dif, data + p, chunk_size, 2); + if (ret != chunk_size) { + fprintf(stderr, "Failed to write whole chunk: " + "%i of %i bytes\n", ret, chunk_size); + return -EINVAL; + } + } + return 0; +} + +/* Download raw binary file to DfuSe device */ +int dfuse_do_bin_dnload(struct dfu_if *dif, int xfer_size, + struct dfu_file file, unsigned int start_address) +{ + unsigned int dwElementAddress; + unsigned int dwElementSize; + unsigned char *data; + int read_bytes = 0; + int ret; + + dwElementAddress = start_address; + dwElementSize = file.size; + if (verbose) + printf("Uploading to address = 0x%08x, size = %i\n", + dwElementAddress, dwElementSize); + + data = malloc(dwElementSize); + if (!data) { + fprintf(stderr, "Could not allocate data buffer\n"); + return -ENOMEM; + } + ret = read(file.fd, data, dwElementSize); + read_bytes += ret; + if (ret < dwElementSize) { + fprintf(stderr, "Could not read data\n"); + ret = -EINVAL; + goto out_free; + } + + ret = dfuse_dnload_element(dif, dwElementAddress, dwElementSize, data, + xfer_size); + if (ret != 0) + goto out_free; + + if (read_bytes != file.size) { + fprintf(stderr, "Warning: Read %i bytes, file size %i\n", + read_bytes, (int)file.size); + } + ret = read_bytes; + + out_free: + free(data); + return ret; +} + +/* Parse a DfuSe file and download contents to device */ +int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size, + struct dfu_file file) +{ + char dfuprefix[11]; + char targetprefix[274]; + char elementheader[8]; + int image; + int element; + int bTargets; + int bAlternateSetting; + int dwNbElements; + unsigned int dwElementAddress; + unsigned int dwElementSize; + unsigned char *data; + int read_bytes = 0; + int ret; + + /* Must be larger than a minimal DfuSe header and suffix */ + if (file.size <= sizeof(dfuprefix) + file.suffixlen + + sizeof(targetprefix) + sizeof(elementheader)) { + fprintf(stderr, "File too small for a DfuSe file\n"); + return -EINVAL; + } + + ret = read(file.fd, dfuprefix, sizeof(dfuprefix)); + if (ret < (int)sizeof(dfuprefix)) { + fprintf(stderr, "Could not read DfuSe header\n"); + return -EIO; + } + read_bytes = ret; + if (strncmp(dfuprefix, "DfuSe", 5)) { + fprintf(stderr, "No valid DfuSe signature\n"); + return -EINVAL; + } + if (dfuprefix[5] != 0x01) { + fprintf(stderr, "DFU format revision %i not supported\n", + dfuprefix[5]); + return -EINVAL; + } + bTargets = dfuprefix[10]; + printf("file contains %i DFU images\n", bTargets); + + for (image = 1; image <= bTargets; image++) { + printf("parsing DFU image %i\n", image); + ret = read(file.fd, targetprefix, sizeof(targetprefix)); + read_bytes += ret; + if (ret < sizeof(targetprefix)) { + fprintf(stderr, "Could not read DFU header\n"); + return -EIO; + } + if (strncmp(targetprefix, "Target", 6)) { + fprintf(stderr, "No valid target signature\n"); + return -EINVAL; + } + bAlternateSetting = targetprefix[6]; + dwNbElements = quad2uint((unsigned char *)targetprefix + 270); + printf("image for alternate setting %i, ", bAlternateSetting); + printf("(%i elements, ", dwNbElements); + printf("total size = %i)\n", + quad2uint((unsigned char *)targetprefix + 266)); + if (bAlternateSetting != dif->altsetting) + printf("Warning: Image does not match current alternate" + " setting.\n" + "Please rerun with the correct -a option setting" + " to download this image!\n"); + for (element = 1; element <= dwNbElements; element++) { + printf("parsing element %i, ", element); + ret = + read(file.fd, elementheader, sizeof(elementheader)); + read_bytes += ret; + if (ret < sizeof(elementheader)) { + fprintf(stderr, + "Could not read element header\n"); + return -EINVAL; + } + dwElementAddress = + quad2uint((unsigned char *)elementheader); + dwElementSize = + quad2uint((unsigned char *)elementheader + 4); + printf("address = 0x%08x, ", dwElementAddress); + printf("size = %i\n", dwElementSize); + + /* sanity check */ + if (read_bytes + dwElementSize + file.suffixlen > + file.size) { + fprintf(stderr, + "File too small for element size\n"); + return -EINVAL; + } + data = malloc(dwElementSize); + if (!data) { + fprintf(stderr, + "Could not allocate data buffer\n"); + return -ENOMEM; + } + ret = read(file.fd, data, dwElementSize); + read_bytes += ret; + if (ret < dwElementSize) { + fprintf(stderr, "Could not read data\n"); + free(data); + return -EIO; + } + + if (bAlternateSetting == dif->altsetting) + ret = + dfuse_dnload_element(dif, dwElementAddress, + dwElementSize, data, + xfer_size); + else + ret = 0; + free(data); + if (ret != 0) + return ret; + } + } + + /* Just for book-keeping, read through the whole file */ + data = malloc(file.suffixlen); + if (!data) { + fprintf(stderr, "Could not allocate data buffer for suffix\n"); + return -ENOMEM; + } + ret = read(file.fd, data, file.suffixlen); + free(data); + if (ret < file.suffixlen) { + fprintf(stderr, "Could not read through suffix\n"); + return -EIO; + } + read_bytes += ret; + + if (read_bytes != file.size) { + fprintf(stderr, "Warning: Read %i bytes, file size %i\n", + read_bytes, (int)file.size); + } + + printf("done parsing DfuSe file\n"); + return read_bytes; +} + +int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file file, + unsigned int address) +{ + mem_layout = parse_memory_layout((char *)dif->alt_name); + if (!mem_layout) { + fprintf(stderr, "Error: Failed to parse memory layout\n"); + exit(1); + } + if (address) { + if (file.bcdDFU == 0x11a) { + fprintf(stderr, "Error: This is a DfuSe file, not " + "meant for raw download\n"); + return -EINVAL; + } + return dfuse_do_bin_dnload(dif, xfer_size, file, address); + } else { + if (file.bcdDFU != 0x11a) { + fprintf(stderr, "Error: Only DfuSe file version 1.1a " + "is supported\n"); + return -EINVAL; + } + return dfuse_do_dfuse_dnload(dif, xfer_size, file); + } + free_segment_list(mem_layout); +} diff -Nru dfu-util-0.4/src/dfuse.h dfu-util-0.5/src/dfuse.h --- dfu-util-0.4/src/dfuse.h 1970-01-01 00:00:00.000000000 +0000 +++ dfu-util-0.5/src/dfuse.h 2011-10-31 09:00:32.000000000 +0000 @@ -0,0 +1,35 @@ +/* This implements the ST Microsystems DFU extensions (DfuSe) + * as per the DfuSe 1.1a specification (Document UM0391) + * + * (C) 2010-2011 Tormod Volden + * + * 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 + */ + +#ifndef _DFUSE_H +#define _DFUSE_H + +#include + +enum dfuse_command { SET_ADDRESS, ERASE_PAGE, MASS_ERASE }; + +int dfuse_special_command(struct dfu_if *dif, unsigned int address, + enum dfuse_command command); +int dfuse_do_upload(struct dfu_if *dif, int xfer_size, struct dfu_file file, + unsigned int address); +int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file file, + unsigned int address); + +#endif diff -Nru dfu-util-0.4/src/dfuse_mem.c dfu-util-0.5/src/dfuse_mem.c --- dfu-util-0.4/src/dfuse_mem.c 1970-01-01 00:00:00.000000000 +0000 +++ dfu-util-0.5/src/dfuse_mem.c 2011-10-31 09:00:32.000000000 +0000 @@ -0,0 +1,207 @@ +/* Helper functions for reading the memory map in a device + * following the ST DfuSe 1.1a specification. + * + * (C) 2011 Tormod Volden + * + * 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 +#include +#include +#include + +#include "dfuse_mem.h" + +extern int verbose; + +int add_segment(struct memsegment **segment_list, struct memsegment segment) +{ + struct memsegment *new_element; + + new_element = malloc(sizeof(struct memsegment)); + if (!new_element) + return -ENOMEM; + *new_element = segment; + new_element->next = NULL; + + if (*segment_list == NULL) + /* list can be empty on first call */ + *segment_list = new_element; + else { + struct memsegment *next_element; + + /* find last element in list */ + next_element = *segment_list; + while (next_element->next != NULL) + next_element = next_element->next; + next_element->next = new_element; + } + return 0; +} + +struct memsegment *find_segment(struct memsegment *segment_list, + unsigned int address) +{ + while (segment_list != NULL) { + if (segment_list->start <= address && + segment_list->end >= address) + return segment_list; + segment_list = segment_list->next; + } + return NULL; +} + +void free_segment_list(struct memsegment *segment_list) +{ + struct memsegment *next_element; + + while (segment_list->next != NULL) { + next_element = segment_list->next; + free(segment_list); + segment_list = next_element; + } + free(segment_list); +} + +struct memsegment *parse_memory_layout(char *intf_desc) +{ + + char multiplier, memtype; + unsigned int address; + int sectors, size; + char *name, *typestring; + int ret; + int count = 0; + char separator; + int scanned; + struct memsegment *segment_list = NULL; + struct memsegment segment; + +#ifdef DEBUG_DRY + intf_desc = "@fake /0x08000000/12*001Ka,11*001Kg,9*2Ka,24*4Kg"; +#endif + name = malloc(strlen(intf_desc)); + if (!name) { + fprintf(stderr, "Error: Cannot allocate memory\n"); + exit(1); + } + ret = sscanf(intf_desc, "@%[^/]%n", name, &scanned); + if (ret < 1) { + fprintf(stderr, "Error: Could not read name, sscanf returned" + "%d\n", ret); + free(name); + return NULL; + } + printf("DfuSe interface name: \"%s\"\n", name); + free(name); + + intf_desc += scanned; + typestring = malloc(strlen(intf_desc)); + if (!typestring) { + fprintf(stderr, "Error: Cannot allocate memory\n"); + exit(1); + } + while (ret = sscanf(intf_desc, "/0x%x/%n", &address, &scanned), + ret > 0) { + + intf_desc += scanned; + while (ret = sscanf(intf_desc, "%d*%d%c%[^,/]%n", + §ors, &size, &multiplier, typestring, + &scanned), ret > 2) { + intf_desc += scanned; + + count++; + memtype = 0; + if (ret == 4) { + if (strlen(typestring) == 1 + && typestring[0] != '/') + memtype = typestring[0]; + else { + fprintf(stderr, + "Parsing type identifier '%s' " + "failed for segment %i\n", + typestring, count); + continue; + } + } + + switch (multiplier) { + case 'B': + break; + case 'K': + size *= 1024; + break; + case 'M': + size *= 1024 * 1024; + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + if (!memtype) { + fprintf(stderr, + "Non-valid multiplier '%c', " + "interpreted as type " + "identifier instead\n", + multiplier); + memtype = multiplier; + break; + } + /* fallthrough if memtype was already set */ + default: + fprintf(stderr, + "Non-valid multiplier '%c', " + "assuming bytes\n", multiplier); + } + + if (!memtype) { + fprintf(stderr, + "No valid type for segment %d\n\n", + count); + continue; + } + + segment.start = address; + segment.end = address + sectors * size - 1; + segment.pagesize = size; + segment.memtype = memtype & 7; + add_segment(&segment_list, segment); + + if (verbose) + printf("Memory segment at 0x%08x %3d x %4d = " + "%5d (%s%s%s)\n", + address, sectors, size, sectors * size, + memtype & DFUSE_READABLE ? "r" : "", + memtype & DFUSE_ERASABLE ? "e" : "", + memtype & DFUSE_WRITEABLE ? "w" : ""); + + address += sectors * size; + + separator = *intf_desc; + if (separator == ',') + intf_desc += 1; + else + break; + } /* while per segment */ + + } /* while per address */ + free(typestring); + + return segment_list; +} diff -Nru dfu-util-0.4/src/dfuse_mem.h dfu-util-0.5/src/dfuse_mem.h --- dfu-util-0.4/src/dfuse_mem.h 1970-01-01 00:00:00.000000000 +0000 +++ dfu-util-0.5/src/dfuse_mem.h 2011-10-31 09:00:32.000000000 +0000 @@ -0,0 +1,44 @@ +/* Helper functions for reading the memory map in a device + * following the ST DfuSe 1.1a specification. + * + * (C) 2011 Tormod Volden + * + * 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 + */ + +#ifndef _DFUSE_MEM_H +#define _DFUSE_MEM_H + +#define DFUSE_READABLE 1 +#define DFUSE_ERASABLE 2 +#define DFUSE_WRITEABLE 4 + +struct memsegment { + unsigned int start; + unsigned int end; + int pagesize; + int memtype; + struct memsegment *next; +}; + +int add_segment(struct memsegment **list, struct memsegment new_element); + +struct memsegment *find_segment(struct memsegment *list, unsigned int address); + +void free_segment_list(struct memsegment *list); + +struct memsegment *parse_memory_layout(char *intf_desc_str); + +#endif diff -Nru dfu-util-0.4/src/main.c dfu-util-0.5/src/main.c --- dfu-util-0.4/src/main.c 2011-07-18 18:30:05.000000000 +0000 +++ dfu-util-0.5/src/main.c 2011-11-01 15:39:07.000000000 +0000 @@ -34,6 +34,7 @@ #include "usb_dfu.h" #include "dfu_file.h" #include "dfu_load.h" +#include "dfuse.h" #include "quirks.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -51,13 +52,12 @@ int debug; int verbose = 0; -/* define a portable function for reading a 16bit little-endian word */ -unsigned short get_int16_le(const void *p) -{ - const unsigned char *cp = p; +/* If we really have to guess (non-compliant devices) */ +#define DEFAULT_TRANSFER_SIZE 1024 - return ( cp[0] ) | ( ((unsigned short)cp[1]) << 8 ); -} +/* USB string descriptor should contain max 126 UTF-16 characters + * but 253 would even accomodate any UTF-8 encoding */ +#define MAX_DESC_STR_LEN 253 /* Find DFU interfaces in a given device. * Iterate through all DFU interfaces and their alternate settings @@ -185,47 +185,58 @@ return dif->count; } -#define MAX_STR_LEN 64 - -static int print_dfu_if(struct dfu_if *dfu_if, void *v) +/* Retrieves alternate interface name string. + * Returns string length, or negative on error */ +static int get_alt_name(struct dfu_if *dfu_if, unsigned char *name) { libusb_device *dev = dfu_if->dev; struct libusb_config_descriptor *cfg; - int if_name_str_idx; - unsigned char name[MAX_STR_LEN+1] = "UNDEFINED"; - - libusb_get_config_descriptor_by_value(dev, dfu_if->configuration, &cfg); + int alt_name_str_idx; + int ret; - if_name_str_idx = cfg->interface[dfu_if->interface] - .altsetting[dfu_if->altsetting].iInterface; - if (if_name_str_idx) { + ret = libusb_get_config_descriptor_by_value(dev, dfu_if->configuration, + &cfg); + if (ret) + return ret; + + alt_name_str_idx = cfg->interface[dfu_if->interface]. + altsetting[dfu_if->altsetting].iInterface; + ret = -1; + if (alt_name_str_idx) { if (!dfu_if->dev_handle) libusb_open(dfu_if->dev, &dfu_if->dev_handle); if (dfu_if->dev_handle) - libusb_get_string_descriptor_ascii(dfu_if->dev_handle, - if_name_str_idx, name, - MAX_STR_LEN); + ret = libusb_get_string_descriptor_ascii( + dfu_if->dev_handle, alt_name_str_idx, + name, MAX_DESC_STR_LEN); } + libusb_free_config_descriptor(cfg); + return ret; +} - printf("Found %s: [0x%04x:0x%04x] devnum=%u, cfg=%u, intf=%u, " +static int print_dfu_if(struct dfu_if *dfu_if, void *v) +{ + unsigned char name[MAX_DESC_STR_LEN+1] = "UNDEFINED"; + + get_alt_name(dfu_if, name); + + printf("Found %s: [%04x:%04x] devnum=%u, cfg=%u, intf=%u, " "alt=%u, name=\"%s\"\n", dfu_if->flags & DFU_IFF_DFU ? "DFU" : "Runtime", dfu_if->vendor, dfu_if->product, dfu_if->devnum, - dfu_if->configuration, dfu_if->interface, + dfu_if->configuration, dfu_if->interface, dfu_if->altsetting, name); - - libusb_free_config_descriptor(cfg); return 0; } /* Walk the device tree and print out DFU devices */ -static int list_dfu_interfaces(void) +static int list_dfu_interfaces(libusb_context *ctx) { libusb_device **list; libusb_device *dev; ssize_t num_devs, i; - num_devs = libusb_get_device_list(NULL, &list); + num_devs = libusb_get_device_list(ctx, &list); for (i = 0; i < num_devs; ++i) { dev = list[i]; @@ -238,25 +249,10 @@ static int alt_by_name(struct dfu_if *dfu_if, void *v) { - libusb_device *dev = dfu_if->dev; - struct libusb_config_descriptor *cfg; - int if_name_str_idx; - unsigned char name[MAX_STR_LEN+1] = "UNDEFINED"; - - libusb_get_config_descriptor_by_value(dev, dfu_if->configuration, &cfg); + unsigned char name[MAX_DESC_STR_LEN+1]; - if_name_str_idx = cfg->interface[dfu_if->interface] - .altsetting[dfu_if->altsetting].iInterface; - if (!if_name_str_idx) + if (get_alt_name(dfu_if, name) < 0) return 0; - if (!dfu_if->dev_handle) - libusb_open(dfu_if->dev, &dfu_if->dev_handle); - if (!dfu_if->dev_handle) - return 0; - if (libusb_get_string_descriptor_ascii(dfu_if->dev_handle, - if_name_str_idx, name, - MAX_STR_LEN) < 0) - return 0; /* should we return an error here ? */ if (strcmp((char *)name, v)) return 0; /* @@ -287,35 +283,29 @@ /* Iterate over all matching DFU capable devices within system */ -static int iterate_dfu_devices(struct dfu_if *dif, +static int iterate_dfu_devices(libusb_context *ctx, struct dfu_if *dif, int (*action)(struct libusb_device *dev, void *user), void *user) { - struct libusb_device_descriptor desc; - struct libusb_device *dev; libusb_device **list; ssize_t num_devs, i; - dev = NULL; - num_devs = libusb_get_device_list(NULL, &list); // FIXME set context - - /* Walk the tree and find our device. */ + num_devs = libusb_get_device_list(ctx, &list); for (i = 0; i < num_devs; ++i) { - uint8_t bnum = libusb_get_bus_number(list[i]); - uint8_t dnum = libusb_get_device_address(list[i]); - int retval; - dev = list[i]; - libusb_get_device_descriptor(list[i], &desc); + struct libusb_device_descriptor desc; + struct libusb_device *dev = list[i]; + if (dif && (dif->flags & DFU_IFF_DEVNUM) && + (libusb_get_bus_number(dev) != dif->bus || + libusb_get_device_address(dev) != dif->devnum)) + continue; + libusb_get_device_descriptor(dev, &desc); if (dif && (dif->flags & DFU_IFF_VENDOR) && desc.idVendor != dif->vendor) continue; if (dif && (dif->flags & DFU_IFF_PRODUCT) && desc.idProduct != dif->product) continue; - if (dif && (dif->flags & DFU_IFF_DEVNUM) && - (bnum != dif->bus || dnum != dif->devnum)) - continue; if (!count_dfu_interfaces(dev)) continue; @@ -340,9 +330,9 @@ /* Find the first DFU-capable device, save it in dfu_if->dev */ -static int get_first_dfu_device(struct dfu_if *dif) +static int get_first_dfu_device(libusb_context *ctx, struct dfu_if *dif) { - return iterate_dfu_devices(dif, found_dfu_device, dif); + return iterate_dfu_devices(ctx, dif, found_dfu_device, dif); } @@ -356,11 +346,11 @@ /* Count DFU capable devices within system */ -static int count_dfu_devices(struct dfu_if *dif) +static int count_dfu_devices(libusb_context *ctx, struct dfu_if *dif) { int num_found = 0; - iterate_dfu_devices(dif, count_one_dfu_device, &num_found); + iterate_dfu_devices(ctx, dif, count_one_dfu_device, &num_found); return num_found; } @@ -408,58 +398,135 @@ #endif /* !HAVE_USBPATH_H */ -/* Look for descriptor in the configuration descriptor hierarchy */ -static int usb_get_extra_descriptor(struct dfu_if *dfu_if, unsigned char type, - unsigned char index, void *resbuf, int size) +/* Look for a descriptor in a concatenated descriptor list + * Will return desc_index'th match of given descriptor type + * Returns length of found descriptor, limited to res_size */ +static int find_descriptor(const unsigned char *desc_list, int list_len, + uint8_t desc_type, uint8_t desc_index, + uint8_t *res_buf, int res_size) { - unsigned char *cbuf; - int conflen; - int ret; int p = 0; - int foundlen = 0; + int hit = 0; + + while (p + 1 < list_len) { + int desclen; + + desclen = (int) desc_list[p]; + if (desclen == 0) { + fprintf(stderr, "Error: Invalid descriptor list\n"); + return -1; + } + if (desc_list[p + 1] == desc_type && hit++ == desc_index) { + if (desclen > res_size) + desclen = res_size; + if (p + desclen > list_len) + desclen = list_len - p; + memcpy(res_buf, &desc_list[p], desclen); + return desclen; + } + p += (int) desc_list[p]; + } + return 0; +} + +/* Look for a descriptor in the active configuration + * Will also find extra descriptors which are normally + * not returned by the standard libusb_get_descriptor() */ +static int usb_get_any_descriptor(struct libusb_device_handle *dev_handle, + uint8_t desc_type, + uint8_t desc_index, + unsigned char *resbuf, int res_len) +{ + struct libusb_device *dev = libusb_get_device(dev_handle); struct libusb_config_descriptor *config; + int ret; + uint16_t conflen; + unsigned char *cbuf; /* Get the total length of the configuration descriptors */ - ret = libusb_get_active_config_descriptor(dfu_if->dev, &config); - if (ret) { - fprintf(stderr, "Error: failed " - "libusb_get_active_config_descriptor()\n"); + ret = libusb_get_active_config_descriptor(dev, &config); + if (ret == LIBUSB_ERROR_NOT_FOUND) { + fprintf(stderr, "Error: Device is unconfigured\n"); return -1; + } else if (ret) { + fprintf(stderr, "Error: failed " + "libusb_get_active_config_descriptor()\n"); + exit(1); } conflen = config->wTotalLength; libusb_free_config_descriptor(config); - /* Suck in the whole configuration descriptor list */ + /* Suck in the configuration descriptor list from device */ cbuf = malloc(conflen); - ret = libusb_get_descriptor(dfu_if->dev_handle, LIBUSB_DT_CONFIG, - index, cbuf, conflen); + ret = libusb_get_descriptor(dev_handle, LIBUSB_DT_CONFIG, + desc_index, cbuf, conflen); if (ret < conflen) { fprintf(stderr, "Warning: failed to retrieve complete " - "configuration descriptor\n"); + "configuration descriptor, got %i/%i\n", + ret, conflen); conflen = ret; } + /* Search through the configuration descriptor list */ + ret = find_descriptor(cbuf, conflen, desc_type, desc_index, + resbuf, res_len); + free(cbuf); + + /* A descriptor must be at least 2 bytes long */ + if (ret > 1) { + if (verbose) + printf("Found descriptor in complete configuration " + "descriptor list\n"); + return ret; + } + + /* Finally try to retrieve it requesting the device directly + * This is not supported on all devices for non-standard types */ + return libusb_get_descriptor(dev_handle, desc_type, desc_index, + resbuf, res_len); +} + +/* Get cached extra descriptor from libusb for an interface + * Returns length of found descriptor */ +static int get_cached_extra_descriptor(struct libusb_device *dev, + uint8_t bConfValue, + uint8_t intf, + uint8_t desc_type, uint8_t desc_index, + unsigned char *resbuf, int res_len) +{ + struct libusb_config_descriptor *cfg; + const unsigned char *extra; + int extra_len; + int ret; + int alt; + + ret = libusb_get_config_descriptor_by_value(dev, bConfValue, &cfg); + if (ret == LIBUSB_ERROR_NOT_FOUND) { + fprintf(stderr, "Error: Device is unconfigured\n"); + return -1; + } else if (ret) { + fprintf(stderr, "Error: failed " + "libusb_config_descriptor_by_value()\n"); + exit(1); + } - /* Iterate through the descriptors */ - while (p + 1 < conflen) { - int desclen, smallest; - - desclen = (int) cbuf[p]; - if (cbuf[p + 1] == type) { - smallest = desclen < size ? desclen : size; - memcpy(resbuf, &cbuf[p], smallest); - foundlen = smallest; + /* Extra descriptors can be shared between alternate settings but + * libusb may attach them to one setting. Therefore go through all. + * Note that desc_index is per alternate setting, hits will not be + * counted from one to another */ + for (alt = 0; alt < cfg->interface[intf].num_altsetting; + alt++) { + extra = cfg->interface[intf].altsetting[alt].extra; + extra_len = cfg->interface[intf].altsetting[alt].extra_length; + if (extra_len > 1) + ret = find_descriptor(extra, extra_len, desc_type, + desc_index, resbuf, res_len); + if (ret > 1) break; - } - p += desclen; } - free(cbuf); - /* A descriptor is at least 2 bytes long */ - if (foundlen > 1) - return foundlen; - - /* try to retrieve it through usb_get_descriptor directly */ - return libusb_get_descriptor(dfu_if->dev_handle, type, index, resbuf, - size); + libusb_free_config_descriptor(cfg); + if (ret < 2 && verbose) + printf("Did not find cached descriptor\n"); + return ret; } static void help(void) @@ -479,12 +546,21 @@ " -U --upload file\t\tRead firmware from device into \n" " -D --download file\t\tWrite firmware from into device\n" " -R --reset\t\t\tIssue USB Reset signalling once we're finished\n" + " -s --dfuse-address address\tST DfuSe mode, specify target address for\n" + "\t\t\t\traw file download or upload. Not applicable for\n" + "\t\t\t\tDfuSe file (.dfu) downloads\n" ); } static void print_version(void) { - printf("dfu-util version %s\n", VERSION); + printf("dfu-util %s\n\n", VERSION); + printf("(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.\n" + "(C) 2010-2011 Tormod Volden (DfuSe support)\n" + "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n"); + + printf("dfu-util does currently only support DFU version 1.0\n\n"); + } static struct option opts[] = { @@ -504,10 +580,13 @@ { "upload", 1, 0, 'U' }, { "download", 1, 0, 'D' }, { "reset", 0, 0, 'R' }, + { "dfuse-address", 1, 0, 's' }, }; enum mode { MODE_NONE, + MODE_VERSION, + MODE_LIST, MODE_UPLOAD, MODE_DOWNLOAD, }; @@ -518,36 +597,28 @@ int num_devs; int num_ifs; unsigned int transfer_size = 0; - unsigned int default_transfer_size = 1024; unsigned int host_page_size; enum mode mode = MODE_NONE; struct dfu_status status; - struct usb_dfu_func_descriptor func_dfu; + struct usb_dfu_func_descriptor func_dfu = {0}, func_dfu_rt = {0}; libusb_context *ctx; struct dfu_file file; char *alt_name = NULL; /* query alt name if non-NULL */ + char *device_id_filter = NULL; + unsigned char active_alt_name[MAX_DESC_STR_LEN+1]; char *end; int final_reset = 0; int ret; - - printf("dfu-util - (C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.\n" - "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n"); - - printf("dfu-util does currently only support DFU version 1.0\n\n"); + int dfuse = 0; + unsigned int dfuse_address = 0; /* FIXME allow address to be zero? */ host_page_size = getpagesize(); memset(dif, 0, sizeof(*dif)); file.name = NULL; - ret = libusb_init(&ctx); - if (ret) { - fprintf(stderr, "unable to initialize libusb: %i\n", ret); - return EXIT_FAILURE; - } - while (1) { int c, option_index = 0; - c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:R", opts, + c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:Rs:", opts, &option_index); if (c == -1) break; @@ -558,27 +629,16 @@ exit(0); break; case 'V': - print_version(); - exit(0); + mode = MODE_VERSION; break; case 'v': - if (verbose) { - libusb_set_debug(ctx, 255); - } - verbose = 1; + verbose++; break; case 'l': - list_dfu_interfaces(); - exit(0); + mode = MODE_LIST; break; case 'd': - /* Parse device ID */ - parse_vendprod(&dif->vendor, &dif->product, optarg); - printf("Filter on vendor = 0x%04x product = 0x%04x\n", dif->vendor, dif->product); - if (dif->vendor) - dif->flags |= DFU_IFF_VENDOR; - if (dif->product) - dif->flags |= DFU_IFF_PRODUCT; + device_id_filter = optarg; break; case 'p': /* Parse device path */ @@ -626,27 +686,63 @@ case 'R': final_reset = 1; break; + case 's': + dfuse = 1; + if (strcmp(optarg, "default")) { + dfuse_address = strtoul(optarg, &end, 0); + if (!dfuse_address || (*end)) { + fprintf(stderr, "invalid dfuse address: %s\n", + optarg); + exit(2); + } + } + break; default: help(); exit(2); } } + print_version(); + if (mode == MODE_VERSION) { + exit(0); + } + if (mode == MODE_NONE) { - fprintf(stderr, "You need to specify one of -D or -U\n"); + fprintf(stderr, "Error: You need to specify one of -D or -U\n\n"); help(); exit(2); } - if (!file.name) { - fprintf(stderr, "You need to specify a filename to -D or -U\n"); - help(); - exit(2); + if (device_id_filter) { + /* Parse device ID */ + parse_vendprod(&dif->vendor, &dif->product, device_id_filter); + printf("Filter on vendor = 0x%04x product = 0x%04x\n", + dif->vendor, dif->product); + if (dif->vendor) + dif->flags |= DFU_IFF_VENDOR; + if (dif->product) + dif->flags |= DFU_IFF_PRODUCT; + } + + ret = libusb_init(&ctx); + if (ret) { + fprintf(stderr, "unable to initialize libusb: %i\n", ret); + return EXIT_FAILURE; + } + + if (verbose > 1) { + libusb_set_debug(ctx, 255); + } + + if (mode == MODE_LIST) { + list_dfu_interfaces(ctx); + exit(0); } dfu_init(5000); - num_devs = count_dfu_devices(dif); + num_devs = count_dfu_devices(ctx, dif); if (num_devs == 0) { fprintf(stderr, "No DFU capable USB device found\n"); exit(1); @@ -660,7 +756,7 @@ "device\n"); exit(3); } - if (!get_first_dfu_device(dif)) + if (!get_first_dfu_device(ctx, dif)) exit(3); /* We have exactly one device. Its libusb_device is now in dif->dev */ @@ -682,6 +778,27 @@ /* find set of quirks for this device */ set_quirks(_rt_dif.vendor, _rt_dif.product); + /* Obtain run-time DFU functional descriptor without asking device + * E.g. Freerunner does not like to be requested at this point */ + ret = get_cached_extra_descriptor(_rt_dif.dev, _rt_dif.configuration, + _rt_dif.interface, USB_DT_DFU, 0, + (unsigned char *) &func_dfu_rt, + sizeof(func_dfu_rt)); + if (ret == 7) { + /* DFU 1.0 does not have this field */ + printf("Deducing device DFU version from functional descriptor " + "length\n"); + func_dfu_rt.bcdDFUVersion = libusb_cpu_to_le16(0x0100); + } else if (ret < 9) { + fprintf(stderr, "WARNING: Can not find cached DFU functional " + "descriptor\n"); + printf("Warning: Assuming DFU version 1.0\n"); + func_dfu_rt.bcdDFUVersion = libusb_cpu_to_le16(0x0100); + } + printf("Run-time device DFU version %04x\n", + libusb_le16_to_cpu(func_dfu_rt.bcdDFUVersion)); + + /* Transition from run-Time mode to DFU mode */ if (!(_rt_dif.flags & DFU_IFF_DFU)) { /* In the 'first round' during runtime mode, there can only be one * DFU Interface descriptor according to the DFU Spec. */ @@ -723,10 +840,15 @@ } libusb_release_interface(_rt_dif.dev_handle, _rt_dif.interface); - printf("Resetting USB...\n"); - ret = libusb_reset_device(_rt_dif.dev_handle); - if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) - fprintf(stderr, "error resetting after detach\n"); + if (func_dfu_rt.bmAttributes & USB_DFU_WILL_DETACH) { + printf("Device will detach and reattach...\n"); + } else { + printf("Resetting USB...\n"); + ret = libusb_reset_device(_rt_dif.dev_handle); + if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) + fprintf(stderr, "error resetting " + "after detach\n"); + } sleep(2); break; case DFU_STATE_dfuERROR: @@ -767,7 +889,7 @@ } } - num_devs = count_dfu_devices(dif); + num_devs = count_dfu_devices(ctx, dif); if (num_devs == 0) { fprintf(stderr, "Lost device after RESET?\n"); exit(1); @@ -777,7 +899,7 @@ "then disconnect all but one device\n"); exit(1); } - if (!get_first_dfu_device(dif)) + if (!get_first_dfu_device(ctx, dif)) exit(3); printf("Opening USB Device...\n"); @@ -825,6 +947,10 @@ exit(1); } print_dfu_if(dif, NULL); + if (get_alt_name(dif, active_alt_name) > 0) + dif->alt_name = active_alt_name; + else + dif->alt_name = NULL; #if 0 printf("Setting Configuration %u...\n", dif->configuration); @@ -884,22 +1010,60 @@ break; } - if (!transfer_size) { - /* Obtain DFU functional descriptor */ - ret = usb_get_extra_descriptor(dif, USB_DT_DFU, - dif->interface, &func_dfu, sizeof(func_dfu)); - if (ret < 0) { - fprintf(stderr, "Error obtaining DFU functional " - "descriptor\n"); - } else { - transfer_size = get_int16_le(&func_dfu.wTransferSize); - printf("Device returned transfer size %i\n", - transfer_size); + if (DFU_STATUS_OK != status.bStatus ) { + printf("WARNING: DFU Status: '%s'\n", + dfu_status_to_string(status.bStatus)); + /* Clear our status & try again. */ + dfu_clear_status(dif->dev_handle, dif->interface); + dfu_get_status(dif->dev_handle, dif->interface, &status); + + if (DFU_STATUS_OK != status.bStatus) { + fprintf(stderr, "Error: %d\n", status.bStatus); + exit(1); } + if (!(quirks & QUIRK_POLLTIMEOUT)) + usleep(status.bwPollTimeout * 1000); } + + /* Get the DFU mode DFU functional descriptor + * If it is not found cached, we will request it from the device */ + ret = get_cached_extra_descriptor(dif->dev, dif->configuration, + dif->interface, USB_DT_DFU, 0, + (unsigned char *) &func_dfu, + sizeof(func_dfu)); + if (ret < 7) { + fprintf(stderr, "Error obtaining cached DFU functional " + "descriptor\n"); + ret = usb_get_any_descriptor(dif->dev_handle, + USB_DT_DFU, 0, + (unsigned char *) &func_dfu, + sizeof(func_dfu)); + } + if (ret == 7) { + printf("Deducing device DFU version from functional descriptor " + "length\n"); + func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); + } else if (ret < 9) { + printf("Error obtaining DFU functional descriptor\n"); + printf("Warning: Assuming DFU version 1.0\n"); + func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); + printf("Warning: Transfer size can not be detected\n"); + func_dfu.wTransferSize = 0; + } + printf("DFU mode device DFU version %04x\n", + libusb_le16_to_cpu(func_dfu.bcdDFUVersion)); + + if (func_dfu.bcdDFUVersion == 0x11a) + dfuse = 1; + + if (!transfer_size) { + transfer_size = libusb_le16_to_cpu(func_dfu.wTransferSize); + printf("Device returned transfer size %i\n", transfer_size); + } + /* if returned zero or not detected (and not user specified) */ if (!transfer_size) { - transfer_size = default_transfer_size; + transfer_size = DEFAULT_TRANSFER_SIZE; printf("Warning: Trying default transfer size %i\n", transfer_size); } @@ -916,21 +1080,6 @@ printf("Adjusted transfer size to %i\n", transfer_size); } - if (DFU_STATUS_OK != status.bStatus ) { - printf("WARNING: DFU Status: '%s'\n", - dfu_status_to_string(status.bStatus)); - /* Clear our status & try again. */ - dfu_clear_status(dif->dev_handle, dif->interface); - dfu_get_status(dif->dev_handle, dif->interface, &status); - - if (DFU_STATUS_OK != status.bStatus) { - fprintf(stderr, "Error: %d\n", status.bStatus); - exit(1); - } - if (!(quirks & QUIRK_POLLTIMEOUT)) - usleep(status.bwPollTimeout * 1000); - } - switch (mode) { case MODE_UPLOAD: file.fd = open(file.name, O_WRONLY|O_CREAT|O_EXCL, 0644); @@ -938,8 +1087,14 @@ perror(file.name); exit(1); } - if (dfuload_do_upload(dif, transfer_size, file) < 0) + if (dfuse) { + if (dfuse_do_upload(dif, transfer_size, file, + dfuse_address) < 0) + exit(1); + } else { + if (dfuload_do_upload(dif, transfer_size, file) < 0) exit(1); + } close(file.fd); break; case MODE_DOWNLOAD: @@ -953,7 +1108,7 @@ exit(1); if (ret == 0) { fprintf(stderr, "Warning: File has no DFU suffix\n"); - } else if (file.bcdDFU != 0x0100) { + } else if (file.bcdDFU != 0x0100 && file.bcdDFU != 0x11a) { fprintf(stderr, "Unsupported DFU file revision " "%04x\n", file.bcdDFU); exit(1); @@ -968,8 +1123,14 @@ fprintf(stderr, "Warning: File product ID %04x does " "not match device %04x\n", file.idProduct, dif->product); } - if (dfuload_do_dnload(dif, transfer_size, file) < 0) - exit(1); + if (dfuse || file.bcdDFU == 0x11a) { + if (dfuse_do_dnload(dif, transfer_size, file, + dfuse_address) < 0) + exit(1); + } else { + if (dfuload_do_dnload(dif, transfer_size, file) < 0) + exit(1); + } close(file.fd); break; default: @@ -989,6 +1150,7 @@ } libusb_close(dif->dev_handle); + libusb_exit(ctx); exit(0); } diff -Nru dfu-util-0.4/src/Makefile.am dfu-util-0.5/src/Makefile.am --- dfu-util-0.4/src/Makefile.am 2011-07-18 18:29:44.000000000 +0000 +++ dfu-util-0.5/src/Makefile.am 2011-10-31 09:00:32.000000000 +0000 @@ -4,6 +4,10 @@ dfu_util_SOURCES = main.c \ dfu_load.c \ dfu_load.h \ + dfuse.c \ + dfuse.h \ + dfuse_mem.c \ + dfuse_mem.h \ dfu.c \ dfu.h \ usb_dfu.h \ diff -Nru dfu-util-0.4/src/Makefile.in dfu-util-0.5/src/Makefile.in --- dfu-util-0.4/src/Makefile.in 2011-07-19 15:14:07.000000000 +0000 +++ dfu-util-0.5/src/Makefile.in 2011-11-01 15:43:28.000000000 +0000 @@ -45,7 +45,8 @@ CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) -am_dfu_util_OBJECTS = main.$(OBJEXT) dfu_load.$(OBJEXT) dfu.$(OBJEXT) \ +am_dfu_util_OBJECTS = main.$(OBJEXT) dfu_load.$(OBJEXT) \ + dfuse.$(OBJEXT) dfuse_mem.$(OBJEXT) dfu.$(OBJEXT) \ dfu_file.$(OBJEXT) quirks.$(OBJEXT) dfu_util_OBJECTS = $(am_dfu_util_OBJECTS) dfu_util_LDADD = $(LDADD) @@ -171,6 +172,10 @@ dfu_util_SOURCES = main.c \ dfu_load.c \ dfu_load.h \ + dfuse.c \ + dfuse.h \ + dfuse_mem.c \ + dfuse_mem.h \ dfu.c \ dfu.h \ usb_dfu.h \ @@ -263,6 +268,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfu_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfu_load.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfuse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfuse_mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quirks.Po@am__quote@