summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTormod Volden <debian.tormod@gmail.com>2022-02-17 22:43:52 +0100
committerTormod Volden <debian.tormod@gmail.com>2022-02-17 22:43:52 +0100
commit624320002eaaa1e16d0037552a9af3faadff847f (patch)
tree05480c414ddabd8b333cb6ec5b8d69068c796007
parent1c0e195328fa75f5ac2a1a261d78cd89eefb591e (diff)
parent138bbe40145da5a527fa98f2f7aed3187fd91b1d (diff)
Update upstream source from tag 'upstream/0.11'
Update to upstream version '0.11' with Debian dir caf4f3420abd8fb11101ecf6542bb6360112994c
-rw-r--r--AUTHORS15
-rw-r--r--ChangeLog58
-rw-r--r--DEVICES.txt10
-rw-r--r--INSTALL4
-rw-r--r--Makefile.am10
-rw-r--r--Makefile.in77
-rw-r--r--README12
-rw-r--r--TODO1
-rw-r--r--aclocal.m4432
-rw-r--r--config.h.in14
-rwxr-xr-xconfigure442
-rw-r--r--configure.ac7
-rwxr-xr-xdfuse-pack.py219
-rw-r--r--doc/40-dfuse.rules4
-rw-r--r--doc/60-dfuse.rules13
-rw-r--r--doc/Makefile.am9
-rw-r--r--doc/Makefile.in64
-rw-r--r--doc/SPEC-differences.txt21
-rw-r--r--doc/dfu-prefix.184
-rw-r--r--doc/dfu-prefix.1.md64
-rw-r--r--doc/dfu-suffix.191
-rw-r--r--doc/dfu-suffix.1.md72
-rw-r--r--doc/dfu-util.151
-rwxr-xr-xm4/compile13
-rwxr-xr-xm4/depcomp461
-rwxr-xr-xm4/install-sh405
-rwxr-xr-xm4/missing420
-rw-r--r--src/Makefile.in90
-rw-r--r--src/dfu.c5
-rw-r--r--src/dfu.h3
-rw-r--r--src/dfu_file.c75
-rw-r--r--src/dfu_file.h2
-rw-r--r--src/dfu_load.c84
-rw-r--r--src/dfu_util.c147
-rw-r--r--src/dfu_util.h5
-rw-r--r--src/dfuse.c338
-rw-r--r--src/dfuse.h3
-rw-r--r--src/dfuse_mem.c7
-rw-r--r--src/main.c314
-rw-r--r--src/portable.h24
-rw-r--r--src/prefix.c25
-rwxr-xr-xsrc/quirks.c75
-rwxr-xr-xsrc/quirks.h33
-rw-r--r--src/suffix.c19
-rw-r--r--src/usb_dfu.h6
45 files changed, 2913 insertions, 1415 deletions
diff --git a/AUTHORS b/AUTHORS
index 09894dd..df0d377 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,6 +9,7 @@ Daniel Willmann
Mike Frysinger
Uwe Hermann
C. Scott Ananian
+Tormod Volden
Bernard Blackham
Holger Freyther
Marc Singer
@@ -32,3 +33,17 @@ Dirk Castelijns
Gordon McNab
Stefan Zehl
Timo Poikola
+Michael Everitt
+David G. Turner
+Geoffrey Hausheer
+Thilo Cestonaro
+Alex Mastro
+Colin Parker
+Xavier Domont
+Ievgenii Meshcheriakov
+Aleks Chakin
+Niels Skou Olsen
+Jörg Riechardt
+Thomas Hebb
+Jérôme Hamm
+Hendry Kaak
diff --git a/ChangeLog b/ChangeLog
index 99e690b..6a98b97 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+0.11:
+ o Fix suffix check regression on Windows with Large File Support
+ o Skip setting alternate interface when not needed
+ o Only clamp transfer size on Linux
+ o Quirk for GD32 leave request
+ o Improve status and error messages and exit codes
+ o dfuse: Process all alternate interfaces in a DfuSe file
+ o dfuse-pack.py: Fix alternate settings if first is 0
+
+ 2021-09-05 Tormod Volden <debian.tormod@gmail.com>
+
+0.10:
+ o New --wait option for devices to appear (Jörg Riechardt)
+ o New --devnum option to filter devices (Harald Welte)
+ o Support DFU_STATE_dfuMANIFEST_WAIT_RST (Jérôme Hamm)
+ o Support large files (Tormod Volden)
+ o Quirks for Jabra devices (Niels Skou Olsen)
+ o Quirks for OpenPICC, SIMtrace (Harald Welte)
+ o Quirks for GD32VF103 (Thomas Hebb)
+ o Fix numeric argument parsing (Timo Poikola)
+ o Improve alternate interface index matching (Aleks Chakin)
+ o Improve libusb error messages (Alex Mastro)
+ o Improve Stellaris firmware detection (Aleks Chakin)
+ o Improve warnings and debug output (Tormod Volden)
+ o Update manual page (Thomas Hebb)
+ o Manual pages for dfu-suffix and dfu-prefix (Tormod Volden)
+ o Usage text describes DfuSe modifiers (Uwe Bonnes)
+ o dfuse: Erase all pages before programming (Geoffrey Hausheer)
+ o dfuse: New "will-reset" option (Ievgenii Meshcheriakov)
+ o dfuse: Allow 0 as start address (Xavier Domont)
+ o dfuse: Workaround for Black Magic Probe issue (Tormod Volden)
+ o dfuse: Workaround for STM32L4 page erase stalls (Tormod Volden)
+ o dfuse-pack.py: Set (multiple) alternate interfaces (Tormod Volden)
+ o dfuse-pack.py: S19 and ihex support (Thilo Cestonaro)
+ o dfuse-pack.py: Intel HEX multi-segment index fix (Colin Parker)
+ o dfuse-pack.py: Correct DFUImageSize (Hendry Kaak)
+ o dfuse-pack.py: Python 3 compatibility (Michael Everitt)
+
+ 2020-11-21 Tormod Volden <debian.tormod@gmail.com>
+
0.9:
o Reimplemented USBPATH support (Stefan Zehl)
o Better parsing of numeric arguments (Timo Poikola)
@@ -6,7 +46,7 @@
o Workaround for LPC DFU bootloader (Dirk Castelijns)
o Include example udev rules file (Tormod Volden)
-2016-02-08: Tormod Volden <debian.tormod@gmail.com>
+ 2016-02-08 Tormod Volden <debian.tormod@gmail.com>
0.8:
o New, separate dfu-prefix tool (Uwe Bonnes)
@@ -21,7 +61,7 @@
o dfuse-pack.py tool for .dfu files (Antonio Galeo)
o Many other fixes from many people
-2014-09-13: Tormod Volden <debian.tormod@gmail.com>
+ 2014-09-13 Tormod Volden <debian.tormod@gmail.com>
0.7:
o Support for TI Stellaris devices (Tommi Keisala)
@@ -32,7 +72,7 @@
o Arbitrary upload lengths
o "force" option for various possible (dangerous) overrides
-2012-10-07: Tormod Volden <debian.tormod@gmail.com>
+ 2012-10-07 Tormod Volden <debian.tormod@gmail.com>
0.6:
o Add detach mode (Stefan Schmidt)
@@ -53,7 +93,7 @@
an error about it. (Tormod Volden)
o Add quirk for Maple since it reports wrong DFU version (Tormod Volden)
-2012-04-22: Stefan Schmidt <stefan@datenfreihafen.org>
+ 2012-04-22 Stefan Schmidt <stefan@datenfreihafen.org>
0.5:
o DfuSe extension support for ST devices (Tormod Volden)
@@ -61,7 +101,7 @@
Volden)
o Internal cleanup and some manual page fixes (Tormod Volden)
-2011-11-02: Stefan Schmidt <stefan@datenfreihafen.org>
+ 2011-11-02 Stefan Schmidt <stefan@datenfreihafen.org>
0.4:
o Rework to use libusb-1.0 (Stefan Schmidt)
@@ -70,12 +110,12 @@
o More flexible -d vid:pid parsing (Tormod Volden)
o Many bug fixes and cleanups
-2011-07-20: Stefan Schmidt <stefan@datenfreihafen.org>
+ 2011-07-20 Stefan Schmidt <stefan@datenfreihafen.org>
0.3:
o quirks: Add OpenOCD to the poll timeout quirk table.
-2010-12-22: Stefan Schmidt <stefan@datenfreihafen.org>
+ 2010-12-22 Stefan Schmidt <stefan@datenfreihafen.org>
0.2:
o Fix some typos on the website and the README (Antonio Ospite, Uwe
@@ -95,9 +135,9 @@
o Print out in which direction we are transferring data
o Abort in upload if the file already exists
-2010-11-17 Stefan Schmidt <stefan@datenfreihafen.org>
+ 2010-11-17 Stefan Schmidt <stefan@datenfreihafen.org>
0.1:
Initial release
-2010-05-23 Stefan Schmidt <stefan@datenfreihafen.org>
+ 2010-05-23 Stefan Schmidt <stefan@datenfreihafen.org>
diff --git a/DEVICES.txt b/DEVICES.txt
index bdd9f1f..addbd2f 100644
--- a/DEVICES.txt
+++ b/DEVICES.txt
@@ -2,11 +2,11 @@ List of supported software and hardware products:
Software user (bootloader, etc)
-------------------------------
-- Sam7DFU: http://www.openpcd.org/Sam7dfu
-- U-boot: DFU patches
+- Sam7DFU: http://git.osmocom.org/openpcd/
+- U-boot: http://www.denx.de/wiki/U-Boot/
- Barebox: http://www.barebox.org/
-- Leaflabs: http://code.google.com/p/leaflabs/
-- Blackmagic DFU
+- Leaflabs: https://www.leaflabs.com/maple
+- Blackmagic: https://github.com/blacksphere/blackmagic/wiki
Products using DFU
------------------
@@ -15,6 +15,6 @@ Products using DFU
- Leaflabs Maple
- ATUSB from Qi Hardware
- STM32F105/7, STM32F2/F3/F4 in System Bootloader
-- Blackmagic debug probe
+- Black Magic Probe debugger
- NXP LPC31xx/LPC43XX, e.g. LPC-Link and LPC-Link2, need binaries
with LPC prefix and encoding (LPC-Link)
diff --git a/INSTALL b/INSTALL
index 88f6246..195f314 100644
--- a/INSTALL
+++ b/INSTALL
@@ -17,3 +17,7 @@
make install
+ If installing to a system directory use
+
+ sudo make install
+
diff --git a/Makefile.am b/Makefile.am
index 641dda5..27ec432 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,13 @@
SUBDIRS = src doc
EXTRA_DIST = autogen.sh TODO DEVICES.txt dfuse-pack.py
+
+wwwman: www/dfu-util.1.html www/dfu-suffix.1.html www/dfu-prefix.1.html
+
+www/%.1.html : doc/%.1
+ pandoc -f man -t html -s -o $@ $^
+
+pdfman: dfu-util.1.man.pdf dfu-prefix.1.man.pdf dfu-suffix.1.man.pdf
+
+%.1.man.pdf: doc/%.1
+ man -Tpdf $^ > $@
diff --git a/Makefile.in b/Makefile.in
index d1ebfca..287cff7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -76,16 +86,12 @@ NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = .
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/configure $(am__configure_deps) \
- $(srcdir)/config.h.in AUTHORS COPYING ChangeLog INSTALL README \
- TODO m4/compile m4/depcomp m4/install-sh m4/missing \
- $(top_srcdir)/m4/compile $(top_srcdir)/m4/install-sh \
- $(top_srcdir)/m4/missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
@@ -126,7 +132,7 @@ am__recursive_targets = \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
- cscope distdir dist dist-all distcheck
+ cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)config.h.in
# Read a list of newline-separated strings from the standard input,
@@ -149,6 +155,10 @@ ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/m4/compile $(top_srcdir)/m4/install-sh \
+ $(top_srcdir)/m4/missing AUTHORS COPYING ChangeLog INSTALL \
+ README TODO m4/compile m4/install-sh m4/missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -275,6 +285,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@@ -304,15 +315,14 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -445,7 +455,10 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -510,7 +523,7 @@ distdir: $(DISTFILES)
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
@@ -526,17 +539,17 @@ dist-xz: distdir
$(am__post_remove_distdir)
dist-tarZ: distdir
- @echo WARNING: "Support for shar distribution archives is" \
- "deprecated." >&2
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
- @echo WARNING: "Support for distribution archives compressed with" \
- "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
@@ -554,7 +567,7 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
@@ -564,23 +577,23 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
- mkdir $(distdir)/_build $(distdir)/_inst
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build \
- && ../configure \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
- --srcdir=.. --prefix="$$dc_install_base" \
+ --srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -755,6 +768,18 @@ uninstall-am:
mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am
+.PRECIOUS: Makefile
+
+
+wwwman: www/dfu-util.1.html www/dfu-suffix.1.html www/dfu-prefix.1.html
+
+www/%.1.html : doc/%.1
+ pandoc -f man -t html -s -o $@ $^
+
+pdfman: dfu-util.1.man.pdf dfu-prefix.1.man.pdf dfu-suffix.1.man.pdf
+
+%.1.man.pdf: doc/%.1
+ man -Tpdf $^ > $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/README b/README
index 89f051a..9061c8d 100644
--- a/README
+++ b/README
@@ -1,21 +1,21 @@
Dfu-util - Device Firmware Upgrade Utilities
-Dfu-util is the host side implementation of the DFU 1.0 [1] and DFU 1.1 [2]
+Dfu-util is a host side implementation of the DFU 1.0 and DFU 1.1 [1]
specification of the USB forum.
DFU is intended to download and upload firmware to devices connected over
USB. It ranges from small devices like micro-controller boards up to mobile
-phones. With dfu-util you are able to download firmware to your device or
-upload firmware from it.
+phones and single-board computers. dfu-util is able to download firmware
+to devices as well as to upload firmware from them.
dfu-util has been tested with Openmoko Neo1973 and Freerunner and many
other devices.
-[1] DFU 1.0 spec: http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
-[2] DFU 1.1 spec: http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf
-
The official website is:
http://dfu-util.sourceforge.net
See the INSTALL file for build instructions.
+
+[1] DFU 1.1 specification:
+ https://www.usb.org/sites/default/files/DFU_1.1.pdf
diff --git a/TODO b/TODO
index 900c30c..477a79c 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,4 @@
DfuSe:
-- Do erase and write in two separate passes when downloading
- Skip "Set Address" command when downloading contiguous blocks
- Implement "Get Commands" command
diff --git a/aclocal.m4 b/aclocal.m4
index da47901..87a5999 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -20,32 +20,63 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
-# serial 1 (pkg-config-0.24)
-#
-# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
-#
-# 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.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# PKG_PROG_PKG_CONFIG([MIN-VERSION])
-# ----------------------------------
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29.1)
+dnl
+dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29.1])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
@@ -67,18 +98,19 @@ if test -n "$PKG_CONFIG"; then
PKG_CONFIG=""
fi
fi[]dnl
-])# PKG_PROG_PKG_CONFIG
+])dnl PKG_PROG_PKG_CONFIG
-# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-#
-# Check to see whether a particular set of modules exists. Similar
-# to PKG_CHECK_MODULES(), but does not set variables or print errors.
-#
-# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-# only at the first occurence in configure.ac, so if the first place
-# it's called might be skipped (such as if it is within an "if", you
-# have to call PKG_CHECK_EXISTS manually
-# --------------------------------------------------------------
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
@@ -88,8 +120,10 @@ m4_ifvaln([$3], [else
$3])dnl
fi])
-# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
-# ---------------------------------------------
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
@@ -101,10 +135,11 @@ m4_define([_PKG_CONFIG],
else
pkg_failed=untried
fi[]dnl
-])# _PKG_CONFIG
+])dnl _PKG_CONFIG
-# _PKG_SHORT_ERRORS_SUPPORTED
-# -----------------------------
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@@ -112,19 +147,17 @@ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
else
_pkg_short_errors_supported=no
fi[]dnl
-])# _PKG_SHORT_ERRORS_SUPPORTED
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
-# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
-# [ACTION-IF-NOT-FOUND])
-#
-#
-# Note that if there is a possibility the first call to
-# PKG_CHECK_MODULES might not happen, you should be sure to include an
-# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
-#
-#
-# --------------------------------------------------------------
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
@@ -178,9 +211,92 @@ else
AC_MSG_RESULT([yes])
$3
fi[]dnl
-])# PKG_CHECK_MODULES
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
+
+# Copyright (C) 2002-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -192,10 +308,10 @@ fi[]dnl
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.14'
+[am__api_version='1.16'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.14.1], [],
+m4_if([$1], [1.16.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -211,14 +327,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.14.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -263,15 +379,14 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -302,7 +417,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -493,13 +608,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@@ -507,49 +621,41 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
+ # TODO: see whether this extra hack can be removed once we start
+ # requiring Autoconf 2.70 or later.
+ AS_CASE([$CONFIG_FILES],
+ [*\'*], [eval set x "$CONFIG_FILES"],
+ [*], [set x $CONFIG_FILES])
shift
- for mf
+ # Used to flag and report bootstrapping failures.
+ am_rc=0
+ for am_mf
do
# Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named 'Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
+ am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile which includes
+ # dependency-tracking related rules and includes.
+ # Grep'ing the whole file directly is not great: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`AS_DIRNAME("$mf")`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running 'make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "$am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`AS_DIRNAME(["$file"])`
- AS_MKDIR_P([$dirpart/$fdir])
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
+ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+ || continue
+ am_dirpart=`AS_DIRNAME(["$am_mf"])`
+ am_filepart=`AS_BASENAME(["$am_mf"])`
+ AM_RUN_LOG([cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles]) || am_rc=$?
done
+ if test $am_rc -ne 0; then
+ AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+ for automatic dependency tracking. Try re-running configure with the
+ '--disable-dependency-tracking' option to at least be able to build
+ the package (albeit without support for automatic dependency tracking).])
+ fi
+ AS_UNSET([am_dirpart])
+ AS_UNSET([am_filepart])
+ AS_UNSET([am_mf])
+ AS_UNSET([am_rc])
+ rm -f conftest-deps.mk
}
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
@@ -558,18 +664,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
-# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each '.P' file that we will
-# need in order to bootstrap the dependency handling code.
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
+ [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -656,11 +761,11 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# For better backward compatibility. To be removed once Automake 1.9.x
# dies out for good. For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -724,7 +829,7 @@ END
Aborting the configuration process, to ensure you take notice of the issue.
You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -733,7 +838,11 @@ to "yes", and re-run configure.
END
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
fi
-fi])
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -762,7 +871,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -773,7 +882,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -783,7 +892,7 @@ if test x"${install_sh}" != xset; then
fi
AC_SUBST([install_sh])])
-# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+# Copyright (C) 2003-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -804,7 +913,7 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -812,49 +921,42 @@ AC_SUBST([am__leading_dot])])
# AM_MAKE_INCLUDE()
# -----------------
-# Check to see how make treats includes.
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
am__doit:
- @echo this is the am__doit target
+ @echo this is the am__doit target >confinc.out
.PHONY: am__doit
END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+ AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+ AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+ ['0:this is the am__doit target'],
+ [AS_CASE([$s],
+ [BSD], [am__include='.include' am__quote='"'],
+ [am__include='include' am__quote=''])])
+ if test "$am__include" != "#"; then
+ _am_result="yes ($s style)"
+ break
+ fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -893,7 +995,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -922,7 +1024,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -969,7 +1071,7 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -988,7 +1090,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1069,7 +1171,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
-# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+# Copyright (C) 2009-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1129,7 +1231,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1157,7 +1259,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1176,7 +1278,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+# Copyright (C) 2004-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
diff --git a/config.h.in b/config.h.in
index 905a0c3..62aa1d2 100644
--- a/config.h.in
+++ b/config.h.in
@@ -3,9 +3,6 @@
/* Define to 1 if you have the `err' function. */
#undef HAVE_ERR
-/* Define to 1 if you have the `getpagesize' function. */
-#undef HAVE_GETPAGESIZE
-
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@@ -72,6 +69,17 @@
/* Version number of package */
#undef VERSION
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
diff --git a/configure b/configure
index 8f54581..16c82ab 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for dfu-util 0.9.
+# Generated by GNU Autoconf 2.69 for dfu-util 0.11.
#
# Report bugs to <http://sourceforge.net/p/dfu-util/tickets/>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='dfu-util'
PACKAGE_TARNAME='dfu-util'
-PACKAGE_VERSION='0.9'
-PACKAGE_STRING='dfu-util 0.9'
+PACKAGE_VERSION='0.11'
+PACKAGE_STRING='dfu-util 0.11'
PACKAGE_BUGREPORT='http://sourceforge.net/p/dfu-util/tickets/'
PACKAGE_URL='http://dfu-util.sourceforge.net'
@@ -640,7 +640,6 @@ am__nodep
AMDEPBACKSLASH
AMDEP_FALSE
AMDEP_TRUE
-am__quote
am__include
DEPDIR
OBJEXT
@@ -696,6 +695,7 @@ infodir
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -714,12 +714,14 @@ PACKAGE_VERSION
PACKAGE_TARNAME
PACKAGE_NAME
PATH_SEPARATOR
-SHELL'
+SHELL
+am__quote'
ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_silent_rules
enable_dependency_tracking
+enable_largefile
'
ac_precious_vars='build_alias
host_alias
@@ -773,6 +775,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1025,6 +1028,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1162,7 +1174,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1275,7 +1287,7 @@ if test "$ac_init_help" = "long"; then
# 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.9 to adapt to many kinds of systems.
+\`configure' configures dfu-util 0.11 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1315,6 +1327,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1341,7 +1354,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of dfu-util 0.9:";;
+ short | recursive ) echo "Configuration of dfu-util 0.11:";;
esac
cat <<\_ACEOF
@@ -1355,6 +1368,7 @@ Optional Features:
do not reject slow dependency extractors
--disable-dependency-tracking
speeds up one-time build
+ --disable-largefile omit support for large files
Some influential environment variables:
CC C compiler command
@@ -1440,7 +1454,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-dfu-util configure 0.9
+dfu-util configure 0.11
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1863,7 +1877,7 @@ cat >config.log <<_ACEOF
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.9, which was
+It was created by dfu-util $as_me 0.11, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2240,7 +2254,7 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-am__api_version='1.14'
+am__api_version='1.16'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -2412,8 +2426,8 @@ test "$program_suffix" != NONE &&
ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
@@ -2432,7 +2446,7 @@ else
$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -2726,7 +2740,7 @@ fi
# Define the identity of the package.
PACKAGE='dfu-util'
- VERSION='0.9'
+ VERSION='0.11'
cat >>confdefs.h <<_ACEOF
@@ -2756,12 +2770,12 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# For better backward compatibility. To be removed once Automake 1.9.x
# dies out for good. For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
mkdir_p='$(MKDIR_P)'
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
@@ -2808,7 +2822,7 @@ END
Aborting the configuration process, to ensure you take notice of the issue.
You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -2818,6 +2832,7 @@ END
as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
fi
fi
+
ac_config_headers="$ac_config_headers config.h"
@@ -3714,45 +3729,45 @@ DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+cat > confinc.mk << 'END'
am__doit:
- @echo this is the am__doit target
+ @echo this is the am__doit target >confinc.out
.PHONY: am__doit
END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
am__include="#"
am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+ { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
+ (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ case $?:`cat confinc.out 2>/dev/null` in #(
+ '0:this is the am__doit target') :
+ case $s in #(
+ BSD) :
+ am__include='.include' am__quote='"' ;; #(
+ *) :
+ am__include='include' am__quote='' ;;
+esac ;; #(
+ *) :
;;
- esac
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
+esac
+ if test "$am__include" != "#"; then
+ _am_result="yes ($s style)"
+ break
+ fi
+done
+rm -f confinc.* confmf.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+$as_echo "${_am_result}" >&6; }
# Check whether --enable-dependency-tracking was given.
if test "${enable_dependency_tracking+set}" = set; then :
@@ -4721,7 +4736,7 @@ test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
esac
-for ac_func in getpagesize nanosleep err
+for ac_func in nanosleep err
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -4734,6 +4749,208 @@ fi
done
+# Checks how to do large files
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
+
+
+fi
+
+
ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile"
cat >confcache <<\_ACEOF
@@ -5266,7 +5483,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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.9, which was
+This file was extended by dfu-util $as_me 0.11, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -5333,7 +5550,7 @@ _ACEOF
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.9
+dfu-util config.status 0.11
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -5452,7 +5669,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
#
# INIT-COMMANDS
#
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
_ACEOF
@@ -6066,29 +6283,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
# Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
+ # TODO: see whether this extra hack can be removed once we start
+ # requiring Autoconf 2.70 or later.
+ case $CONFIG_FILES in #(
+ *\'*) :
+ eval set x "$CONFIG_FILES" ;; #(
+ *) :
+ set x $CONFIG_FILES ;; #(
+ *) :
+ ;;
+esac
shift
- for mf
+ # Used to flag and report bootstrapping failures.
+ am_rc=0
+ for am_mf
do
# Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named 'Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
+ am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile which includes
+ # dependency-tracking related rules and includes.
+ # Grep'ing the whole file directly is not great: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$mf" : 'X\(//\)[^/]' \| \
- X"$mf" : 'X\(//\)$' \| \
- X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$mf" |
+ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+ || continue
+ am_dirpart=`$as_dirname -- "$am_mf" ||
+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$am_mf" : 'X\(//\)[^/]' \| \
+ X"$am_mf" : 'X\(//\)$' \| \
+ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$am_mf" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
@@ -6106,53 +6329,48 @@ $as_echo X"$mf" |
q
}
s/.*/./; q'`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running 'make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "$am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$file" : 'X\(//\)[^/]' \| \
- X"$file" : 'X\(//\)$' \| \
- X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
+ am_filepart=`$as_basename -- "$am_mf" ||
+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$am_mf" : 'X\(//\)$' \| \
+ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$am_mf" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
}
- /^X\(\/\/\)$/{
+ /^X\/\(\/\/\)$/{
s//\1/
q
}
- /^X\(\/\).*/{
+ /^X\/\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
- as_dir=$dirpart/$fdir; as_fn_mkdir_p
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
+ { echo "$as_me:$LINENO: cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles" >&5
+ (cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } || am_rc=$?
done
+ if test $am_rc -ne 0; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Something went wrong bootstrapping makefile fragments
+ for automatic dependency tracking. Try re-running configure with the
+ '--disable-dependency-tracking' option to at least be able to build
+ the package (albeit without support for automatic dependency tracking).
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ { am_dirpart=; unset am_dirpart;}
+ { am_filepart=; unset am_filepart;}
+ { am_mf=; unset am_mf;}
+ { am_rc=; unset am_rc;}
+ rm -f conftest-deps.mk
}
;;
diff --git a/configure.ac b/configure.ac
index f5a43b8..1d99965 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
-AC_INIT([dfu-util],[0.9],[http://sourceforge.net/p/dfu-util/tickets/],,[http://dfu-util.sourceforge.net])
+AC_INIT([dfu-util],[0.11],[http://sourceforge.net/p/dfu-util/tickets/],,[http://dfu-util.sourceforge.net])
AC_CONFIG_AUX_DIR(m4)
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_HEADERS([config.h])
@@ -34,7 +34,10 @@ AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MEMCMP
-AC_CHECK_FUNCS([getpagesize nanosleep err])
+AC_CHECK_FUNCS([nanosleep err])
+
+# Checks how to do large files
+AC_SYS_LARGEFILE
AC_CONFIG_FILES(Makefile src/Makefile doc/Makefile)
AC_OUTPUT
diff --git a/dfuse-pack.py b/dfuse-pack.py
index 875cc5c..c0a5f0a 100755
--- a/dfuse-pack.py
+++ b/dfuse-pack.py
@@ -5,26 +5,37 @@
# see http://www.gnu.org/licenses/lgpl-3.0.txt
import sys,struct,zlib,os
+import binascii
from optparse import OptionParser
+try:
+ from intelhex import IntelHex
+except ImportError:
+ IntelHex = None
+
DEFAULT_DEVICE="0x0483:0xdf11"
+DEFAULT_NAME=b'ST...'
+
+# Prefix and Suffix sizes are derived from ST's DfuSe File Format Specification (UM0391), DFU revision 1.1a
+PREFIX_SIZE=11
+SUFFIX_SIZE=16
def named(tuple,names):
- return dict(zip(names.split(),tuple))
+ return dict(list(zip(names.split(),tuple)))
def consume(fmt,data,names):
n = struct.calcsize(fmt)
return named(struct.unpack(fmt,data[:n]),names),data[n:]
-def cstring(string):
- return string.split('\0',1)[0]
+def cstring(bytestring):
+ return bytestring.partition(b'\0')[0]
def compute_crc(data):
return 0xFFFFFFFF & -zlib.crc32(data) -1
def parse(file,dump_images=False):
- print 'File: "%s"' % file
+ print('File: "%s"' % file)
data = open(file,'rb').read()
crc = compute_crc(data[:-4])
prefix, data = consume('<5sBIB',data,'signature version size targets')
- print '%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix
+ print('%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix)
for t in range(prefix['targets']):
tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements')
tprefix['num'] = t
@@ -32,40 +43,53 @@ def parse(file,dump_images=False):
tprefix['name'] = cstring(tprefix['name'])
else:
tprefix['name'] = ''
- print '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix
+ print('%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix)
tsize = tprefix['size']
target, data = data[:tsize], data[tsize:]
for e in range(tprefix['elements']):
eprefix, target = consume('<2I',target,'address size')
eprefix['num'] = e
- print ' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix
+ print(' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix)
esize = eprefix['size']
image, target = target[:esize], target[esize:]
if dump_images:
out = '%s.target%d.image%d.bin' % (file,t,e)
open(out,'wb').write(image)
- print ' DUMPED IMAGE TO "%s"' % out
+ print(' DUMPED IMAGE TO "%s"' % out)
if len(target):
- print "target %d: PARSE ERROR" % t
- suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc')
- print 'usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix
+ print("target %d: PARSE ERROR" % t)
+ suffix = named(struct.unpack('<4H3sBI',data[:SUFFIX_SIZE]),'device product vendor dfu ufd len crc')
+ print('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix)
if crc != suffix['crc']:
- print "CRC ERROR: computed crc32 is 0x%08x" % crc
- data = data[16:]
+ print("CRC ERROR: computed crc32 is 0x%08x" % crc)
+ data = data[SUFFIX_SIZE:]
if data:
- print "PARSE ERROR"
+ print("PARSE ERROR")
+
+def checkbin(binfile):
+ data = open(binfile,'rb').read()
+ if (len(data) < SUFFIX_SIZE):
+ return
+ crc = compute_crc(data[:-4])
+ suffix = named(struct.unpack('<4H3sBI',data[-SUFFIX_SIZE:]),'device product vendor dfu ufd len crc')
+ if crc == suffix['crc'] and suffix['ufd'] == b'UFD':
+ print('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix)
+ print("It looks like the file %s has a DFU suffix!" % binfile)
+ print("Please remove any DFU suffix and retry.")
+ sys.exit(1)
-def build(file,targets,device=DEFAULT_DEVICE):
- data = ''
+def build(file,targets,name=DEFAULT_NAME,device=DEFAULT_DEVICE):
+ data = b''
for t,target in enumerate(targets):
- tdata = ''
+ tdata = b''
for image in target:
tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data']
- tdata = struct.pack('<6sBI255s2I','Target',0,1,'ST...',len(tdata),len(target)) + tdata
+ ealt = image['alt']
+ tdata = struct.pack('<6sBI255s2I',b'Target',ealt,1,name,len(tdata),len(target)) + tdata
data += tdata
- data = struct.pack('<5sBIB','DfuSe',1,len(data)+11,len(targets)) + data
- v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
- data += struct.pack('<4H3sB',0,d,v,0x011a,'UFD',16)
+ data = struct.pack('<5sBIB',b'DfuSe',1,PREFIX_SIZE + len(data) + SUFFIX_SIZE,len(targets)) + data
+ v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)]
+ data += struct.pack('<4H3sB',0,d,v,0x011a,b'UFD',SUFFIX_SIZE)
crc = compute_crc(data)
data += struct.pack('<I',crc)
open(file,'wb').write(data)
@@ -73,49 +97,160 @@ def build(file,targets,device=DEFAULT_DEVICE):
if __name__=="__main__":
usage = """
%prog [-d|--dump] infile.dfu
-%prog {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu"""
+%prog {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu
+%prog {-s|--build-s19} file.s19 [{-D|--device}=vendor:device] outfile.dfu
+%prog {-i|--build-ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu"""
parser = OptionParser(usage=usage)
parser.add_option("-b", "--build", action="append", dest="binfiles",
- help="build a DFU file from given BINFILES", metavar="BINFILES")
+ help="Include a raw binary file, to be loaded at the specified address. The BINFILES argument is of the form address:path-to-file. The address can have @X appended where X is the alternate interface number for this binary file. Note that the binary files must not have any DFU suffix!", metavar="BINFILES")
+ parser.add_option("-i", "--build-ihex", action="append", dest="hexfiles",
+ help="build a DFU file from given Intel HEX HEXFILES", metavar="HEXFILES")
+ parser.add_option("-s", "--build-s19", type="string", dest="s19files",
+ help="build a DFU file from given S19 S-record S19FILE", metavar="S19FILE")
parser.add_option("-D", "--device", action="store", dest="device",
help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE")
+ parser.add_option("-a", "--alt-intf", action="store", dest="alt",
+ help="build for alternate interface number ALTINTF, defaults to 0", metavar="ALTINTF")
parser.add_option("-d", "--dump", action="store_true", dest="dump_images",
default=False, help="dump contained images to current directory")
(options, args) = parser.parse_args()
- if options.binfiles and len(args)==1:
+ targets = []
+
+ if options.alt:
+ try:
+ default_alt = int(options.alt)
+ except ValueError:
+ print("Alternate interface option argument %s invalid." % options.alt)
+ sys.exit(1)
+ else:
+ default_alt = 0
+
+ if (options.binfiles or options.hexfiles) and len(args)==1:
target = []
- for arg in options.binfiles:
- try:
- address,binfile = arg.split(':',1)
- except ValueError:
- print "Address:file couple '%s' invalid." % arg
- sys.exit(1)
- try:
- address = int(address,0) & 0xFFFFFFFF
- except ValueError:
- print "Address %s invalid." % address
- sys.exit(1)
- if not os.path.isfile(binfile):
- print "Unreadable file '%s'." % binfile
+ old_ealt = None
+
+ if options.binfiles:
+ for arg in options.binfiles:
+ try:
+ address,binfile = arg.split(':',1)
+ except ValueError:
+ print("Address:file couple '%s' invalid." % arg)
+ sys.exit(1)
+ try:
+ address,alts = address.split('@',1)
+ if alts:
+ try:
+ ealt = int(alts)
+ except ValueError:
+ print("Alternate interface number %s invalid." % alts)
+ sys.exit(1)
+ else:
+ ealt = default_alt
+ except ValueError:
+ ealt = default_alt
+ try:
+ address = int(address,0) & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ if not os.path.isfile(binfile):
+ print("Unreadable file '%s'." % binfile)
+ sys.exit(1)
+ checkbin(binfile)
+ if old_ealt is not None and ealt != old_ealt:
+ targets.append(target)
+ target = []
+ target.append({ 'address': address, 'alt': ealt, 'data': open(binfile,'rb').read() })
+ old_ealt = ealt
+ targets.append(target)
+
+ if options.hexfiles:
+ if not IntelHex:
+ print("Error: IntelHex python module could not be found")
sys.exit(1)
- target.append({ 'address': address, 'data': open(binfile,'rb').read() })
+ for hexf in options.hexfiles:
+ ih = IntelHex(hexf)
+ for (address,end) in ih.segments():
+ try:
+ address = address & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ target.append({ 'address': address, 'alt': default_alt, 'data': ih.tobinstr(start=address, end=end-1)})
+ targets.append(target)
+
+ outfile = args[0]
+ device = DEFAULT_DEVICE
+ if options.device:
+ device=options.device
+ try:
+ v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)]
+ except:
+ print("Invalid device '%s'." % device)
+ sys.exit(1)
+ build(outfile,targets,DEFAULT_NAME,device)
+ elif options.s19files and len(args)==1:
+ address = 0
+ data = ""
+ target = []
+ name = DEFAULT_NAME
+ with open(options.s19files) as f:
+ lines = f.readlines()
+ for line in lines:
+ curaddress = 0
+ curdata = ""
+ line = line.rstrip()
+ if line.startswith ( "S0" ):
+ name = binascii.a2b_hex(line[8:len(line) - 2])
+ elif line.startswith ( "S3" ):
+ try:
+ curaddress = int(line[4:12], 16) & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ curdata = binascii.unhexlify(line[12:-2])
+ elif line.startswith ( "S2" ):
+ try:
+ curaddress = int(line[4:10], 16) & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ curdata = binascii.unhexlify(line[10:-2])
+ elif line.startswith ( "S1" ):
+ try:
+ curaddress = int(line[4:8], 16) & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ curdata = binascii.unhexlify(line[8:-2])
+ if address == 0:
+ address = curaddress
+ data = curdata
+ elif address + len(data) != curaddress:
+ target.append({ 'address': address, 'alt': default_alt, 'data': data })
+ address = curaddress
+ data = curdata
+ else:
+ data += curdata
outfile = args[0]
device = DEFAULT_DEVICE
if options.device:
device=options.device
try:
- v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
+ v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)]
except:
- print "Invalid device '%s'." % device
+ print("Invalid device '%s'." % device)
sys.exit(1)
- build(outfile,[target],device)
+ build(outfile,[target],name,device)
elif len(args)==1:
infile = args[0]
if not os.path.isfile(infile):
- print "Unreadable file '%s'." % infile
+ print("Unreadable file '%s'." % infile)
sys.exit(1)
parse(infile, dump_images=options.dump_images)
else:
parser.print_help()
+ if not IntelHex:
+ print("Note: Intel hex files support requires the IntelHex python module")
sys.exit(1)
diff --git a/doc/40-dfuse.rules b/doc/40-dfuse.rules
deleted file mode 100644
index 38e7233..0000000
--- a/doc/40-dfuse.rules
+++ /dev/null
@@ -1,4 +0,0 @@
-# Example udev rules (usually placed in /etc/udev/rules.d)
-# Makes STM32 DfuSe device writeable for the "plugdev" group
-
-ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE="664", GROUP="plugdev"
diff --git a/doc/60-dfuse.rules b/doc/60-dfuse.rules
new file mode 100644
index 0000000..47396b9
--- /dev/null
+++ b/doc/60-dfuse.rules
@@ -0,0 +1,13 @@
+# Example udev rules (usually placed in /etc/udev/rules.d)
+
+# STM32
+ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", TAG+="uaccess"
+
+# GD32VF103
+ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", TAG+="uaccess"
+
+# Spark Core
+ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="607f", TAG+="uaccess"
+
+# On older systems, a user group like "plugdev" can be given access:
+# ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE="664", GROUP="plugdev"
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 4e1127d..7dffb68 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,2 +1,7 @@
-man_MANS = dfu-util.1
-EXTRA_DIST = dfu-util.1 40-dfuse.rules
+man_MANS = dfu-util.1 dfu-suffix.1 dfu-prefix.1
+EXTRA_DIST = .
+dist-hook:
+ rm $(distdir)/Makefile
+
+%.1 : %.1.md
+ pandoc $< -s -t man > $@
diff --git a/doc/Makefile.in b/doc/Makefile.in
index afe47e5..30d39c6 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -76,11 +86,11 @@ NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = doc
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
@@ -136,6 +146,7 @@ am__installdirs = "$(DESTDIR)$(man1dir)"
NROFF = nroff
MANS = $(man_MANS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -221,6 +232,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@@ -229,8 +241,8 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-man_MANS = dfu-util.1
-EXTRA_DIST = dfu-util.1 40-dfuse.rules
+man_MANS = dfu-util.1 dfu-suffix.1 dfu-prefix.1
+EXTRA_DIST = .
all: all-am
.SUFFIXES:
@@ -246,14 +258,13 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign doc/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -314,7 +325,10 @@ ctags CTAGS:
cscope cscopelist:
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@@ -344,6 +358,9 @@ distdir: $(DISTFILES)
|| exit 1; \
fi; \
done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
check-am: all-am
check: check-am
all-am: Makefile $(MANS)
@@ -452,17 +469,24 @@ uninstall-man: uninstall-man1
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
- ctags-am distclean distclean-generic distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-man install-man1 install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
- pdf-am ps ps-am tags-am uninstall uninstall-am uninstall-man \
- uninstall-man1
+ ctags-am dist-hook distclean distclean-generic distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man1 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-man uninstall-man1
+
+.PRECIOUS: Makefile
+
+dist-hook:
+ rm $(distdir)/Makefile
+%.1 : %.1.md
+ pandoc $< -s -t man > $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/doc/SPEC-differences.txt b/doc/SPEC-differences.txt
new file mode 100644
index 0000000..3daa5c6
--- /dev/null
+++ b/doc/SPEC-differences.txt
@@ -0,0 +1,21 @@
+From 1.0 to 1.1:
+----------------
+(Page references in 1.1 spec)
+
+Page 10: Added protocol column to table 3.2
+Page 12: Changed value for bInterfaceProtocol from 00h to 01h (table 4.1)
+Page 13: Added bitWillDetach flag in bmAttributes at bit 3 (table 4.2)
+ Changed bLength from 07h to 09h (table 4.2)
+Page 14: Added bcdDFUVersion (table 4.2)
+ Changed bDeviceClass value from FEh to 00h (table 4.3)
+ Changed bDevicesubClass value from 01h to 00h (table 4.3)
+Page 15: Changed bInterfaceProtocol value from 00h to 02h (table 4.4)
+Page 17: Adjust wording for bitWillDetach addition (5.1)
+Page 26: Adjust wording for bitWillDetach addition (7)
+Page 29: Adjust wording for bitWillDetach addition (A.2.1)
+
+Summary:
+- Addition of the bitWillDetach flag which allows the device to detach instead
+ of waiting of the host to reset the device.
+- Version changes for bInterfaceProtocol, bDeviceClass and bDevicesubClass
+- Addition of bcdDFUVersion
diff --git a/doc/dfu-prefix.1 b/doc/dfu-prefix.1
new file mode 100644
index 0000000..a135dec
--- /dev/null
+++ b/doc/dfu-prefix.1
@@ -0,0 +1,84 @@
+.\" Automatically generated by Pandoc 2.5
+.\"
+.TH "DFU\-PREFIX" "1" "September 2021" "dfu\-util 0.11" ""
+.hy
+.SH NAME
+.PP
+dfu\-prefix \- add, check, or remove special firmware file prefix
+.SH SYNOPSIS
+.PP
+\f[B]dfu\-prefix\f[R] [ \f[B]\-s\f[R] \f[I]address\f[R] | \f[B]\-L\f[R]
+] \f[B]\-\-add\f[R] \f[I]DFU_FILE\f[R]
+.PD 0
+.P
+.PD
+\f[B]dfu\-prefix\f[R] [ \f[B]\-T\f[R] | \f[B]\-L\f[R] ]
+\f[B]\-\-check\f[R] \f[I]DFU_FILE\f[R]
+.PD 0
+.P
+.PD
+\f[B]dfu\-prefix\f[R] [ \f[B]\-T\f[R] | \f[B]\-L\f[R] ]
+\f[B]\-\-delete\f[R] \f[I]DFU_FILE\f[R]
+.PD 0
+.P
+.PD
+\f[B]dfu\-prefix\f[R] \f[B]\-\-help\f[R]
+.PD 0
+.P
+.PD
+\f[B]dfu\-prefix\f[R] \f[B]\-\-version\f[R]
+.SH DESCRIPTION
+.PP
+The program \f[B]dfu\-prefix\f[R] can be used to add, check or remove a
+prefix used by certain hardware manufacturers.
+The Stellaris format from TI and the LPC format from NXP is supported.
+.PP
+Note that a standard DFU firmware file has no concept of a prefix, and a
+DFU host tool like dfu\-util passes the prefix on to the device as part
+of the normal firmware payload.
+.SH OPTIONS
+.TP
+.B \-s, \-\-stellaris\-address \f[I]address\f[R]
+(in combination with \-\-add) Add TI Stellaris address prefix to file
+.TP
+.B \-T, \-\-stellaris
+(in combination with \-\-delete or \-\-check) Act on TI Stellaris
+address prefix of file
+.TP
+.B \-L, \-\-lpc\-prefix
+(in combination with \-\-add or \-\-delete or \-\-check) Use NXP LPC DFU
+prefix format
+.TP
+.B \-h, \-\-help
+Displays a help message.
+.TP
+.B \-V, \-\-version
+Displays the software version.
+.SH EXAMPLES
+.TP
+.B \f[B]dfu\-prefix\f[R] \-\-stellaris\-address 0x0100 \-\-add firmware.dfu
+Adds a Stellaris prefix with load address 0x0100
+.TP
+.B \f[B]dfu\-prefix\f[R] \-\-stellaris \-\-check firmware.dfu
+Checks the file firmware.dfu for a Stellaris prefix
+.TP
+.B \f[B]dfu\-prefix\f[R] \-\-lpc\-prefix \-\-delete firmware.dfu
+Removes a LPC prefix from the file firmware.dfu
+.SH EXIT VALUES
+.TP
+.B \f[B]0\f[R]
+Success (also if prefix is missing)
+.TP
+.B \f[B]\-64\f[R]
+Usage error
+.SH BUGS
+.PP
+https://sourceforge.net/p/dfu\-util/tickets/
+.SH COPYRIGHT
+.PP
+License GPLv2: GNU GPL version 2
+.SH SEE ALSO
+.PP
+\f[B]dfu\-suffix\f[R](1), \f[B]dfu\-util\f[R](1)
+.SH AUTHORS
+See AUTHORS file in source.
diff --git a/doc/dfu-prefix.1.md b/doc/dfu-prefix.1.md
new file mode 100644
index 0000000..2f76a07
--- /dev/null
+++ b/doc/dfu-prefix.1.md
@@ -0,0 +1,64 @@
+% DFU-PREFIX(1) dfu-util 0.11
+% See AUTHORS file in source
+% September 2021
+
+# NAME
+dfu-prefix - add, check, or remove special firmware file prefix
+
+# SYNOPSIS
+**dfu-prefix** [ **\-s** *address* | **\-L** ] **\--add** *DFU_FILE*\
+**dfu-prefix** [ **\-T** | **\-L** ] **\--check** *DFU_FILE*\
+**dfu-prefix** [ **\-T** | **\-L** ] **\--delete** *DFU_FILE*\
+**dfu-prefix** **\--help**\
+**dfu-prefix** **\--version**
+
+# DESCRIPTION
+The program **dfu-prefix** can be used to add, check or remove a prefix
+used by certain hardware manufacturers. The Stellaris format from TI
+and the LPC format from NXP is supported.
+
+Note that a standard DFU firmware file has no concept of a prefix, and
+a DFU host tool like dfu-util passes the prefix on to the device as
+part of the normal firmware payload.
+
+# OPTIONS
+-s, \--stellaris-address *address*
+: (in combination with \--add) Add TI Stellaris address prefix to file
+
+-T, \--stellaris
+: (in combination with \--delete or \--check) Act on TI Stellaris address prefix of file
+
+-L, \--lpc-prefix
+: (in combination with \--add or \--delete or \--check) Use NXP LPC DFU prefix format
+
+-h, \--help
+: Displays a help message.
+
+-V, \--version
+: Displays the software version.
+
+# EXAMPLES
+**dfu-prefix** \--stellaris-address 0x0100 \--add firmware.dfu
+: Adds a Stellaris prefix with load address 0x0100
+
+**dfu-prefix** \--stellaris \--check firmware.dfu
+: Checks the file firmware.dfu for a Stellaris prefix
+
+**dfu-prefix** \--lpc-prefix \--delete firmware.dfu
+: Removes a LPC prefix from the file firmware.dfu
+
+# EXIT VALUES
+**0**
+: Success (also if prefix is missing)
+
+**-64**
+: Usage error
+
+# BUGS
+https://sourceforge.net/p/dfu-util/tickets/
+
+# COPYRIGHT
+License GPLv2: GNU GPL version 2
+
+# SEE ALSO
+**dfu-suffix**(1), **dfu-util**(1)
diff --git a/doc/dfu-suffix.1 b/doc/dfu-suffix.1
new file mode 100644
index 0000000..edea5d0
--- /dev/null
+++ b/doc/dfu-suffix.1
@@ -0,0 +1,91 @@
+.\" Automatically generated by Pandoc 2.5
+.\"
+.TH "DFU\-SUFFIX" "1" "September 2021" "dfu\-util 0.11" ""
+.hy
+.SH NAME
+.PP
+dfu\-suffix \- add, check, or remove DFU firmware file suffix
+.SH SYNOPSIS
+.PP
+\f[B]dfu\-suffix\f[R] [\f[I]options\f[R]] \f[B]\-\-add\f[R]
+\f[I]DFU_FILE\f[R]
+.PD 0
+.P
+.PD
+\f[B]dfu\-suffix\f[R] \f[B]\-\-check\f[R] \f[I]DFU_FILE\f[R]
+.PD 0
+.P
+.PD
+\f[B]dfu\-suffix\f[R] \f[B]\-\-delete\f[R] \f[I]DFU_FILE\f[R]
+.PD 0
+.P
+.PD
+\f[B]dfu\-suffix\f[R] \f[B]\-\-help\f[R]
+.PD 0
+.P
+.PD
+\f[B]dfu\-suffix\f[R] \f[B]\-\-version\f[R]
+.SH DESCRIPTION
+.PP
+The program \f[B]dfu\-suffix\f[R] can be used to add, check or remove a
+DFU firmware file suffix, recommended for safely matching a firmware
+file and device.
+.PP
+Note that a suffix is recommended by the DFU standard, but not required.
+A DFU host tool like dfu\-util will recognize the suffix and use it to
+check that the device is matching, but not transfer the suffix to the
+device.
+.SH OPTIONS
+.TP
+.B \-v, \-\-vid \f[I]vendorID\f[R]
+Specify USB vendor ID (hexadecimal)
+.TP
+.B \-p, \-\-pid \f[I]productID\f[R]
+Specify USB product ID (hexadecimal)
+.TP
+.B \-d, \-\-did \f[I]deviceID\f[R]
+Specify USB device ID (hexadecimal)
+.TP
+.B \-S, \-\-spec \f[I]version\f[R]
+Specify DFU specification version (hexadecimal)
+.TP
+.B \-h, \-\-help
+Displays a help message.
+.TP
+.B \-V, \-\-version
+Displays the software version.
+.SH EXAMPLES
+.TP
+.B \f[B]dfu\-suffix\f[R] \-\-vid 0123 \-\-add firmware.dfu
+Adds a suffix matching vendor 0x0123 and product ID 0x4567.
+Since product and device ID are not specified, they will contain the
+wildcard value 0xFFFF.
+.TP
+.B \f[B]dfu\-suffix\f[R] \-\-check firmware.dfu
+Checks the file firmware.dfu for a valid DFU suffix
+.TP
+.B \f[B]dfu\-suffix\f[R] \-\-delete firmware.dfu
+Removes a valid DFU suffix from the file firmware.dfu
+.SH EXIT VALUES
+.TP
+.B \f[B]0\f[R]
+Success (also if suffix is missing)
+.TP
+.B \f[B]\-64\f[R]
+Usage error
+.SH LIMITATIONS
+.PP
+\f[B]dfu\-suffix\f[R] can not tell a broken DFU suffix (e.g.\ checksum
+mismatch) from a non\-existing suffix, so only a valid suffix can be
+removed.
+.SH BUGS
+.PP
+https://sourceforge.net/p/dfu\-util/tickets/
+.SH COPYRIGHT
+.PP
+License GPLv2: GNU GPL version 2
+.SH SEE ALSO
+.PP
+\f[B]dfu\-prefix\f[R](1), \f[B]dfu\-util\f[R](1)
+.SH AUTHORS
+See AUTHORS file in source.
diff --git a/doc/dfu-suffix.1.md b/doc/dfu-suffix.1.md
new file mode 100644
index 0000000..9bb4375
--- /dev/null
+++ b/doc/dfu-suffix.1.md
@@ -0,0 +1,72 @@
+% DFU-SUFFIX(1) dfu-util 0.11
+% See AUTHORS file in source
+% September 2021
+
+# NAME
+dfu-suffix - add, check, or remove DFU firmware file suffix
+
+# SYNOPSIS
+**dfu-suffix** [*options*] **\--add** *DFU_FILE*\
+**dfu-suffix** **\--check** *DFU_FILE*\
+**dfu-suffix** **\--delete** *DFU_FILE*\
+**dfu-suffix** **\--help**\
+**dfu-suffix** **\--version**
+
+# DESCRIPTION
+The program **dfu-suffix** can be used to add, check or remove a DFU firmware file suffix,
+recommended for safely matching a firmware file and device.
+
+Note that a suffix is recommended by the DFU standard, but not required.
+A DFU host tool like dfu-util will recognize the suffix and use it to check
+that the device is matching, but not transfer the suffix to the device.
+
+# OPTIONS
+-v, \--vid *vendorID*
+: Specify USB vendor ID (hexadecimal)
+
+-p, \--pid *productID*
+: Specify USB product ID (hexadecimal)
+
+-d, \--did *deviceID*
+: Specify USB device ID (hexadecimal)
+
+-S, \--spec *version*
+: Specify DFU specification version (hexadecimal)
+
+-h, \--help
+: Displays a help message.
+
+-V, \--version
+: Displays the software version.
+
+# EXAMPLES
+**dfu-suffix** \--vid 0123 \--add firmware.dfu
+: Adds a suffix matching vendor 0x0123 and product ID 0x4567.
+Since product and device ID are not specified,
+they will contain the wildcard value 0xFFFF.
+
+**dfu-suffix** \--check firmware.dfu
+: Checks the file firmware.dfu for a valid DFU suffix
+
+**dfu-suffix** \--delete firmware.dfu
+: Removes a valid DFU suffix from the file firmware.dfu
+
+# EXIT VALUES
+**0**
+: Success (also if suffix is missing)
+
+**-64**
+: Usage error
+
+# LIMITATIONS
+**dfu-suffix** can not tell a broken DFU suffix (e.g. checksum mismatch)
+from a non-existing suffix, so only a valid suffix can be removed.
+
+# BUGS
+https://sourceforge.net/p/dfu-util/tickets/
+
+# COPYRIGHT
+License GPLv2: GNU GPL version 2
+
+# SEE ALSO
+**dfu-prefix**(1), **dfu-util**(1)
diff --git a/doc/dfu-util.1 b/doc/dfu-util.1
index 4d1705f..3ef65e8 100644
--- a/doc/dfu-util.1
+++ b/doc/dfu-util.1
@@ -1,4 +1,4 @@
-.TH DFU-UTIL 1 "September 23, 2012"
+.TH "DFU\-UTIL" "1" "September 2021" "dfu\-util 0.11" ""
.SH NAME
dfu-util \- Device firmware update (DFU) USB programmer
.SH SYNOPSIS
@@ -39,6 +39,7 @@ dfu-util \- Device firmware update (DFU) USB programmer
.IR size \|]
.RB [\| \-Z
.IR size \|]
+.RB [\| \-w \|]
.RB [\| \-s
.IR address \|]
.RB [\| \-R \|]
@@ -136,6 +137,7 @@ Specify the DFU interface number.
Specify the altsetting of the DFU interface by name or by number.
.TP
.BR "\-S, \-\-serial" " [\fIRun-Time SERIAL\fP][,[\fIDFU Mode SERIAL\fP]]"
+.RS
Specify the run-time and DFU mode serial numbers used to further restrict
device matches. If multiple, identical DFU devices are simultaneously
connected to a system then vendor and product ID will be insufficient for
@@ -145,14 +147,16 @@ parameter to specify a serial number which also must match.
If only a single serial number is specified, then the same serial number is
used in both run-time and DFU mode. An empty serial number will match any
serial number in the corresponding mode.
+.RE
.TP
-.B "\-t, \-\-transfer-size" " SIZE"
+.BR "\-t, \-\-transfer-size" " SIZE"
Specify the number of bytes per USB transfer. The optimal value is
usually determined automatically so this option is rarely useful. If
you need to use this option for a device, please report it as a bug.
.TP
-.B "\-Z, \-\-upload-size" " SIZE"
-Specify the expected upload size, in bytes.
+.BR "\-Z, \-\-upload-size" " SIZE"
+Specify the expected upload size, in bytes. Note that the value is only used
+for scaling the progress bar, the actual upload size is determined by the device.
.TP
.BR "\-U, \-\-upload" " FILE"
Read firmware from device into
@@ -161,23 +165,44 @@ Read firmware from device into
.BR "\-D, \-\-download" " FILE"
Write firmware from
.B FILE
-into device. When FILE is \-, the firmware is read from stdin.
+into device. When
+.B FILE
+is \-, the firmware is read from stdin.
.TP
.B "\-R, \-\-reset"
Issue USB reset signalling after upload or download has finished.
.TP
-.BR "\-s, \-\-dfuse-address" " address"
+.B "\-e, \-\-detach"
+Request that the device re-enumerate out of run-time mode and into DFU mode as
+when uploading or downloading, but exit immediately after sending the request.
+.TP
+.BR "\-E, \-\-detach-delay" " SECONDS"
+When uploading or downloading, wait
+.B SECONDS
+seconds for the device to re-enumerate after sending the detach request before
+giving up. Defaults to 5 seconds. This option has no effect with \fB-e\fP,
+since that causes dfu-util to immediately exit after sending the detach request.
+.TP
+.B "\-w, \-\-wait"
+Wait until matching device appears on the USB bus.
+.TP
+.BR "\-s, \-\-dfuse-address" " [\fIADDRESS\fP][:\fILENGTH\fP][:\fIMODIFIERS\fP]"
Specify target address for raw binary download/upload on DfuSe devices. Do
.B not
-use this for downloading DfuSe (.dfu) files. Modifiers can be added
-to the address, separated by a colon, to perform special DfuSE commands such
-as "leave" DFU mode, "unprotect" and "mass-erase" flash memory.
+use this option for downloading DfuSe (.dfu) files.
+A length can be specified for uploads. Modifiers can be added after the
+address, separated by a colon, to perform special DfuSE commands such as
+"leave" DFU mode, "unprotect" and "mass-erase" flash memory.
+If the device can be expected to reset itself after the operation, "will-reset"
+should be added. The "force" modifier will override some sanity checks, and is
+also needed for the "unprotect" and "mass-erase" operations.
.TP
.B "\-v, \-\-verbose"
Print more information about dfu-util's operation. A second
.B -v
-will turn on verbose logging of USB requests. Repeat this option to further
-increase verbosity.
+adds more details. A third
+.B -v
+activates verbose logging of USB requests (libusb debug output).
.TP
.B "\-h, \-\-help"
Show a help text and exit.
@@ -215,7 +240,7 @@ Flashing a
.B .dfu
(special DfuSe format) file to the device:
.br
-.B " $ dfu-util -a 0 -D /path/to/dfuse-image.dfu"
+.B " $ dfu-util -D /path/to/dfuse-image.dfu"
.PP
Reading out 1 KB of flash starting at address 0x8000000:
.br
@@ -234,7 +259,7 @@ Please use the
information in your bug report.
.SH SEE ALSO
The dfu-util home page is
-.B http://sourceforge.net/p/dfu-util/
+.B http://dfu-util.sourceforge.net/
.SH HISTORY
dfu-util was originally written for the OpenMoko project by
Weston Schmidt <weston_schmidt@yahoo.com> and
diff --git a/m4/compile b/m4/compile
index 531136b..99e5052 100755
--- a/m4/compile
+++ b/m4/compile
@@ -1,9 +1,9 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
-scriptversion=2012-10-14.11; # UTC
+scriptversion=2018-03-07.03; # UTC
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
# 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 <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -255,7 +255,8 @@ EOF
echo "compile $scriptversion"
exit $?
;;
- cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
+ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
@@ -339,9 +340,9 @@ exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/m4/depcomp b/m4/depcomp
index 25a39e6..65cbf70 100755
--- a/m4/depcomp
+++ b/m4/depcomp
@@ -1,10 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
-scriptversion=2012-03-27.16; # UTC
+scriptversion=2018-03-07.03; # UTC
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
-# 2011, 2012 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# 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
@@ -17,7 +16,7 @@ scriptversion=2012-03-27.16; # UTC
# 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 <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -28,9 +27,9 @@ scriptversion=2012-03-27.16; # UTC
case $1 in
'')
- echo "$0: No command. Try '$0 --help' for more information." 1>&2
- exit 1;
- ;;
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
@@ -57,11 +56,65 @@ EOF
;;
esac
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
# A tabulation character.
tab=' '
# A newline character.
nl='
'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
@@ -75,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
@@ -86,32 +142,32 @@ if test "$depmode" = hp; then
fi
if test "$depmode" = dashXmstdout; then
- # This is just like dashmstdout with a different argument.
- dashmflag=-xM
- depmode=dashmstdout
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
- # This is just like msvisualcpp but w/o cygpath translation.
- # Just convert the backslash-escaped backslashes to single forward
- # slashes to satisfy depend.m4
- cygpath_u='sed s,\\\\,/,g'
- depmode=msvisualcpp
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
- # This is just like msvc7 but w/o cygpath translation.
- # Just convert the backslash-escaped backslashes to single forward
- # slashes to satisfy depend.m4
- cygpath_u='sed s,\\\\,/,g'
- depmode=msvc7
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
fi
if test "$depmode" = xlc; then
- # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
- gccflag=-qmakedep=gcc,-MF
- depmode=gcc
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
fi
case "$depmode" in
@@ -134,8 +190,7 @@ gcc3)
done
"$@"
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -143,13 +198,17 @@ gcc3)
;;
gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-## -MM, not -M (despite what the docs say).
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
@@ -157,15 +216,14 @@ gcc)
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
- alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
@@ -174,15 +232,15 @@ gcc)
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
- tr ' ' "$nl" < "$tmpdepfile" |
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
- | sed -e 's/$/ :/' >> "$depfile"
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -200,8 +258,7 @@ sgi)
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -209,7 +266,6 @@ sgi)
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
-
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
@@ -217,19 +273,15 @@ sgi)
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
- tr "$nl" ' ' >> "$depfile"
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
-
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
- >> "$depfile"
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
+ make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
@@ -247,9 +299,8 @@ aix)
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ set_dir_from "$object"
+ set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
@@ -262,9 +313,7 @@ aix)
"$@" -M
fi
stat=$?
-
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
@@ -273,65 +322,113 @@ aix)
do
test -f "$tmpdepfile" && break
done
- if test -f "$tmpdepfile"; then
- # Each line is of the form 'foo.o: dependent.h'.
- # Do two passes, one to just change these to
- # '$object: dependent.h' and one to simply 'dependent.h:'.
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
-icc)
- # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
- # However on
- # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
- # ICC 7.0 will fill foo.d with something like
- # foo.o: sub/foo.c
- # foo.o: sub/foo.h
- # which is wrong. We want
- # sub/foo.o: sub/foo.c
- # sub/foo.o: sub/foo.h
- # sub/foo.c:
- # sub/foo.h:
- # ICC 7.1 will output
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
- # and will wrap long lines using '\':
+ # and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
- # tcc 0.9.26 (FIXME still under development at the moment of writing)
- # will emit a similar output, but also prepend the continuation lines
- # with horizontal tabulation characters.
- "$@" -MD -MF "$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
+
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
- # Each line is of the form 'foo.o: dependent.h',
- # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
- # '$object: dependent.h' and one to simply 'dependent.h:'.
- sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
- < "$tmpdepfile" > "$depfile"
- sed '
- s/[ '"$tab"'][ '"$tab"']*/ /g
- s/^ *//
- s/ *\\*$//
- s/^[^:]*: *//
- /^$/d
- /:$/d
- s/$/ :/
- ' < "$tmpdepfile" >> "$depfile"
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -342,9 +439,8 @@ hp2)
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ set_dir_from "$object"
+ set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
@@ -355,8 +451,7 @@ hp2)
"$@" +Maked
fi
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
@@ -366,76 +461,61 @@ hp2)
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
- s/^ *//
- s/ \\*$//
- s/$/:/
- p
- }' "$tmpdepfile" >> "$depfile"
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
else
- echo "#dummy" > "$depfile"
+ make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
- # The Tru64 compiler uses -MD to generate dependencies as a side
- # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
- # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
- # dependencies in 'foo.d' instead, so we check for that too.
- # Subdirectories are respected.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-
- if test "$libtool" = yes; then
- # With Tru64 cc, shared objects can also be used to make a
- # static library. This mechanism is used in libtool 1.4 series to
- # handle both shared and static libraries in a single compilation.
- # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
- #
- # With libtool 1.5 this exception was removed, and libtool now
- # generates 2 separate objects for the 2 libraries. These two
- # compilations output dependencies in $dir.libs/$base.o.d and
- # in $dir$base.o.d. We have to check for both files, because
- # one of the two compilations can be disabled. We should prefer
- # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
- # automatically cleaned when .libs/ is deleted, while ignoring
- # the former would cause a distcleancheck panic.
- tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
- tmpdepfile2=$dir$base.o.d # libtool 1.5
- tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
- tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
- "$@" -Wc,-MD
- else
- tmpdepfile1=$dir$base.o.d
- tmpdepfile2=$dir$base.d
- tmpdepfile3=$dir$base.d
- tmpdepfile4=$dir$base.d
- "$@" -MD
- fi
-
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
msvc7)
if test "$libtool" = yes; then
@@ -446,8 +526,7 @@ msvc7)
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
- if test "$stat" = 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -473,6 +552,7 @@ $ {
G
p
}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
@@ -524,13 +604,14 @@ dashmstdout)
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
- sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
- tr ' ' "$nl" < "$tmpdepfile" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -583,10 +664,12 @@ makedepend)
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
- sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
@@ -622,10 +705,10 @@ cpp)
esac
done
- "$@" -E |
- sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
- -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
- sed '$ s: \\$::' > "$tmpdepfile"
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
@@ -657,15 +740,15 @@ msvisualcpp)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
- set fnord "$@"
- shift
- shift
- ;;
+ set fnord "$@"
+ shift
+ shift
+ ;;
*)
- set fnord "$@" "$arg"
- shift
- shift
- ;;
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
esac
done
"$@" -E 2>/dev/null |
@@ -700,9 +783,9 @@ exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/m4/install-sh b/m4/install-sh
index a9244eb..8175c64 100755
--- a/m4/install-sh
+++ b/m4/install-sh
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2011-01-19.21; # UTC
+scriptversion=2018-03-11.20; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,25 +35,21 @@ scriptversion=2011-01-19.21; # UTC
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
+# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
+tab=' '
nl='
'
-IFS=" "" $nl"
+IFS=" $tab$nl"
-# set DOITPROG to echo to test this script
+# Set DOITPROG to "echo" to test this script.
-# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
+doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
@@ -68,17 +64,6 @@ mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
-posix_glob='?'
-initialize_posix_glob='
- test "$posix_glob" != "?" || {
- if (set -f) 2>/dev/null; then
- posix_glob=
- else
- posix_glob=:
- fi
- }
-'
-
posix_mkdir=
# Desired mode of installed file.
@@ -97,7 +82,7 @@ dir_arg=
dst_arg=
copy_on_change=false
-no_target_directory=
+is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
@@ -137,46 +122,57 @@ while test $# -ne 0; do
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
- shift;;
+ shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- shift;;
+ case $mode in
+ *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
-o) chowncmd="$chownprog $2"
- shift;;
+ shift;;
-s) stripcmd=$stripprog;;
- -t) dst_arg=$2
- # Protect names problematic for `test' and other utilities.
- case $dst_arg in
- -* | [=\(\)!]) dst_arg=./$dst_arg;;
- esac
- shift;;
+ -t)
+ is_target_a_directory=always
+ dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
- -T) no_target_directory=true;;
+ -T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
- --) shift
- break;;
+ --) shift
+ break;;
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
*) break;;
esac
shift
done
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+ if test -n "$dst_arg"; then
+ echo "$0: target directory not allowed when installing a directory." >&2
+ exit 1
+ fi
+fi
+
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
@@ -190,7 +186,7 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
fi
shift # arg
dst_arg=$arg
- # Protect names problematic for `test' and other utilities.
+ # Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
@@ -202,12 +198,21 @@ if test $# -eq 0; then
echo "$0: no input file specified." >&2
exit 1
fi
- # It's OK to call `install-sh -d' without argument.
+ # It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
+ if test $# -gt 1 || test "$is_target_a_directory" = always; then
+ if test ! -d "$dst_arg"; then
+ echo "$0: $dst_arg: Is not a directory." >&2
+ exit 1
+ fi
+ fi
+fi
+
+if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
@@ -223,16 +228,16 @@ if test -z "$dir_arg"; then
*[0-7])
if test -z "$stripcmd"; then
- u_plus_rw=
+ u_plus_rw=
else
- u_plus_rw='% 200'
+ u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
- u_plus_rw=
+ u_plus_rw=
else
- u_plus_rw=,u+rw
+ u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
@@ -240,7 +245,7 @@ fi
for src
do
- # Protect names problematic for `test' and other utilities.
+ # Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
@@ -266,122 +271,113 @@ do
fi
dst=$dst_arg
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
+ # If destination is a directory, append the input filename.
if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dst_arg: Is a directory" >&2
- exit 1
+ if test "$is_target_a_directory" = never; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
fi
dstdir=$dst
- dst=$dstdir/`basename "$src"`
+ dstbase=`basename "$src"`
+ case $dst in
+ */) dst=$dst$dstbase;;
+ *) dst=$dst/$dstbase;;
+ esac
dstdir_status=0
else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
+ dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
+ case $dstdir in
+ */) dstdirslash=$dstdir;;
+ *) dstdirslash=$dstdir/;;
+ esac
+
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ # Note that $RANDOM variable is not portable (e.g. dash); Use it
+ # here however when possible just to lower collision chance.
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
+ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ # Because "mkdir -p" follows existing symlinks and we likely work
+ # directly in world-writeable /tmp, make sure that the '$tmpdir'
+ # directory is successfully created first before we actually test
+ # 'mkdir -p' feature.
+ if (umask $mkdir_umask &&
+ $mkdirprog $mkdir_mode "$tmpdir" &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ test_tmpdir="$tmpdir/a"
+ ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
esac
if
$posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
@@ -391,53 +387,51 @@ do
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
- /*) prefix='/';;
- [-=\(\)!]*) prefix='./';;
- *) prefix='';;
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
esac
- eval "$initialize_posix_glob"
-
oIFS=$IFS
IFS=/
- $posix_glob set -f
+ set -f
set fnord $dstdir
shift
- $posix_glob set +f
+ set +f
IFS=$oIFS
prefixes=
for d
do
- test X"$d" = X && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
done
if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
fi
fi
fi
@@ -450,8 +444,8 @@ do
else
# Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
+ dsttmp=${dstdirslash}_inst.$$_
+ rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
@@ -472,15 +466,12 @@ do
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
- eval "$initialize_posix_glob" &&
- $posix_glob set -f &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+ set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
- $posix_glob set +f &&
-
+ set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
@@ -493,24 +484,24 @@ do
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
- } ||
- { echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
@@ -519,9 +510,9 @@ do
done
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/m4/missing b/m4/missing
index 86a8fc3..625aeb1 100755
--- a/m4/missing
+++ b/m4/missing
@@ -1,11 +1,10 @@
#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
+# Common wrapper for a few potentially missing GNU programs.
-scriptversion=2012-01-06.13; # UTC
+scriptversion=2018-03-07.03; # UTC
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
-# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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
@@ -18,7 +17,7 @@ scriptversion=2012-01-06.13; # UTC
# 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 <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -26,68 +25,40 @@ scriptversion=2012-01-06.13; # UTC
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
- echo 1>&2 "Try \`$0 --help' for more information"
+ echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
-run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
- configure_ac=configure.ac
-else
- configure_ac=configure.in
-fi
+case $1 in
-msg="missing on your system"
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
-case $1 in
---run)
- # Try to run requested program, and just exit if it succeeds.
- run=
- shift
- "$@" && exit 0
- # Exit code 63 means version mismatch. This often happens
- # when the user try to use an ancient version of a tool on
- # a file that requires a minimum version. In this case we
- # we should proceed has if the program had been absent, or
- # if --run hadn't been passed.
- if test $? = 63; then
- run=:
- msg="probably too old"
- fi
- ;;
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
- --run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
- aclocal touch file \`aclocal.m4'
- autoconf touch file \`configure'
- autoheader touch file \`config.h.in'
- autom4te touch the output file, or create a stub one
- automake touch all \`Makefile.in' files
- bison create \`y.tab.[ch]', if possible, from existing .[ch]
- flex create \`lex.yy.c', if possible, from existing .c
- help2man touch the output file
- lex create \`lex.yy.c', if possible, from existing .c
- makeinfo touch the output file
- yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
-Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
-\`g' are ignored when checking the name.
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
@@ -99,233 +70,146 @@ Send bug reports to <bug-automake@gnu.org>."
;;
-*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
-# normalize program name to check for.
-program=`echo "$1" | sed '
- s/^gnu-//; t
- s/^gnu//; t
- s/^g//; t'`
-
-# Now exit if we have it, but it failed. Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program). This is about non-GNU programs, so use $1 not
-# $program.
-case $1 in
- lex*|yacc*)
- # Not GNU programs, they don't have --version.
- ;;
-
- *)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- # Could not run --version or --help. This is probably someone
- # running `$TOOL --version' or `$TOOL --help' to check whether
- # $TOOL exists and not knowing $TOOL uses missing.
- exit 1
- fi
- ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case $program in
- aclocal*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acinclude.m4' or \`${configure_ac}'. You might want
- to install the \`Automake' and \`Perl' packages. Grab them from
- any GNU archive site."
- touch aclocal.m4
- ;;
-
- autoconf*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`${configure_ac}'. You might want to install the
- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
- archive site."
- touch configure
- ;;
-
- autoheader*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acconfig.h' or \`${configure_ac}'. You might want
- to install the \`Autoconf' and \`GNU m4' packages. Grab them
- from any GNU archive site."
- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
- test -z "$files" && files="config.h"
- touch_files=
- for f in $files; do
- case $f in
- *:*) touch_files="$touch_files "`echo "$f" |
- sed -e 's/^[^:]*://' -e 's/:.*//'`;;
- *) touch_files="$touch_files $f.in";;
- esac
- done
- touch $touch_files
- ;;
-
- automake*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
- You might want to install the \`Automake' and \`Perl' packages.
- Grab them from any GNU archive site."
- find . -type f -name Makefile.am -print |
- sed 's/\.am$/.in/' |
- while read f; do touch "$f"; done
- ;;
-
- autom4te*)
- echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
- You might have modified some files without having the
- proper tools for further handling them.
- You can get \`$1' as part of \`Autoconf' from any GNU
- archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo "#! /bin/sh"
- echo "# Created by GNU Automake missing as a replacement of"
- echo "# $ $@"
- echo "exit 0"
- chmod +x $file
- exit 1
- fi
- ;;
-
- bison*|yacc*)
- echo 1>&2 "\
-WARNING: \`$1' $msg. You should only need it if
- you modified a \`.y' file. You may need the \`Bison' package
- in order for those modifications to take effect. You can get
- \`Bison' from any GNU archive site."
- rm -f y.tab.c y.tab.h
- if test $# -ne 1; then
- eval LASTARG=\${$#}
- case $LASTARG in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if test ! -f y.tab.h; then
- echo >y.tab.h
- fi
- if test ! -f y.tab.c; then
- echo 'main() { return 0; }' >y.tab.c
- fi
- ;;
-
- lex*|flex*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.l' file. You may need the \`Flex' package
- in order for those modifications to take effect. You can get
- \`Flex' from any GNU archive site."
- rm -f lex.yy.c
- if test $# -ne 1; then
- eval LASTARG=\${$#}
- case $LASTARG in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if test ! -f lex.yy.c; then
- echo 'main() { return 0; }' >lex.yy.c
- fi
- ;;
-
- help2man*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a dependency of a manual page. You may need the
- \`Help2man' package in order for those modifications to take
- effect. You can get \`Help2man' from any GNU archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo ".ab help2man is required to generate this page"
- exit $?
- fi
- ;;
-
- makeinfo*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.texi' or \`.texinfo' file, or any other file
- indirectly affecting the aspect of the manual. The spurious
- call might also be the consequence of using a buggy \`make' (AIX,
- DU, IRIX). You might want to install the \`Texinfo' package or
- the \`GNU make' package. Grab either from any GNU archive site."
- # The file to touch is that specified with -o ...
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -z "$file"; then
- # ... or it is the one specified with @setfilename ...
- infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '
- /^@setfilename/{
- s/.* \([^ ]*\) *$/\1/
- p
- q
- }' $infile`
- # ... or it is derived from the source name (dir/f.texi becomes f.info)
- test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
- fi
- # If the file does not exist, the user really needs makeinfo;
- # let's fail without touching anything.
- test -f $file || exit 1
- touch $file
- ;;
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
- *)
- echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
- You might have modified some files without having the
- proper tools for further handling them. Check the \`README' file,
- it often tells you about the needed prerequisites for installing
- this package. You may also peek at any GNU archive site, in case
- some other package would contain this missing \`$1' program."
- exit 1
+perl_URL=https://www.perl.org/
+flex_URL=https://github.com/westes/flex
+gnu_software_URL=https://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'autom4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
;;
-esac
-
-exit 0
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/src/Makefile.in b/src/Makefile.in
index 7f0f072..c35a06d 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -79,12 +89,11 @@ POST_UNINSTALL = :
bin_PROGRAMS = dfu-util$(EXEEXT) dfu-suffix$(EXEEXT) \
dfu-prefix$(EXEEXT)
subdir = src
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/m4/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
@@ -116,7 +125,12 @@ am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/m4/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/dfu.Po ./$(DEPDIR)/dfu_file.Po \
+ ./$(DEPDIR)/dfu_load.Po ./$(DEPDIR)/dfu_util.Po \
+ ./$(DEPDIR)/dfuse.Po ./$(DEPDIR)/dfuse_mem.Po \
+ ./$(DEPDIR)/main.Po ./$(DEPDIR)/prefix.Po \
+ ./$(DEPDIR)/quirks.Po ./$(DEPDIR)/suffix.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -158,6 +172,7 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/m4/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -243,6 +258,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@@ -294,14 +310,13 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -373,16 +388,22 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@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)/dfu_util.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)/prefix.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quirks.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/suffix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfu.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfu_file.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfu_load.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfu_util.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfuse.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfuse_mem.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefix.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quirks.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/suffix.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -450,7 +471,10 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@@ -522,7 +546,16 @@ clean: clean-am
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-am
- -rm -rf ./$(DEPDIR)
+ -rm -f ./$(DEPDIR)/dfu.Po
+ -rm -f ./$(DEPDIR)/dfu_file.Po
+ -rm -f ./$(DEPDIR)/dfu_load.Po
+ -rm -f ./$(DEPDIR)/dfu_util.Po
+ -rm -f ./$(DEPDIR)/dfuse.Po
+ -rm -f ./$(DEPDIR)/dfuse_mem.Po
+ -rm -f ./$(DEPDIR)/main.Po
+ -rm -f ./$(DEPDIR)/prefix.Po
+ -rm -f ./$(DEPDIR)/quirks.Po
+ -rm -f ./$(DEPDIR)/suffix.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -568,7 +601,16 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
+ -rm -f ./$(DEPDIR)/dfu.Po
+ -rm -f ./$(DEPDIR)/dfu_file.Po
+ -rm -f ./$(DEPDIR)/dfu_load.Po
+ -rm -f ./$(DEPDIR)/dfu_util.Po
+ -rm -f ./$(DEPDIR)/dfuse.Po
+ -rm -f ./$(DEPDIR)/dfuse_mem.Po
+ -rm -f ./$(DEPDIR)/main.Po
+ -rm -f ./$(DEPDIR)/prefix.Po
+ -rm -f ./$(DEPDIR)/quirks.Po
+ -rm -f ./$(DEPDIR)/suffix.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -588,7 +630,7 @@ uninstall-am: uninstall-binPROGRAMS
.MAKE: install-am install-strip
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \
distclean distclean-compile distclean-generic distclean-tags \
distdir dvi dvi-am html html-am info info-am install \
@@ -602,6 +644,8 @@ uninstall-am: uninstall-binPROGRAMS
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-binPROGRAMS
+.PRECIOUS: Makefile
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/dfu.c b/src/dfu.c
index 14d7673..091e74b 100644
--- a/src/dfu.c
+++ b/src/dfu.c
@@ -21,9 +21,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
-
#include <libusb.h>
#include "portable.h"
diff --git a/src/dfu.h b/src/dfu.h
index 8e3caeb..c91c427 100644
--- a/src/dfu.h
+++ b/src/dfu.h
@@ -23,6 +23,7 @@
#include <libusb.h>
#include "usb_dfu.h"
+#include "dfuse_mem.h"
/* DFU states */
#define STATE_APP_IDLE 0x00
@@ -67,6 +68,7 @@
/* DFU interface */
#define DFU_IFF_DFU 0x0001 /* DFU Mode, (not Runtime) */
+#define DFU_IFF_ALT 0x0002 /* Multiple alternate settings */
/* This is based off of DFU_GETSTATUS
*
@@ -101,6 +103,7 @@ struct dfu_if {
libusb_device *dev;
libusb_device_handle *dev_handle;
struct dfu_if *next;
+ struct memsegment *mem_layout; /* for DfuSe */
};
int dfu_detach( libusb_device_handle *device,
diff --git a/src/dfu_file.c b/src/dfu_file.c
index 7c897d4..dbe7374 100644
--- a/src/dfu_file.c
+++ b/src/dfu_file.c
@@ -1,7 +1,7 @@
/*
* Load or store DFU files including suffix and prefix
*
- * Copyright 2014 Tormod Volden <debian.tormod@gmail.com>
+ * Copyright 2014-2019 Tormod Volden <debian.tormod@gmail.com>
* Copyright 2012 Stefan Schmidt <stefan@datenfreihafen.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#define __USE_MINGW_ANSI_STDIO 1
#include <stdio.h>
#include <string.h>
#include <errno.h>
@@ -26,6 +31,7 @@
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
+#include <limits.h>
#include "portable.h"
#include "dfu_file.h"
@@ -93,6 +99,11 @@ static int probe_prefix(struct dfu_file *file)
if (file->size.total < LMDFU_PREFIX_LENGTH)
return 1;
if ((prefix[0] == 0x01) && (prefix[1] == 0x00)) {
+ uint32_t payload_length = (prefix[7] << 24) | (prefix[6] << 16) |
+ (prefix[5] << 8) | prefix[4];
+ uint32_t expected_payload_length = (uint32_t) file->size.total - LMDFU_PREFIX_LENGTH - file->size.suffix;
+ if (payload_length != expected_payload_length)
+ return 1;
file->prefix_type = LMDFU_PREFIX;
file->size.prefix = LMDFU_PREFIX_LENGTH;
file->lmdfu_address = 1024 * ((prefix[3] << 8) | prefix[2]);
@@ -142,7 +153,7 @@ void dfu_progress_bar(const char *desc, unsigned long long curr,
}
buf[x] = 0;
- printf("\r%s\t[%s] %3lld%% %12lld bytes", desc, buf,
+ printf("\r%s\t[%s] %3llu%% %12llu bytes", desc, buf,
(100ULL * curr) / max, curr);
if (progress == PROGRESS_BAR_WIDTH)
@@ -194,7 +205,7 @@ void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum pre
free(file->firmware);
if (!strcmp(file->name, "-")) {
- int read_bytes;
+ size_t read_bytes;
#ifdef WIN32
_setmode( _fileno( stdin ), _O_BINARY );
@@ -205,33 +216,52 @@ void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum pre
while (read_bytes == STDIN_CHUNK_SIZE) {
file->firmware = (uint8_t*) realloc(file->firmware, file->size.total + STDIN_CHUNK_SIZE);
if (!file->firmware)
- err(EX_IOERR, "Could not allocate firmware buffer");
+ err(EX_SOFTWARE, "Could not allocate firmware buffer");
read_bytes = fread(file->firmware + file->size.total, 1, STDIN_CHUNK_SIZE, stdin);
file->size.total += read_bytes;
}
if (verbose)
- printf("Read %i bytes from stdin\n", file->size.total);
+ printf("Read %lli bytes from stdin\n", (long long) file->size.total);
/* Never require suffix when reading from stdin */
check_suffix = MAYBE_SUFFIX;
} else {
+ ssize_t read_count;
+ off_t read_total = 0;
+
f = open(file->name, O_RDONLY | O_BINARY);
if (f < 0)
- err(EX_IOERR, "Could not open file %s for reading", file->name);
+ err(EX_NOINPUT, "Could not open file %s for reading", file->name);
offset = lseek(f, 0, SEEK_END);
- if ((int)offset < 0 || (int)offset != offset)
- err(EX_IOERR, "File size is too big");
+ if (offset < 0)
+ err(EX_SOFTWARE, "File size is too big");
if (lseek(f, 0, SEEK_SET) != 0)
err(EX_IOERR, "Could not seek to beginning");
file->size.total = offset;
+
+ if (file->size.total > SSIZE_MAX) {
+ err(EX_SOFTWARE, "File too large for memory allocation on this platform");
+ }
file->firmware = dfu_malloc(file->size.total);
- if (read(f, file->firmware, file->size.total) != file->size.total) {
- err(EX_IOERR, "Could not read %d bytes from %s",
- file->size.total, file->name);
+ while (read_total < file->size.total) {
+ off_t to_read = file->size.total - read_total;
+ /* read() limit on Linux, slightly below MAX_INT on Windows */
+ if (to_read > 0x7ffff000)
+ to_read = 0x7ffff000;
+ read_count = read(f, file->firmware + read_total, to_read);
+ if (read_count == 0)
+ break;
+ if (read_count == -1 && errno != EINTR)
+ break;
+ read_total += read_count;
+ }
+ if (read_total != file->size.total) {
+ err(EX_IOERR, "Could only read %lld of %lld bytes from %s",
+ (long long) read_total, (long long) file->size.total, file->name);
}
close(f);
}
@@ -285,12 +315,12 @@ void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum pre
file->size.suffix = dfusuffix[11];
if (file->size.suffix < DFU_SUFFIX_LENGTH) {
- errx(EX_IOERR, "Unsupported DFU suffix length %d",
+ errx(EX_DATAERR, "Unsupported DFU suffix length %d",
file->size.suffix);
}
if (file->size.suffix > file->size.total) {
- errx(EX_IOERR, "Invalid DFU suffix length %d",
+ errx(EX_DATAERR, "Invalid DFU suffix length %d",
file->size.suffix);
}
@@ -302,23 +332,22 @@ checked:
if (missing_suffix) {
if (check_suffix == NEEDS_SUFFIX) {
warnx("%s", reason);
- errx(EX_IOERR, "Valid DFU suffix needed");
+ errx(EX_DATAERR, "Valid DFU suffix needed");
} else if (check_suffix == MAYBE_SUFFIX) {
- warnx("%s", reason);
- warnx("A valid DFU suffix will be required in "
- "a future dfu-util release!!!");
+ warnx("Warning: %s", reason);
+ warnx("A valid DFU suffix will be required in a future dfu-util release");
}
} else {
if (check_suffix == NO_SUFFIX) {
- errx(EX_SOFTWARE, "Please remove existing DFU suffix before adding a new one.\n");
+ errx(EX_DATAERR, "Please remove existing DFU suffix before adding a new one.\n");
}
}
}
res = probe_prefix(file);
if ((res || file->size.prefix == 0) && check_prefix == NEEDS_PREFIX)
- errx(EX_IOERR, "Valid DFU prefix needed");
+ errx(EX_DATAERR, "Valid DFU prefix needed");
if (file->size.prefix && check_prefix == NO_PREFIX)
- errx(EX_IOERR, "A prefix already exists, please delete it first");
+ errx(EX_DATAERR, "A prefix already exists, please delete it first");
if (file->size.prefix && verbose) {
uint8_t *data = file->firmware;
if (file->prefix_type == LMDFU_PREFIX)
@@ -328,14 +357,14 @@ checked:
"Payload length: %d\n",
file->lmdfu_address,
data[4] | (data[5] << 8) |
- (data[6] << 16) | (data[7] << 14));
+ (data[6] << 16) | (data[7] << 24));
else if (file->prefix_type == LPCDFU_UNENCRYPTED_PREFIX)
printf("Possible unencrypted NXP LPC DFU prefix with "
"the following properties\n"
"Payload length: %d kiByte\n",
data[2] >>1 | (data[3] << 7) );
else
- errx(EX_IOERR, "Unknown DFU prefix type");
+ errx(EX_DATAERR, "Unknown DFU prefix type");
}
}
@@ -346,7 +375,7 @@ void dfu_store_file(struct dfu_file *file, int write_suffix, int write_prefix)
f = open(file->name, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT, 0666);
if (f < 0)
- err(EX_IOERR, "Could not open file %s for writing", file->name);
+ err(EX_CANTCREAT, "Could not open file %s for writing", file->name);
/* write prefix, if any */
if (write_prefix) {
diff --git a/src/dfu_file.h b/src/dfu_file.h
index abebd44..98a7aa2 100644
--- a/src/dfu_file.h
+++ b/src/dfu_file.h
@@ -11,7 +11,7 @@ struct dfu_file {
uint8_t *firmware;
/* Different sizes */
struct {
- int total;
+ off_t total;
int prefix;
int suffix;
} size;
diff --git a/src/dfu_load.c b/src/dfu_load.c
index 64f7009..a461614 100644
--- a/src/dfu_load.c
+++ b/src/dfu_load.c
@@ -9,7 +9,7 @@
*
* Copyright 2007-2008 Harald Welte <laforge@gnumonks.org>
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
- * Copyright 2014 Tormod Volden <debian.tormod@gmail.com>
+ * Copyright 2014-2016 Tormod Volden <debian.tormod@gmail.com>
*
* 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
@@ -26,6 +26,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#define __USE_MINGW_ANSI_STDIO 1
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -43,7 +48,7 @@
int dfuload_do_upload(struct dfu_if *dif, int xfer_size,
int expected_size, int fd)
{
- int total_bytes = 0;
+ off_t total_bytes = 0;
unsigned short transaction = 0;
unsigned char *buf;
int ret;
@@ -51,49 +56,52 @@ int dfuload_do_upload(struct dfu_if *dif, int xfer_size,
buf = dfu_malloc(xfer_size);
printf("Copying data from DFU device to PC\n");
- dfu_progress_bar("Upload", 0, 1);
while (1) {
int rc;
+ dfu_progress_bar("Upload", total_bytes, expected_size);
rc = dfu_upload(dif->dev_handle, dif->interface,
- xfer_size, transaction++, buf);
+ xfer_size, transaction++, buf);
if (rc < 0) {
- warnx("Error during upload");
+ warnx("\nError during upload (%s)",
+ libusb_error_name(rc));
ret = rc;
- goto out_free;
+ break;
}
dfu_file_write_crc(fd, 0, buf, rc);
total_bytes += rc;
if (total_bytes < 0)
- errx(EX_SOFTWARE, "Received too many bytes (wraparound)");
+ errx(EX_SOFTWARE, "\nReceived too many bytes (wraparound)");
if (rc < xfer_size) {
/* last block, return */
- ret = total_bytes;
+ ret = 0;
break;
}
+ }
+ free(buf);
+ if (ret == 0) {
+ dfu_progress_bar("Upload", total_bytes, total_bytes);
+ } else {
dfu_progress_bar("Upload", total_bytes, expected_size);
+ printf("\n");
}
- ret = 0;
-
-out_free:
- dfu_progress_bar("Upload", total_bytes, total_bytes);
if (total_bytes == 0)
printf("\nFailed.\n");
- free(buf);
- if (verbose)
- printf("Received a total of %i bytes\n", total_bytes);
+ else
+ printf("Received a total of %lli bytes\n", (long long) total_bytes);
+
if (expected_size != 0 && total_bytes != expected_size)
- errx(EX_SOFTWARE, "Unexpected number of bytes uploaded from device");
+ warnx("Unexpected number of bytes uploaded from device");
return ret;
}
int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
{
- int bytes_sent;
- int expected_size;
+ off_t bytes_sent;
+ off_t expected_size;
unsigned char *buf;
unsigned short transaction = 0;
struct dfu_status dst;
@@ -107,19 +115,20 @@ int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
dfu_progress_bar("Download", 0, 1);
while (bytes_sent < expected_size) {
- int bytes_left;
+ off_t bytes_left;
int chunk_size;
bytes_left = expected_size - bytes_sent;
if (bytes_left < xfer_size)
- chunk_size = bytes_left;
+ chunk_size = (int) bytes_left;
else
chunk_size = xfer_size;
ret = dfu_download(dif->dev_handle, dif->interface,
- chunk_size, transaction++, chunk_size ? buf : NULL);
+ chunk_size, transaction++, chunk_size ? buf : NULL);
if (ret < 0) {
- warnx("Error during download");
+ warnx("Error during download (%s)",
+ libusb_error_name(ret));
goto out;
}
bytes_sent += chunk_size;
@@ -128,7 +137,8 @@ int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
do {
ret = dfu_get_status(dif, &dst);
if (ret < 0) {
- errx(EX_IOERR, "Error during download get_status");
+ errx(EX_IOERR, "Error during download get_status (%s)",
+ libusb_error_name(ret));
goto out;
}
@@ -138,11 +148,14 @@ int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
/* Wait while device executes flashing */
milli_sleep(dst.bwPollTimeout);
+ if (verbose > 1)
+ fprintf(stderr, "Poll timeout %i ms\n", dst.bwPollTimeout);
} while (1);
+
if (dst.bStatus != DFU_STATUS_OK) {
printf(" failed!\n");
- printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
+ printf("DFU state(%u) = %s, status(%u) = %s\n", dst.bState,
dfu_state_to_string(dst.bState), dst.bStatus,
dfu_status_to_string(dst.bStatus));
ret = -1;
@@ -152,26 +165,27 @@ int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
}
/* send one zero sized download request to signalize end */
- ret = dfu_download(dif->dev_handle, dif->interface,
- 0, transaction, NULL);
+ ret = dfu_download(dif->dev_handle, dif->interface, 0, transaction, NULL);
if (ret < 0) {
- errx(EX_IOERR, "Error sending completion packet");
+ errx(EX_IOERR, "Error sending completion packet (%s)",
+ libusb_error_name(ret));
goto out;
}
dfu_progress_bar("Download", bytes_sent, bytes_sent);
if (verbose)
- printf("Sent a total of %i bytes\n", bytes_sent);
+ printf("Sent a total of %lli bytes\n", (long long) bytes_sent);
get_status:
/* Transition to MANIFEST_SYNC state */
ret = dfu_get_status(dif, &dst);
if (ret < 0) {
- warnx("unable to read DFU status after completion");
+ warnx("unable to read DFU status after completion (%s)",
+ libusb_error_name(ret));
goto out;
}
- printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
+ printf("DFU state(%u) = %s, status(%u) = %s\n", dst.bState,
dfu_state_to_string(dst.bState), dst.bStatus,
dfu_status_to_string(dst.bStatus));
@@ -186,11 +200,19 @@ get_status:
milli_sleep(1000);
goto get_status;
break;
+ case DFU_STATE_dfuMANIFEST_WAIT_RST:
+ printf("Resetting USB to switch back to runtime mode\n");
+ ret = libusb_reset_device(dif->dev_handle);
+ if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) {
+ fprintf(stderr, "error resetting after download (%s)\n",
+ libusb_error_name(ret));
+ }
+ break;
case DFU_STATE_dfuIDLE:
break;
}
printf("Done!\n");
out:
- return bytes_sent;
+ return ret;
}
diff --git a/src/dfu_util.c b/src/dfu_util.c
index fa3af58..b785428 100644
--- a/src/dfu_util.c
+++ b/src/dfu_util.c
@@ -4,6 +4,7 @@
* Written by Harald Welte <laforge@openmoko.org>
* Copyright 2007-2008 by OpenMoko, Inc.
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
+ * Copyright 2016-2019 Tormod Volden <debian.tormod@gmail.com>
*
* Based on existing code of dfu-programmer-0.4
*
@@ -22,6 +23,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -32,9 +37,7 @@
#include "dfu.h"
#include "usb_dfu.h"
#include "dfu_file.h"
-#include "dfu_load.h"
#include "dfu_util.h"
-#include "dfuse.h"
#include "quirks.h"
/*
@@ -71,6 +74,87 @@ static int find_descriptor(const uint8_t *desc_list, int list_len,
return -1;
}
+/*
+ * Get a string descriptor that's UTF-8 (or ASCII) encoded instead
+ * of UTF-16 encoded like the USB specification mandates. Some
+ * devices, like the GD32VF103, both violate the spec in this way
+ * and store important information in the serial number field. This
+ * function does NOT append a NUL terminator to its buffer, so you
+ * must use the returned length to ensure you stay within bounds.
+ */
+static int get_utf8_string_descriptor(libusb_device_handle *devh,
+ uint8_t desc_index, unsigned char *data, int length)
+{
+ unsigned char tbuf[255];
+ uint16_t langid;
+ int r, outlen;
+
+ /* get the language IDs and pick the first one */
+ r = libusb_get_string_descriptor(devh, 0, 0, tbuf, sizeof(tbuf));
+ if (r < 0) {
+ warnx("Failed to retrieve language identifiers");
+ return r;
+ }
+ if (r < 4 || tbuf[0] < 4 || tbuf[1] != LIBUSB_DT_STRING) { /* must have at least one ID */
+ warnx("Broken LANGID string descriptor");
+ return -1;
+ }
+ langid = tbuf[2] | (tbuf[3] << 8);
+
+ r = libusb_get_string_descriptor(devh, desc_index, langid, tbuf,
+ sizeof(tbuf));
+ if (r < 0) {
+ warnx("Failed to retrieve string descriptor %d", desc_index);
+ return r;
+ }
+ if (r < 2 || tbuf[0] < 2) {
+ warnx("String descriptor %d too short", desc_index);
+ return -1;
+ }
+ if (tbuf[1] != LIBUSB_DT_STRING) { /* sanity check */
+ warnx("Malformed string descriptor %d, type = 0x%02x", desc_index, tbuf[1]);
+ return -1;
+ }
+ if (tbuf[0] > r) { /* if short read, */
+ warnx("Patching string descriptor %d length (was %d, received %d)", desc_index, tbuf[0], r);
+ tbuf[0] = r; /* fix up descriptor length */
+ }
+
+ outlen = tbuf[0] - 2;
+ if (length < outlen)
+ outlen = length;
+
+ memcpy(data, tbuf + 2, outlen);
+
+ return outlen;
+}
+
+/*
+ * Similar to libusb_get_string_descriptor_ascii but will allow
+ * truncated descriptors (descriptor length mismatch) seen on
+ * e.g. the STM32F427 ROM bootloader.
+ */
+static int get_string_descriptor_ascii(libusb_device_handle *devh,
+ uint8_t desc_index, unsigned char *data, int length)
+{
+ unsigned char buf[255];
+ int r, di, si;
+
+ r = get_utf8_string_descriptor(devh, desc_index, buf, sizeof(buf));
+ if (r < 0)
+ return r;
+
+ /* convert from 16-bit unicode to ascii string */
+ for (di = 0, si = 0; si + 1 < r && di < length; si += 2) {
+ if (buf[si + 1]) /* high byte of unicode char */
+ data[di++] = '?';
+ else
+ data[di++] = buf[si];
+ }
+ data[di] = '\0';
+ return di;
+}
+
static void probe_configuration(libusb_device *dev, struct libusb_device_descriptor *desc)
{
struct usb_dfu_func_descriptor func_dfu;
@@ -173,6 +257,8 @@ found_dfu:
for (intf_idx = 0; intf_idx < cfg->bNumInterfaces;
intf_idx++) {
+ int multiple_alt;
+
if (match_iface_index > -1 && match_iface_index != intf_idx)
continue;
@@ -180,9 +266,15 @@ found_dfu:
if (!uif)
break;
+ multiple_alt = uif->num_altsetting > 0;
+
for (alt_idx = 0;
alt_idx < uif->num_altsetting; alt_idx++) {
int dfu_mode;
+ uint16_t quirks;
+
+ quirks = get_quirks(desc->idVendor,
+ desc->idProduct, desc->bcdDevice);
intf = &uif->altsetting[alt_idx];
@@ -199,8 +291,16 @@ found_dfu:
if (desc->idVendor == 0x1fc9 && desc->idProduct == 0x000c && intf->bInterfaceProtocol == 1)
dfu_mode = 1;
+ /*
+ * Old Jabra devices may have bInterfaceProtocol 0 instead of 2.
+ * Also runtime PID and DFU pid are the same.
+ * In DFU mode, the configuration descriptor has only 1 interface.
+ */
+ if (desc->idVendor == 0x0b0e && intf->bInterfaceProtocol == 0 && cfg->bNumInterfaces == 1)
+ dfu_mode = 1;
+
if (dfu_mode &&
- match_iface_alt_index > -1 && match_iface_alt_index != alt_idx)
+ match_iface_alt_index > -1 && match_iface_alt_index != intf->bAlternateSetting)
continue;
if (dfu_mode) {
@@ -215,22 +315,36 @@ found_dfu:
}
}
- if (libusb_open(dev, &devh)) {
- warnx("Cannot open DFU device %04x:%04x", desc->idVendor, desc->idProduct);
+ if (match_devnum >= 0 && match_devnum != libusb_get_device_address(dev))
+ continue;
+
+ ret = libusb_open(dev, &devh);
+ if (ret) {
+ warnx("Cannot open DFU device %04x:%04x found on devnum %i (%s)",
+ desc->idVendor, desc->idProduct, libusb_get_device_address(dev),
+ libusb_error_name(ret));
break;
}
if (intf->iInterface != 0)
- ret = libusb_get_string_descriptor_ascii(devh,
+ ret = get_string_descriptor_ascii(devh,
intf->iInterface, (void *)alt_name, MAX_DESC_STR_LEN);
else
ret = -1;
if (ret < 1)
strcpy(alt_name, "UNKNOWN");
- if (desc->iSerialNumber != 0)
- ret = libusb_get_string_descriptor_ascii(devh,
- desc->iSerialNumber, (void *)serial_name, MAX_DESC_STR_LEN);
- else
+ if (desc->iSerialNumber != 0) {
+ if (quirks & QUIRK_UTF8_SERIAL) {
+ ret = get_utf8_string_descriptor(devh, desc->iSerialNumber,
+ (void *)serial_name, MAX_DESC_STR_LEN - 1);
+ if (ret >= 0)
+ serial_name[ret] = '\0';
+ } else {
+ ret = get_string_descriptor_ascii(devh, desc->iSerialNumber,
+ (void *)serial_name, MAX_DESC_STR_LEN);
+ }
+ } else {
ret = -1;
+ }
if (ret < 1)
strcpy(serial_name, "UNKNOWN");
libusb_close(devh);
@@ -253,8 +367,7 @@ found_dfu:
pdfu->func_dfu = func_dfu;
pdfu->dev = libusb_ref_device(dev);
- pdfu->quirks = get_quirks(desc->idVendor,
- desc->idProduct, desc->bcdDevice);
+ pdfu->quirks = quirks;
pdfu->vendor = desc->idVendor;
pdfu->product = desc->idProduct;
pdfu->bcdDevice = desc->bcdDevice;
@@ -271,6 +384,8 @@ found_dfu:
errx(EX_SOFTWARE, "Out of memory");
if (dfu_mode)
pdfu->flags |= DFU_IFF_DFU;
+ if (multiple_alt)
+ pdfu->flags |= DFU_IFF_ALT;
if (pdfu->quirks & QUIRK_FORCE_DFU11) {
pdfu->func_dfu.bcdDFUVersion =
libusb_cpu_to_le16(0x0110);
@@ -291,6 +406,7 @@ char path_buf[MAX_PATH_LEN];
char *get_path(libusb_device *dev)
{
+#if (defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102) || (defined(LIBUSBX_API_VERSION) && LIBUSBX_API_VERSION >= 0x01000102)
uint8_t path[8];
int r,j;
r = libusb_get_port_numbers(dev, path, sizeof(path));
@@ -301,6 +417,11 @@ char *get_path(libusb_device *dev)
};
}
return path_buf;
+#else
+# warning "libusb too old - building without USB path support!"
+ (void)dev;
+ return NULL;
+#endif
}
void probe_devices(libusb_context *ctx)
@@ -320,7 +441,7 @@ void probe_devices(libusb_context *ctx)
continue;
probe_configuration(dev, &desc);
}
- libusb_free_device_list(list, 0);
+ libusb_free_device_list(list, 1);
}
void disconnect_devices(void)
diff --git a/src/dfu_util.h b/src/dfu_util.h
index c4e0375..ec8aa99 100644
--- a/src/dfu_util.h
+++ b/src/dfu_util.h
@@ -2,8 +2,8 @@
#define DFU_UTIL_H
/* 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
+ * but 254 would even accommodate a UTF-8 encoding + NUL terminator */
+#define MAX_DESC_STR_LEN 254
enum mode {
MODE_NONE,
@@ -23,6 +23,7 @@ extern int match_product_dfu;
extern int match_config_index;
extern int match_iface_index;
extern int match_iface_alt_index;
+extern int match_devnum;
extern const char *match_iface_alt_name;
extern const char *match_serial;
extern const char *match_serial_dfu;
diff --git a/src/dfuse.c b/src/dfuse.c
index 4a02511..17a62f6 100644
--- a/src/dfuse.c
+++ b/src/dfuse.c
@@ -5,7 +5,7 @@
* as per the DfuSe 1.1a specification (ST documents AN3156, AN2606)
* The DfuSe file format is described in ST document UM0391.
*
- * Copyright 2010-2014 Tormod Volden <debian.tormod@gmail.com>
+ * Copyright 2010-2018 Tormod Volden <debian.tormod@gmail.com>
*
* 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
@@ -22,6 +22,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -33,25 +37,27 @@
#include "dfu_file.h"
#include "dfuse.h"
#include "dfuse_mem.h"
+#include "quirks.h"
#define DFU_TIMEOUT 5000
extern int verbose;
static unsigned int last_erased_page = 1; /* non-aligned value, won't match */
-static struct memsegment *mem_layout;
static unsigned int dfuse_address = 0;
+static unsigned int dfuse_address_present = 0;
static unsigned int dfuse_length = 0;
static int dfuse_force = 0;
static int dfuse_leave = 0;
static int dfuse_unprotect = 0;
static int dfuse_mass_erase = 0;
+static int dfuse_will_reset = 0;
-unsigned int quad2uint(unsigned char *p)
+static unsigned int quad2uint(unsigned char *p)
{
return (*p + (*(p + 1) << 8) + (*(p + 2) << 16) + (*(p + 3) << 24));
}
-void dfuse_parse_options(const char *options)
+static void dfuse_parse_options(const char *options)
{
char *end;
const char *endword;
@@ -66,8 +72,9 @@ void dfuse_parse_options(const char *options)
number = strtoul(options, &end, 0);
if (end == endword) {
dfuse_address = number;
+ dfuse_address_present = 1;
} else {
- errx(EX_IOERR, "Invalid dfuse address: %s", options);
+ errx(EX_USAGE, "Invalid dfuse address: %s", options);
}
options = endword;
}
@@ -101,20 +108,25 @@ void dfuse_parse_options(const char *options)
options += 10;
continue;
}
+ if (!strncmp(options, "will-reset", endword - options)) {
+ dfuse_will_reset = 1;
+ options += 10;
+ continue;
+ }
/* any valid number is interpreted as upload length */
number = strtoul(options, &end, 0);
if (end == endword) {
dfuse_length = number;
} else {
- errx(EX_IOERR, "Invalid dfuse modifier: %s", options);
+ errx(EX_USAGE, "Invalid dfuse modifier: %s", options);
}
options = endword;
}
}
/* DFU_UPLOAD request for DfuSe 1.1a */
-int dfuse_upload(struct dfu_if *dif, const unsigned short length,
+static int dfuse_upload(struct dfu_if *dif, const unsigned short length,
unsigned char *data, unsigned short transaction)
{
int status;
@@ -130,14 +142,14 @@ int dfuse_upload(struct dfu_if *dif, const unsigned short length,
/* wLength */ length,
DFU_TIMEOUT);
if (status < 0) {
- errx(EX_IOERR, "%s: libusb_control_msg returned %d",
- __FUNCTION__, status);
+ warnx("dfuse_upload: libusb_control_transfer returned %d (%s)",
+ status, libusb_error_name(status));
}
return status;
}
/* DFU_DNLOAD request for DfuSe 1.1a */
-int dfuse_download(struct dfu_if *dif, const unsigned short length,
+static int dfuse_download(struct dfu_if *dif, const unsigned short length,
unsigned char *data, unsigned short transaction)
{
int status;
@@ -153,15 +165,18 @@ int dfuse_download(struct dfu_if *dif, const unsigned short length,
/* wLength */ length,
DFU_TIMEOUT);
if (status < 0) {
- errx(EX_IOERR, "%s: libusb_control_transfer returned %d",
- __FUNCTION__, status);
+ /* Silently fail on leave request on some unpredictable devices */
+ if ((dif->quirks & QUIRK_DFUSE_LEAVE) && !length && !data && transaction == 2)
+ return status;
+ warnx("dfuse_download: libusb_control_transfer returned %d (%s)",
+ status, libusb_error_name(status));
}
return status;
}
/* DfuSe only commands */
/* Leaves the device in dfuDNLOAD-IDLE state */
-int dfuse_special_command(struct dfu_if *dif, unsigned int address,
+static int dfuse_special_command(struct dfu_if *dif, unsigned int address,
enum dfuse_command command)
{
const char* dfuse_command_name[] = { "SET_ADDRESS" , "ERASE_PAGE",
@@ -171,27 +186,30 @@ int dfuse_special_command(struct dfu_if *dif, unsigned int address,
int ret;
struct dfu_status dst;
int firstpoll = 1;
+ int zerotimeouts = 0;
+ int polltimeout = 0;
+ int stalls = 0;
if (command == ERASE_PAGE) {
struct memsegment *segment;
int page_size;
- segment = find_segment(mem_layout, address);
+ segment = find_segment(dif->mem_layout, address);
if (!segment || !(segment->memtype & DFUSE_ERASABLE)) {
- errx(EX_IOERR, "Page at 0x%08x can not be erased",
+ errx(EX_USAGE, "Page at 0x%08x can not be erased",
address);
}
page_size = segment->pagesize;
- if (verbose > 1)
- printf("Erasing page size %i at address 0x%08x, page "
+ if (verbose)
+ fprintf(stderr, "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_page = address & ~(page_size - 1);
} else if (command == SET_ADDRESS) {
- if (verbose > 2)
- printf(" Setting address pointer to 0x%08x\n",
+ if (verbose > 1)
+ fprintf(stderr, " Setting address pointer to 0x%08x\n",
address);
buf[0] = 0x21; /* Set Address Pointer command */
length = 5;
@@ -202,7 +220,7 @@ int dfuse_special_command(struct dfu_if *dif, unsigned int address,
buf[0] = 0x92;
length = 1;
} else {
- errx(EX_IOERR, "Non-supported special command %d", command);
+ errx(EX_SOFTWARE, "Non-supported special command %d", command);
}
buf[1] = address & 0xff;
buf[2] = (address >> 8) & 0xff;
@@ -216,31 +234,47 @@ int dfuse_special_command(struct dfu_if *dif, unsigned int address,
}
do {
ret = dfu_get_status(dif, &dst);
- if (ret < 0) {
+ /* Workaround for some STM32L4 bootloaders that report a too
+ * short poll timeout and may stall the pipe when we poll */
+ if (ret == LIBUSB_ERROR_PIPE && polltimeout != 0 && stalls < 3) {
+ dst.bState = DFU_STATE_dfuDNBUSY;
+ stalls++;
+ if (verbose)
+ fprintf(stderr, "* Device stalled USB pipe, reusing last poll timeout\n");
+ } else if (ret < 0) {
errx(EX_IOERR, "Error during special command \"%s\" get_status",
dfuse_command_name[command]);
+ } else {
+ polltimeout = dst.bwPollTimeout;
}
if (firstpoll) {
firstpoll = 0;
if (dst.bState != DFU_STATE_dfuDNBUSY) {
- printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
+ fprintf(stderr, "DFU state(%u) = %s, status(%u) = %s\n", dst.bState,
dfu_state_to_string(dst.bState), dst.bStatus,
dfu_status_to_string(dst.bStatus));
- errx(EX_IOERR, "Wrong state after command \"%s\" download",
+ errx(EX_PROTOCOL, "Wrong state after command \"%s\" download",
dfuse_command_name[command]);
}
/* STM32F405 lies about mass erase timeout */
if (command == MASS_ERASE && dst.bwPollTimeout == 100) {
- dst.bwPollTimeout = 35000;
+ polltimeout = 35000; /* Datasheet says up to 32 seconds */
printf("Setting timeout to 35 seconds\n");
}
}
/* wait while command is executed */
- if (verbose)
- printf(" Poll timeout %i ms\n", dst.bwPollTimeout);
- milli_sleep(dst.bwPollTimeout);
+ if (verbose > 1)
+ fprintf(stderr, " Poll timeout %i ms\n", polltimeout);
+ milli_sleep(polltimeout);
if (command == READ_UNPROTECT)
return ret;
+ /* Workaround for e.g. Black Magic Probe getting stuck */
+ if (dst.bwPollTimeout == 0) {
+ if (++zerotimeouts == 100)
+ errx(EX_IOERR, "Device stuck after special command request");
+ } else {
+ zerotimeouts = 0;
+ }
} while (dst.bState == DFU_STATE_dfuDNBUSY);
if (dst.bStatus != DFU_STATUS_OK) {
@@ -250,7 +284,8 @@ int dfuse_special_command(struct dfu_if *dif, unsigned int address,
return ret;
}
-int dfuse_dnload_chunk(struct dfu_if *dif, unsigned char *data, int size,
+/* returns number of bytes sent */
+static int dfuse_dnload_chunk(struct dfu_if *dif, unsigned char *data, int size,
int transaction)
{
int bytes_sent;
@@ -273,14 +308,15 @@ int dfuse_dnload_chunk(struct dfu_if *dif, unsigned char *data, int size,
milli_sleep(dst.bwPollTimeout);
} while (dst.bState != DFU_STATE_dfuDNLOAD_IDLE &&
dst.bState != DFU_STATE_dfuERROR &&
- dst.bState != DFU_STATE_dfuMANIFEST);
+ dst.bState != DFU_STATE_dfuMANIFEST &&
+ !(dfuse_will_reset && (dst.bState == DFU_STATE_dfuDNBUSY)));
if (dst.bState == DFU_STATE_dfuMANIFEST)
printf("Transitioning to dfuMANIFEST state\n");
if (dst.bStatus != DFU_STATUS_OK) {
printf(" failed!\n");
- printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
+ fprintf(stderr, "DFU 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;
@@ -288,6 +324,22 @@ int dfuse_dnload_chunk(struct dfu_if *dif, unsigned char *data, int size,
return bytes_sent;
}
+static void dfuse_do_leave(struct dfu_if *dif)
+{
+ if (dfuse_address_present)
+ dfuse_special_command(dif, dfuse_address, SET_ADDRESS);
+ printf("Submitting leave request...\n");
+ if (dif->quirks & QUIRK_DFUSE_LEAVE) {
+ struct dfu_status dst;
+ /* The device might leave after this request, with or without a response */
+ dfuse_download(dif, 0, NULL, 2);
+ /* Or it might leave after this request, with or without a response */
+ dfu_get_status(dif, &dst);
+ } else {
+ dfuse_dnload_chunk(dif, NULL, 0, 2);
+ }
+}
+
int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd,
const char *dfuse_options)
{
@@ -303,31 +355,41 @@ int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd,
dfuse_parse_options(dfuse_options);
if (dfuse_length)
upload_limit = dfuse_length;
- if (dfuse_address) {
- struct memsegment *segment;
+ if (dfuse_address_present) {
+ struct memsegment *mem_layout, *segment;
mem_layout = parse_memory_layout((char *)dif->alt_name);
if (!mem_layout)
errx(EX_IOERR, "Failed to parse memory layout");
+ if (dif->quirks & QUIRK_DFUSE_LAYOUT)
+ fixup_dfuse_layout(dif, &mem_layout);
segment = find_segment(mem_layout, dfuse_address);
if (!dfuse_force &&
(!segment || !(segment->memtype & DFUSE_READABLE)))
- errx(EX_IOERR, "Page at 0x%08x is not readable",
+ errx(EX_USAGE, "Page at 0x%08x is not readable",
dfuse_address);
if (!upload_limit) {
- upload_limit = segment->end - dfuse_address + 1;
- printf("Limiting upload to end of memory segment, "
- "%i bytes\n", upload_limit);
+ if (segment) {
+ upload_limit = segment->end - dfuse_address + 1;
+ printf("Limiting upload to end of memory segment, "
+ "%i bytes\n", upload_limit);
+ } else {
+ /* unknown segment - i.e. "force" has been used */
+ upload_limit = 0x4000;
+ printf("Limiting upload to %i bytes\n", upload_limit);
+ }
}
dfuse_special_command(dif, dfuse_address, SET_ADDRESS);
dfu_abort_to_idle(dif);
} else {
/* Boot loader decides the start address, unknown to us */
/* Use a short length to lower risk of running out of bounds */
- if (!upload_limit)
+ if (!upload_limit) {
+ warnx("Unbound upload not supported on DfuSe devices");
upload_limit = 0x4000;
+ }
printf("Limiting default upload to %i bytes\n", upload_limit);
}
@@ -354,7 +416,7 @@ int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd,
if (rc < xfer_size || total_bytes >= upload_limit) {
/* last block, return successfully */
- ret = total_bytes;
+ ret = 0;
break;
}
dfu_progress_bar("Upload", total_bytes, upload_limit);
@@ -363,10 +425,8 @@ int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd,
dfu_progress_bar("Upload", total_bytes, total_bytes);
dfu_abort_to_idle(dif);
- if (dfuse_leave) {
- dfuse_special_command(dif, dfuse_address, SET_ADDRESS);
- dfuse_dnload_chunk(dif, NULL, 0, 2); /* Zero-size */
- }
+ if (dfuse_leave)
+ dfuse_do_leave(dif);
out_free:
free(buf);
@@ -376,7 +436,7 @@ int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd,
/* 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,
+static int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddress,
unsigned int dwElementSize, unsigned char *data,
int xfer_size)
{
@@ -386,25 +446,34 @@ int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddress,
/* 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)) {
- errx(EX_IOERR, "Last page at 0x%08x is not writeable",
+ find_segment(dif->mem_layout, dwElementAddress + dwElementSize - 1);
+ if (!dfuse_force &&
+ (!segment || !(segment->memtype & DFUSE_WRITEABLE))) {
+ errx(EX_USAGE, "Last page at 0x%08x is not writeable",
dwElementAddress + dwElementSize - 1);
}
- dfu_progress_bar("Download", 0, 1);
+ if (!verbose)
+ dfu_progress_bar("Erase ", 0, 1);
+ /* First pass: Erase involved pages if needed */
for (p = 0; p < (int)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)) {
- errx(EX_IOERR, "Page at 0x%08x is not writeable",
+ segment = find_segment(dif->mem_layout, address);
+ if (!dfuse_force &&
+ (!segment || !(segment->memtype & DFUSE_WRITEABLE))) {
+ errx(EX_USAGE, "Page at 0x%08x is not writeable",
address);
}
+ /* If the location is not in the memory map we skip erasing */
+ /* since we wouldn't know the correct page size for flash erase */
+ if (!segment)
+ continue;
+
page_size = segment->pagesize;
/* check if this is the last chunk */
@@ -425,17 +494,33 @@ int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddress,
if (((address + chunk_size - 1) & ~(page_size - 1)) !=
last_erased_page) {
- if (verbose > 2)
- printf(" Chunk extends into next page,"
+ if (verbose > 1)
+ fprintf(stderr, " Chunk extends into next page,"
" erase it as well\n");
dfuse_special_command(dif,
address + chunk_size - 1,
ERASE_PAGE);
}
+ if (!verbose)
+ dfu_progress_bar("Erase ", p, dwElementSize);
}
+ }
+ if (!verbose)
+ dfu_progress_bar("Erase ", dwElementSize, dwElementSize);
+ if (!verbose)
+ dfu_progress_bar("Download", 0, 1);
+
+ /* Second pass: Write data to (erased) pages */
+ for (p = 0; p < (int)dwElementSize; p += xfer_size) {
+ unsigned int address = dwElementAddress + p;
+ int chunk_size = xfer_size;
+
+ /* check if this is the last chunk */
+ if (p + chunk_size > (int)dwElementSize)
+ chunk_size = dwElementSize - p;
if (verbose) {
- printf(" Download from image offset "
+ fprintf(stderr, " Download from image offset "
"%08x to memory %08x-%08x, size %i\n",
p, address, address + chunk_size - 1,
chunk_size);
@@ -462,7 +547,7 @@ static void
dfuse_memcpy(unsigned char *dst, unsigned char **src, int *rem, int size)
{
if (size > *rem) {
- errx(EX_IOERR, "Corrupt DfuSe file: "
+ errx(EX_NOINPUT, "Corrupt DfuSe file: "
"Cannot read %d bytes from %d bytes", size, *rem);
}
if (dst != NULL)
@@ -472,7 +557,7 @@ dfuse_memcpy(unsigned char *dst, unsigned char **src, int *rem, int size)
}
/* Download raw binary file to DfuSe device */
-int dfuse_do_bin_dnload(struct dfu_if *dif, int xfer_size,
+static int dfuse_do_bin_dnload(struct dfu_if *dif, int xfer_size,
struct dfu_file *file, unsigned int start_address)
{
unsigned int dwElementAddress;
@@ -484,25 +569,21 @@ int dfuse_do_bin_dnload(struct dfu_if *dif, int xfer_size,
dwElementSize = file->size.total -
file->size.suffix - file->size.prefix;
- printf("Downloading to address = 0x%08x, size = %i\n",
+ printf("Downloading element to address = 0x%08x, size = %i\n",
dwElementAddress, dwElementSize);
data = file->firmware + file->size.prefix;
ret = dfuse_dnload_element(dif, dwElementAddress, dwElementSize, data,
xfer_size);
- if (ret != 0)
- goto out_free;
+ if (ret == 0)
+ printf("File downloaded successfully\n");
- printf("File downloaded successfully\n");
- ret = dwElementSize;
-
- out_free:
return ret;
}
/* Parse a DfuSe file and download contents to device */
-int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
+static int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
struct dfu_file *file)
{
uint8_t dfuprefix[11];
@@ -512,6 +593,7 @@ int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
int element;
int bTargets;
int bAlternateSetting;
+ struct dfu_if *adif;
int dwNbElements;
unsigned int dwElementAddress;
unsigned int dwElementSize;
@@ -526,43 +608,65 @@ int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
/* Must be larger than a minimal DfuSe header and suffix */
if (rem < (int)(sizeof(dfuprefix) +
sizeof(targetprefix) + sizeof(elementheader))) {
- errx(EX_SOFTWARE, "File too small for a DfuSe file");
+ errx(EX_DATAERR, "File too small for a DfuSe file");
}
dfuse_memcpy(dfuprefix, &data, &rem, sizeof(dfuprefix));
if (strncmp((char *)dfuprefix, "DfuSe", 5)) {
- errx(EX_IOERR, "No valid DfuSe signature");
+ errx(EX_DATAERR, "No valid DfuSe signature");
return -EINVAL;
}
if (dfuprefix[5] != 0x01) {
- errx(EX_IOERR, "DFU format revision %i not supported",
+ errx(EX_DATAERR, "DFU format revision %i not supported",
dfuprefix[5]);
return -EINVAL;
}
bTargets = dfuprefix[10];
- printf("file contains %i DFU images\n", bTargets);
+ printf("File contains %i DFU images\n", bTargets);
for (image = 1; image <= bTargets; image++) {
- printf("parsing DFU image %i\n", image);
+ printf("Parsing DFU image %i\n", image);
dfuse_memcpy(targetprefix, &data, &rem, sizeof(targetprefix));
if (strncmp((char *)targetprefix, "Target", 6)) {
- errx(EX_IOERR, "No valid target signature");
+ errx(EX_DATAERR, "No valid target signature");
return -EINVAL;
}
bAlternateSetting = targetprefix[6];
+ if (targetprefix[7])
+ printf("Target name: %s\n", &targetprefix[11]);
+ else
+ printf("No target name\n");
dwNbElements = quad2uint((unsigned char *)targetprefix + 270);
- printf("image for alternate setting %i, ", bAlternateSetting);
+ 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");
+
+ adif = dif;
+ while (adif) {
+ if (bAlternateSetting == adif->altsetting) {
+ adif->dev_handle = dif->dev_handle;
+ printf("Setting Alternate Interface #%d ...\n",
+ adif->altsetting);
+ ret = libusb_set_interface_alt_setting(
+ adif->dev_handle,
+ adif->interface, adif->altsetting);
+ if (ret < 0) {
+ errx(EX_IOERR,
+ "Cannot set alternate interface: %s",
+ libusb_error_name(ret));
+ }
+ break;
+ }
+ adif = adif->next;
+ }
+ if (!adif)
+ warnx("No alternate setting %d (skipping elements)",
+ bAlternateSetting);
+
for (element = 1; element <= dwNbElements; element++) {
- printf("parsing element %i, ", element);
+ printf("Parsing element %i, ", element);
dfuse_memcpy(elementheader, &data, &rem, sizeof(elementheader));
dwElementAddress =
quad2uint((unsigned char *)elementheader);
@@ -577,14 +681,13 @@ int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
}
/* sanity check */
if ((int)dwElementSize > rem)
- errx(EX_SOFTWARE, "File too small for element size");
+ errx(EX_DATAERR, "File too small for element size");
- if (bAlternateSetting == dif->altsetting) {
- ret = dfuse_dnload_element(dif, dwElementAddress,
- dwElementSize, data, xfer_size);
- } else {
+ if (adif)
+ ret = dfuse_dnload_element(adif, dwElementAddress,
+ dwElementSize, data, xfer_size);
+ else
ret = 0;
- }
/* advance read pointer */
dfuse_memcpy(NULL, &data, &rem, dwElementSize);
@@ -597,7 +700,7 @@ int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
if (rem != 0)
warnx("%d bytes leftover", rem);
- printf("done parsing DfuSe file\n");
+ printf("Done parsing DfuSe file\n");
return 0;
}
@@ -606,52 +709,89 @@ int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file,
const char *dfuse_options)
{
int ret;
+ struct dfu_if *adif;
if (dfuse_options)
dfuse_parse_options(dfuse_options);
- mem_layout = parse_memory_layout((char *)dif->alt_name);
- if (!mem_layout) {
- errx(EX_IOERR, "Failed to parse memory layout");
+
+ adif = dif;
+ while (adif) {
+ adif->mem_layout = parse_memory_layout((char *)adif->alt_name);
+ if (!adif->mem_layout)
+ errx(EX_IOERR,
+ "Failed to parse memory layout for alternate interface %i",
+ adif->altsetting);
+ if (adif->quirks & QUIRK_DFUSE_LAYOUT)
+ fixup_dfuse_layout(adif, &(adif->mem_layout));
+ adif = adif->next;
}
+
if (dfuse_unprotect) {
if (!dfuse_force) {
- errx(EX_IOERR, "The read unprotect command "
+ errx(EX_USAGE, "The read unprotect command "
"will erase the flash memory"
"and can only be used with force\n");
}
- dfuse_special_command(dif, 0, READ_UNPROTECT);
+ ret = dfuse_special_command(dif, 0, READ_UNPROTECT);
printf("Device disconnects, erases flash and resets now\n");
- exit(0);
+ return ret;
}
if (dfuse_mass_erase) {
if (!dfuse_force) {
- errx(EX_IOERR, "The mass erase command "
+ errx(EX_USAGE, "The mass erase command "
"can only be used with force");
}
printf("Performing mass erase, this can take a moment\n");
- dfuse_special_command(dif, 0, MASS_ERASE);
+ ret = dfuse_special_command(dif, 0, MASS_ERASE);
}
- if (dfuse_address) {
+ if (!file->name) {
+ printf("DfuSe command mode\n");
+ ret = 0;
+ } else if (dfuse_address_present) {
if (file->bcdDFU == 0x11a) {
- errx(EX_IOERR, "This is a DfuSe file, not "
+ errx(EX_USAGE, "This is a DfuSe file, not "
"meant for raw download");
}
ret = dfuse_do_bin_dnload(dif, xfer_size, file, dfuse_address);
} else {
if (file->bcdDFU != 0x11a) {
warnx("Only DfuSe file version 1.1a is supported");
- errx(EX_IOERR, "(for raw binary download, use the "
+ errx(EX_USAGE, "(for raw binary download, use the "
"--dfuse-address option)");
}
ret = dfuse_do_dfuse_dnload(dif, xfer_size, file);
}
- free_segment_list(mem_layout);
- dfu_abort_to_idle(dif);
+ adif = dif;
+ while (adif) {
+ free_segment_list(adif->mem_layout);
+ adif = adif->next;
+ }
- if (dfuse_leave) {
- dfuse_special_command(dif, dfuse_address, SET_ADDRESS);
- dfuse_dnload_chunk(dif, NULL, 0, 2); /* Zero-size */
+ if (!dfuse_will_reset) {
+ dfu_abort_to_idle(dif);
}
+
+ if (dfuse_leave)
+ dfuse_do_leave(dif);
+
return ret;
}
+
+/* Check if we have one interface, possibly multiple alternate interfaces */
+int dfuse_multiple_alt(struct dfu_if *dfu_root)
+{
+ libusb_device *dev = dfu_root->dev;
+ uint8_t configuration = dfu_root->configuration;
+ uint8_t interface = dfu_root->interface;
+ struct dfu_if *dif = dfu_root->next;
+
+ while (dif) {
+ if (dev != dif->dev ||
+ configuration != dif->configuration ||
+ interface != dif->interface)
+ return 0;
+ dif = dif->next;
+ }
+ return 1;
+}
diff --git a/src/dfuse.h b/src/dfuse.h
index ed1108c..bcb707a 100644
--- a/src/dfuse.h
+++ b/src/dfuse.h
@@ -25,11 +25,10 @@
enum dfuse_command { SET_ADDRESS, ERASE_PAGE, MASS_ERASE, READ_UNPROTECT };
-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, int fd,
const char *dfuse_options);
int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file,
const char *dfuse_options);
+int dfuse_multiple_alt(struct dfu_if *dfu_root);
#endif /* DFUSE_H */
diff --git a/src/dfuse_mem.c b/src/dfuse_mem.c
index a91aacf..867b443 100644
--- a/src/dfuse_mem.c
+++ b/src/dfuse_mem.c
@@ -19,6 +19,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -156,7 +160,8 @@ struct memsegment *parse_memory_layout(char *intf_desc)
memtype = multiplier;
break;
}
- /* fallthrough if memtype was already set */
+ /* if memtype was already set: */
+ /* fall-through */
default:
warnx("Non-valid multiplier '%c', "
"assuming bytes", multiplier);
diff --git a/src/main.c b/src/main.c
index 06ca189..962c2a1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,10 +2,11 @@
* dfu-util
*
* Copyright 2007-2008 by OpenMoko, Inc.
- * Copyright 2010-2016 Tormod Volden and Stefan Schmidt
+ * Copyright 2010-2012 Stefan Schmidt
* Copyright 2013-2014 Hans Petter Selasky <hps@bitfrost.no>
+ * Copyright 2010-2021 Tormod Volden
*
- * Written by Harald Welte <laforge@openmoko.org>
+ * Originally written by Harald Welte <laforge@openmoko.org>
*
* Based on existing code of dfu-programmer-0.4
*
@@ -24,6 +25,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -35,12 +40,10 @@
#include "portable.h"
#include "dfu.h"
-#include "usb_dfu.h"
#include "dfu_file.h"
#include "dfu_load.h"
#include "dfu_util.h"
#include "dfuse.h"
-#include "quirks.h"
int verbose = 0;
@@ -54,6 +57,7 @@ int match_product_dfu = -1;
int match_config_index = -1;
int match_iface_index = -1;
int match_iface_alt_index = -1;
+int match_devnum = -1;
const char *match_iface_alt_name = NULL;
const char *match_serial = NULL;
const char *match_serial_dfu = NULL;
@@ -149,11 +153,11 @@ static int parse_number(char *str, char *nmb)
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
|| (errno != 0 && val == 0) || (*endptr != '\0')) {
- errx(EX_SOFTWARE, "Something went wrong with the argument of --%s\n", str);
+ errx(EX_USAGE, "Something went wrong with the argument of --%s\n", str);
}
- if (endptr == str) {
- errx(EX_SOFTWARE, "No digits were found from the argument of --%s\n", str);
+ if (endptr == nmb) {
+ errx(EX_USAGE, "No digits were found from the argument of --%s\n", str);
}
return (int)val;
@@ -170,6 +174,7 @@ static void help(void)
" -E --detach-delay seconds\tTime to wait before reopening a device after detach\n"
" -d --device <vendor>:<product>[,<vendor_dfu>:<product_dfu>]\n"
"\t\t\t\tSpecify Vendor/Product ID(s) of DFU device\n"
+ " -n --devnum <dnum>\t\tMatch given device number (devnum from --list)\n"
" -p --path <bus-port. ... .port>\tSpecify path to DFU device\n"
" -c --cfg <config_nr>\t\tSpecify the Configuration of DFU device\n"
" -i --intf <intf_nr>\t\tSpecify the DFU Interface number\n"
@@ -182,18 +187,25 @@ static void help(void)
" -Z --upload-size <bytes>\tSpecify the expected upload size in bytes\n"
" -D --download <file>\t\tWrite firmware from <file> 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"
+ " -w --wait\t\t\tWait for device to appear\n"
+ " -s --dfuse-address address<:...>\tST DfuSe mode string, specifying target\n"
+ "\t\t\t\taddress for raw file download or upload (not\n"
+ "\t\t\t\tapplicable for DfuSe file (.dfu) downloads).\n"
+ "\t\t\t\tAdd more DfuSe options separated with ':'\n"
+ "\t\tleave\t\tLeave DFU mode (jump to application)\n"
+ "\t\tmass-erase\tErase the whole device (requires \"force\")\n"
+ "\t\tunprotect\tErase read protected device (requires \"force\")\n"
+ "\t\twill-reset\tExpect device to reset (e.g. option bytes write)\n"
+ "\t\tforce\t\tYou really know what you are doing!\n"
+ "\t\t<length>\tLength of firmware to upload from device\n"
);
- exit(EX_USAGE);
}
static void print_version(void)
{
printf(PACKAGE_STRING "\n\n");
printf("Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.\n"
- "Copyright 2010-2016 Tormod Volden and Stefan Schmidt\n"
+ "Copyright 2010-2021 Tormod Volden and Stefan Schmidt\n"
"This program is Free Software and has ABSOLUTELY NO WARRANTY\n"
"Please report bugs to " PACKAGE_BUGREPORT "\n\n");
}
@@ -220,6 +232,8 @@ static struct option opts[] = {
{ "download", 1, 0, 'D' },
{ "reset", 0, 0, 'R' },
{ "dfuse-address", 1, 0, 's' },
+ { "devnum",1, 0, 'n' },
+ { "wait", 1, 0, 'w' },
{ 0, 0, 0, 0 }
};
@@ -233,6 +247,7 @@ int main(int argc, char **argv)
struct dfu_file file;
char *end;
int final_reset = 0;
+ int wait_device = 0;
int ret;
int dfuse_device = 0;
int fd;
@@ -248,7 +263,7 @@ int main(int argc, char **argv)
while (1) {
int c, option_index = 0;
- c = getopt_long(argc, argv, "hVvleE:d:p:c:i:a:S:t:U:D:Rs:Z:", opts,
+ c = getopt_long(argc, argv, "hVvleE:d:p:c:i:a:S:t:U:D:Rs:Z:wn:", opts,
&option_index);
if (c == -1)
break;
@@ -256,6 +271,7 @@ int main(int argc, char **argv)
switch (c) {
case 'h':
help();
+ exit(EX_OK);
break;
case 'V':
mode = MODE_VERSION;
@@ -276,7 +292,11 @@ int main(int argc, char **argv)
parse_vendprod(optarg);
break;
case 'p':
+#if (defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102) || (defined(LIBUSBX_API_VERSION) && LIBUSBX_API_VERSION >= 0x01000102)
match_path = optarg;
+#else
+ errx(EX_SOFTWARE, "This dfu-util was built without USB path support");
+#endif
break;
case 'c':
/* Configuration */
@@ -294,6 +314,9 @@ int main(int argc, char **argv)
match_iface_alt_index = -1;
}
break;
+ case 'n':
+ match_devnum = atoi(optarg);
+ break;
case 'S':
parse_serial(optarg);
break;
@@ -317,20 +340,41 @@ int main(int argc, char **argv)
case 's':
dfuse_options = optarg;
break;
+ case 'w':
+ wait_device = 1;
+ break;
default:
help();
+ exit(EX_USAGE);
break;
}
}
+ if (optind != argc) {
+ fprintf(stderr, "Error: Unexpected argument: %s\n\n", argv[optind]);
+ help();
+ exit(EX_USAGE);
+ }
print_version();
if (mode == MODE_VERSION) {
- exit(0);
+ exit(EX_OK);
}
- if (mode == MODE_NONE) {
+#if defined(LIBUSB_API_VERSION) || defined(LIBUSBX_API_VERSION)
+ if (verbose) {
+ const struct libusb_version *ver;
+ ver = libusb_get_version();
+ printf("libusb version %i.%i.%i%s (%i)\n", ver->major,
+ ver->minor, ver->micro, ver->rc, ver->nano);
+ }
+#else
+ warnx("libusb version is ancient");
+#endif
+
+ if (mode == MODE_NONE && !dfuse_options) {
fprintf(stderr, "You need to specify one of -D or -U\n");
help();
+ exit(EX_USAGE);
}
if (match_config_index == 0) {
@@ -350,25 +394,49 @@ int main(int argc, char **argv)
match_product = file.idProduct;
printf("Match product ID from file: %04x\n", match_product);
}
+ } else if (mode == MODE_NONE && dfuse_options) {
+ /* for DfuSe special commands, match any device */
+ mode = MODE_DOWNLOAD;
+ file.idVendor = 0xffff;
+ file.idProduct = 0xffff;
+ }
+
+ if (wait_device) {
+ printf("Waiting for device, exit with ctrl-C\n");
}
ret = libusb_init(&ctx);
if (ret)
- errx(EX_IOERR, "unable to initialize libusb: %i", ret);
+ errx(EX_IOERR, "unable to initialize libusb: %s", libusb_error_name(ret));
if (verbose > 2) {
+#if defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000106
+ libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
+#else
libusb_set_debug(ctx, 255);
+#endif
}
-
+probe:
probe_devices(ctx);
if (mode == MODE_LIST) {
list_dfu_interfaces();
- exit(0);
+ disconnect_devices();
+ libusb_exit(ctx);
+ return EX_OK;
}
if (dfu_root == NULL) {
- errx(EX_IOERR, "No DFU capable USB device available");
+ if (wait_device) {
+ milli_sleep(20);
+ goto probe;
+ } else {
+ warnx("No DFU capable USB device available");
+ libusb_exit(ctx);
+ return EX_IOERR;
+ }
+ } else if (file.bcdDFU == 0x11a && dfuse_multiple_alt(dfu_root)) {
+ printf("Multiple alternate interfaces for DfuSe file\n");
} else if (dfu_root->next != NULL) {
/* We cannot safely support more than one DFU capable device
* with same vendor/product ID, since during DFU we need to do
@@ -384,13 +452,32 @@ int main(int argc, char **argv)
printf("Opening DFU capable USB device...\n");
ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle);
if (ret || !dfu_root->dev_handle)
- errx(EX_IOERR, "Cannot open device");
+ errx(EX_IOERR, "Cannot open device: %s", libusb_error_name(ret));
- printf("ID %04x:%04x\n", dfu_root->vendor, dfu_root->product);
+ printf("Device ID %04x:%04x\n", dfu_root->vendor, dfu_root->product);
- printf("Run-time device DFU version %04x\n",
+ /* If first interface is DFU it is likely not proper run-time */
+ if (dfu_root->interface > 0)
+ printf("Run-Time device");
+ else
+ printf("Device");
+ printf(" DFU version %04x\n",
libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion));
+ if (verbose) {
+ printf("DFU attributes: (0x%02x)", dfu_root->func_dfu.bmAttributes);
+ if (dfu_root->func_dfu.bmAttributes & USB_DFU_CAN_DOWNLOAD)
+ printf(" bitCanDnload");
+ if (dfu_root->func_dfu.bmAttributes & USB_DFU_CAN_UPLOAD)
+ printf(" bitCanUpload");
+ if (dfu_root->func_dfu.bmAttributes & USB_DFU_MANIFEST_TOL)
+ printf(" bitManifestationTolerant");
+ if (dfu_root->func_dfu.bmAttributes & USB_DFU_WILL_DETACH)
+ printf(" bitWillDetach");
+ printf("\n");
+ printf("Detach timeout %d ms\n", libusb_le16_to_cpu(dfu_root->func_dfu.wDetachTimeOut));
+ }
+
/* Transition from run-Time mode to DFU mode */
if (!(dfu_root->flags & DFU_IFF_DFU)) {
int err;
@@ -402,18 +489,26 @@ int main(int argc, char **argv)
runtime_vendor = dfu_root->vendor;
runtime_product = dfu_root->product;
- printf("Claiming USB DFU Runtime Interface...\n");
- if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) {
- errx(EX_IOERR, "Cannot claim interface %d",
- dfu_root->interface);
+ printf("Claiming USB DFU (Run-Time) Interface...\n");
+ ret = libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface);
+ if (ret < 0) {
+ errx(EX_IOERR, "Cannot claim interface %d: %s",
+ dfu_root->interface, libusb_error_name(ret));
}
- if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, 0) < 0) {
- errx(EX_IOERR, "Cannot set alt interface zero");
+ /* Needed for some devices where the DFU interface is not the first,
+ * and should also be safe if there are multiple alt settings.
+ * Otherwise skip the request since it might not be supported
+ * by the device and the USB stack may or may not recover */
+ if (dfu_root->interface > 0 || dfu_root->flags & DFU_IFF_ALT) {
+ printf("Setting Alternate Interface zero...\n");
+ ret = libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, 0);
+ if (ret < 0) {
+ errx(EX_IOERR, "Cannot set alternate interface zero: %s", libusb_error_name(ret));
+ }
}
- printf("Determining device status: ");
-
+ printf("Determining device status...\n");
err = dfu_get_status(dfu_root, &status);
if (err == LIBUSB_ERROR_PIPE) {
printf("Device does not implement get_status, assuming appIDLE\n");
@@ -422,17 +517,18 @@ int main(int argc, char **argv)
status.bState = DFU_STATE_appIDLE;
status.iString = 0;
} else if (err < 0) {
- errx(EX_IOERR, "error get_status");
+ errx(EX_IOERR, "error get_status: %s", libusb_error_name(err));
} else {
- printf("state = %s, status = %d\n",
- dfu_state_to_string(status.bState), status.bStatus);
+ printf("DFU state(%u) = %s, status(%u) = %s\n", status.bState,
+ dfu_state_to_string(status.bState), status.bStatus,
+ dfu_status_to_string(status.bStatus));
}
milli_sleep(status.bwPollTimeout);
switch (status.bState) {
case DFU_STATE_appIDLE:
case DFU_STATE_appDETACH:
- printf("Device really in Runtime Mode, send DFU "
+ printf("Device really in Run-Time Mode, send DFU "
"detach request...\n");
if (dfu_detach(dfu_root->dev_handle,
dfu_root->interface, 1000) < 0) {
@@ -445,7 +541,7 @@ int main(int argc, char **argv)
ret = libusb_reset_device(dfu_root->dev_handle);
if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND)
errx(EX_IOERR, "error resetting "
- "after detach");
+ "after detach: %s", libusb_error_name(ret));
}
break;
case DFU_STATE_dfuERROR:
@@ -456,7 +552,8 @@ int main(int argc, char **argv)
}
/* fall through */
default:
- warnx("WARNING: Runtime device already in DFU state ?!?");
+ warnx("WARNING: Device already in DFU mode? (bState=%d %s)",
+ status.bState, dfu_state_to_string(status.bState));
libusb_release_interface(dfu_root->dev_handle,
dfu_root->interface);
goto dfustate;
@@ -466,14 +563,14 @@ int main(int argc, char **argv)
libusb_close(dfu_root->dev_handle);
dfu_root->dev_handle = NULL;
+ /* keeping handles open might prevent re-enumeration */
+ disconnect_devices();
+
if (mode == MODE_DETACH) {
libusb_exit(ctx);
- exit(0);
+ return EX_OK;
}
- /* keeping handles open might prevent re-enumeration */
- disconnect_devices();
-
milli_sleep(detach_delay * 1000);
/* Change match vendor and product to impossible values to force
@@ -492,7 +589,7 @@ int main(int argc, char **argv)
/* Check for DFU mode device */
if (!(dfu_root->flags | DFU_IFF_DFU))
- errx(EX_SOFTWARE, "Device is not in DFU mode");
+ errx(EX_PROTOCOL, "Device is not in DFU mode");
printf("Opening DFU USB Device...\n");
ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle);
@@ -511,37 +608,44 @@ int main(int argc, char **argv)
dfustate:
#if 0
printf("Setting Configuration %u...\n", dfu_root->configuration);
- if (libusb_set_configuration(dfu_root->dev_handle, dfu_root->configuration) < 0) {
- errx(EX_IOERR, "Cannot set configuration");
+ ret = libusb_set_configuration(dfu_root->dev_handle, dfu_root->configuration);
+ if (ret < 0) {
+ errx(EX_IOERR, "Cannot set configuration: %s", libusb_error_name(ret));
}
#endif
printf("Claiming USB DFU Interface...\n");
- if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) {
- errx(EX_IOERR, "Cannot claim interface");
+ ret = libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface);
+ if (ret < 0) {
+ errx(EX_IOERR, "Cannot claim interface - %s", libusb_error_name(ret));
}
- printf("Setting Alternate Setting #%d ...\n", dfu_root->altsetting);
- if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, dfu_root->altsetting) < 0) {
- errx(EX_IOERR, "Cannot set alternate interface");
+ if (dfu_root->flags & DFU_IFF_ALT) {
+ printf("Setting Alternate Interface #%d ...\n", dfu_root->altsetting);
+ ret = libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, dfu_root->altsetting);
+ if (ret < 0) {
+ errx(EX_IOERR, "Cannot set alternate interface: %s", libusb_error_name(ret));
+ }
}
status_again:
- printf("Determining device status: ");
- if (dfu_get_status(dfu_root, &status ) < 0) {
- errx(EX_IOERR, "error get_status");
+ printf("Determining device status...\n");
+ ret = dfu_get_status(dfu_root, &status );
+ if (ret < 0) {
+ errx(EX_IOERR, "error get_status: %s", libusb_error_name(ret));
}
- printf("state = %s, status = %d\n",
- dfu_state_to_string(status.bState), status.bStatus);
+ printf("DFU state(%u) = %s, status(%u) = %s\n", status.bState,
+ dfu_state_to_string(status.bState), status.bStatus,
+ dfu_status_to_string(status.bStatus));
milli_sleep(status.bwPollTimeout);
switch (status.bState) {
case DFU_STATE_appIDLE:
case DFU_STATE_appDETACH:
- errx(EX_IOERR, "Device still in Runtime Mode!");
+ errx(EX_PROTOCOL, "Device still in Run-Time Mode!");
break;
case DFU_STATE_dfuERROR:
- printf("dfuERROR, clearing status\n");
+ printf("Clearing status\n");
if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0) {
errx(EX_IOERR, "error clear_status");
}
@@ -549,15 +653,13 @@ status_again:
break;
case DFU_STATE_dfuDNLOAD_IDLE:
case DFU_STATE_dfuUPLOAD_IDLE:
- printf("aborting previous incomplete transfer\n");
+ printf("Aborting previous incomplete transfer\n");
if (dfu_abort(dfu_root->dev_handle, dfu_root->interface) < 0) {
errx(EX_IOERR, "can't send DFU_ABORT");
}
goto status_again;
break;
case DFU_STATE_dfuIDLE:
- printf("dfuIDLE, continuing\n");
- break;
default:
break;
}
@@ -571,7 +673,7 @@ status_again:
if (dfu_get_status(dfu_root, &status) < 0)
errx(EX_IOERR, "USB communication error");
if (DFU_STATUS_OK != status.bStatus)
- errx(EX_SOFTWARE, "Status is not OK: %d", status.bStatus);
+ errx(EX_PROTOCOL, "Status is not OK: %d", status.bStatus);
milli_sleep(status.bwPollTimeout);
}
@@ -581,29 +683,29 @@ status_again:
if (dfu_root->func_dfu.bcdDFUVersion == libusb_cpu_to_le16(0x11a))
dfuse_device = 1;
-
- /* If not overridden by the user */
- if (!transfer_size) {
- transfer_size = libusb_le16_to_cpu(
- dfu_root->func_dfu.wTransferSize);
- if (transfer_size) {
- printf("Device returned transfer size %i\n",
- transfer_size);
- } else {
- errx(EX_IOERR, "Transfer size must be specified");
- }
+ else if (dfuse_options)
+ printf("Warning: DfuSe option used on non-DfuSe device\n");
+
+ /* Get from device or user, warn if overridden */
+ int func_dfu_transfer_size = libusb_le16_to_cpu(dfu_root->func_dfu.wTransferSize);
+ if (func_dfu_transfer_size) {
+ printf("Device returned transfer size %i\n", func_dfu_transfer_size);
+ if (!transfer_size)
+ transfer_size = func_dfu_transfer_size;
+ else
+ printf("Warning: Overriding device-reported transfer size\n");
+ } else {
+ if (!transfer_size)
+ errx(EX_USAGE, "Transfer size must be specified");
}
-#ifdef HAVE_GETPAGESIZE
-/* autotools lie when cross-compiling for Windows using mingw32/64 */
-#ifndef __MINGW32__
- /* limitation of Linux usbdevio */
- if ((int)transfer_size > getpagesize()) {
- transfer_size = getpagesize();
+#ifdef __linux__
+ /* limited to 4k in libusb Linux backend */
+ if ((int)transfer_size > 4096) {
+ transfer_size = 4096;
printf("Limited transfer size to %i\n", transfer_size);
}
-#endif /* __MINGW32__ */
-#endif /* HAVE_GETPAGESIZE */
+#endif /* __linux__ */
if (transfer_size < dfu_root->bMaxPacketSize0) {
transfer_size = dfu_root->bMaxPacketSize0;
@@ -614,20 +716,22 @@ status_again:
case MODE_UPLOAD:
/* open for "exclusive" writing */
fd = open(file.name, O_WRONLY | O_BINARY | O_CREAT | O_EXCL | O_TRUNC, 0666);
- if (fd < 0)
- err(EX_IOERR, "Cannot open file %s for writing", file.name);
+ if (fd < 0) {
+ warn("Cannot open file %s for writing", file.name);
+ ret = EX_CANTCREAT;
+ break;
+ }
if (dfuse_device || dfuse_options) {
- if (dfuse_do_upload(dfu_root, transfer_size, fd,
- dfuse_options) < 0)
- exit(1);
+ ret = dfuse_do_upload(dfu_root, transfer_size, fd, dfuse_options);
} else {
- if (dfuload_do_upload(dfu_root, transfer_size,
- expected_size, fd) < 0) {
- exit(1);
- }
+ ret = dfuload_do_upload(dfu_root, transfer_size, expected_size, fd);
}
close(fd);
+ if (ret < 0)
+ ret = EX_IOERR;
+ else
+ ret = EX_OK;
break;
case MODE_DOWNLOAD:
@@ -635,47 +739,55 @@ status_again:
(file.idProduct != 0xffff && file.idProduct != runtime_product)) &&
((file.idVendor != 0xffff && file.idVendor != dfu_root->vendor) ||
(file.idProduct != 0xffff && file.idProduct != dfu_root->product))) {
- errx(EX_IOERR, "Error: File ID %04x:%04x does "
+ errx(EX_USAGE, "Error: File ID %04x:%04x does "
"not match device (%04x:%04x or %04x:%04x)",
file.idVendor, file.idProduct,
runtime_vendor, runtime_product,
dfu_root->vendor, dfu_root->product);
}
if (dfuse_device || dfuse_options || file.bcdDFU == 0x11a) {
- if (dfuse_do_dnload(dfu_root, transfer_size, &file,
- dfuse_options) < 0)
- exit(1);
+ ret = dfuse_do_dnload(dfu_root, transfer_size, &file, dfuse_options);
} else {
- if (dfuload_do_dnload(dfu_root, transfer_size, &file) < 0)
- exit(1);
+ ret = dfuload_do_dnload(dfu_root, transfer_size, &file);
}
+ if (ret < 0)
+ ret = EX_IOERR;
+ else
+ ret = EX_OK;
break;
case MODE_DETACH:
- if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) {
+ ret = dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000);
+ if (ret < 0) {
warnx("can't detach");
+ /* allow combination with final_reset */
+ ret = 0;
}
break;
default:
- errx(EX_IOERR, "Unsupported mode: %u", mode);
+ warnx("Unsupported mode: %u", mode);
+ ret = EX_SOFTWARE;
break;
}
- if (final_reset) {
- if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) {
+ if (!ret && final_reset) {
+ ret = dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000);
+ if (ret < 0) {
/* Even if detach failed, just carry on to leave the
device in a known state */
warnx("can't detach");
}
- printf("Resetting USB to switch back to runtime mode\n");
+ printf("Resetting USB to switch back to Run-Time mode\n");
ret = libusb_reset_device(dfu_root->dev_handle);
if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) {
- errx(EX_IOERR, "error resetting after download");
+ warnx("error resetting after download: %s", libusb_error_name(ret));
+ ret = EX_IOERR;
}
}
libusb_close(dfu_root->dev_handle);
dfu_root->dev_handle = NULL;
- libusb_exit(ctx);
- return (0);
+ disconnect_devices();
+ libusb_exit(ctx);
+ return ret;
}
diff --git a/src/portable.h b/src/portable.h
index 989cf51..f009163 100644
--- a/src/portable.h
+++ b/src/portable.h
@@ -2,14 +2,16 @@
#ifndef PORTABLE_H
#define PORTABLE_H
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#else
+#ifndef HAVE_CONFIG_H
# define PACKAGE "dfu-util"
-# define PACKAGE_VERSION "0.9-msvc"
-# define PACKAGE_STRING "dfu-util 0.9-msvc"
+# define PACKAGE_VERSION "0.11-msvc"
+# define PACKAGE_STRING "dfu-util 0.11-msvc"
# define PACKAGE_BUGREPORT "http://sourceforge.net/p/dfu-util/tickets/"
# include <io.h>
+/* FIXME if off_t is a typedef it is not a define */
+# ifndef off_t
+# define off_t long int
+# endif
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_UNISTD_H
@@ -19,13 +21,13 @@
#ifdef HAVE_NANOSLEEP
# include <time.h>
# define milli_sleep(msec) do {\
- if (msec) {\
+ if (msec != 0) {\
struct timespec nanosleepDelay = { (msec) / 1000, ((msec) % 1000) * 1000000 };\
nanosleep(&nanosleepDelay, NULL);\
} } while (0)
#elif defined HAVE_WINDOWS_H
# define milli_sleep(msec) do {\
- if (msec) {\
+ if (msec != 0) {\
Sleep(msec);\
} } while (0)
#else
@@ -56,16 +58,16 @@
#else
# define EX_OK 0 /* successful termination */
# define EX_USAGE 64 /* command line usage error */
+# define EX_DATAERR 65
+# define EX_NOINPUT 66
# define EX_SOFTWARE 70 /* internal software error */
+# define EX_CANTCREAT 73 /* input/output error */
# define EX_IOERR 74 /* input/output error */
+# define EX_PROTOCOL 76 /* input/output error */
#endif /* HAVE_SYSEXITS_H */
#ifndef O_BINARY
# define O_BINARY 0
#endif
-#ifndef off_t
-# define off_t long int
-#endif
-
#endif /* PORTABLE_H */
diff --git a/src/prefix.c b/src/prefix.c
index be8e3fa..58d1a87 100644
--- a/src/prefix.c
+++ b/src/prefix.c
@@ -4,6 +4,7 @@
* Copyright 2011-2012 Stefan Schmidt <stefan@datenfreihafen.org>
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
* Copyright 2014 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
+ * Copyright 2014-2020 Tormod Volden <debian.tormod@gmail.com>
*
* 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
@@ -20,6 +21,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
@@ -54,13 +59,12 @@ static void help(void)
"In combination with -a or -D or -c:\n"
" -L --lpc-prefix\t\tUse NXP LPC DFU prefix format\n"
);
- exit(EX_USAGE);
}
static void print_version(void)
{
printf("dfu-prefix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION);
- printf("Copyright 2011-2012 Stefan Schmidt, 2014 Uwe Bonnes\n"
+ printf("Copyright 2011-2012 Stefan Schmidt, 2014 Uwe Bonnes, 2014-2020 Tormod Volden\n"
"This program is Free Software and has ABSOLUTELY NO WARRANTY\n"
"Please report bugs to %s\n\n", PACKAGE_BUGREPORT);
@@ -75,6 +79,7 @@ static struct option opts[] = {
{ "stellaris-address", 1, 0, 's' },
{ "stellaris", 0, 0, 'T' },
{ "LPC", 0, 0, 'L' },
+ { 0, 0, 0, 0 }
};
int main(int argc, char **argv)
{
@@ -101,9 +106,10 @@ int main(int argc, char **argv)
switch (c) {
case 'h':
help();
+ exit(EX_OK);
break;
case 'V':
- exit(0);
+ exit(EX_OK);
break;
case 'D':
file.name = optarg;
@@ -120,7 +126,7 @@ int main(int argc, char **argv)
case 's':
lmdfu_flash_address = strtoul(optarg, &end, 0);
if (*end) {
- errx(EX_IOERR, "Invalid lmdfu "
+ errx(EX_USAGE, "Invalid lmdfu "
"address: %s", optarg);
}
/* fall-through */
@@ -132,6 +138,7 @@ int main(int argc, char **argv)
break;
default:
help();
+ exit(EX_USAGE);
break;
}
}
@@ -139,12 +146,13 @@ int main(int argc, char **argv)
if (!file.name) {
fprintf(stderr, "You need to specify a filename\n");
help();
+ exit(EX_USAGE);
}
switch(mode) {
case MODE_ADD:
if (type == ZERO_PREFIX)
- errx(EX_IOERR, "Prefix type must be specified");
+ errx(EX_USAGE, "Prefix type must be specified");
dfu_load_file(&file, MAYBE_SUFFIX, NO_PREFIX);
file.lmdfu_address = lmdfu_flash_address;
file.prefix_type = type;
@@ -156,13 +164,13 @@ int main(int argc, char **argv)
dfu_load_file(&file, MAYBE_SUFFIX, MAYBE_PREFIX);
show_suffix_and_prefix(&file);
if (type > ZERO_PREFIX && file.prefix_type != type)
- errx(EX_IOERR, "No prefix of requested type");
+ errx(EX_DATAERR, "No prefix of requested type");
break;
case MODE_DEL:
dfu_load_file(&file, MAYBE_SUFFIX, NEEDS_PREFIX);
if (type > ZERO_PREFIX && file.prefix_type != type)
- errx(EX_IOERR, "No prefix of requested type");
+ errx(EX_DATAERR, "No prefix of requested type");
printf("Removing prefix from file\n");
/* if there was a suffix, rewrite it */
dfu_store_file(&file, file.size.suffix != 0, 0);
@@ -170,7 +178,8 @@ int main(int argc, char **argv)
default:
help();
+ exit(EX_USAGE);
break;
}
- return (0);
+ return EX_OK;
}
diff --git a/src/quirks.c b/src/quirks.c
index de394a6..eec9ef9 100755
--- a/src/quirks.c
+++ b/src/quirks.c
@@ -1,7 +1,7 @@
/*
* Simple quirk system for dfu-util
*
- * Copyright 2010-2014 Tormod Volden
+ * Copyright 2010-2017 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
@@ -18,8 +18,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "portable.h"
#include "quirks.h"
+#include "dfuse_mem.h"
uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice)
{
@@ -32,7 +41,8 @@ uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice)
quirks |= QUIRK_POLLTIMEOUT;
if (vendor == VENDOR_VOTI &&
- product == PRODUCT_OPENPCD)
+ (product == PRODUCT_OPENPCD || product == PRODUCT_SIMTRACE ||
+ product == PRODUCT_OPENPICC))
quirks |= QUIRK_POLLTIMEOUT;
/* Reports wrong DFU version in DFU descriptor */
@@ -52,5 +62,66 @@ uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice)
product == PRODUCT_TRANSIT)
quirks |= QUIRK_POLLTIMEOUT;
+ /* Some GigaDevice GD32 devices have improperly-encoded serial numbers
+ * and bad DfuSe descriptors which we use serial number to correct.
+ * They also "leave" without a DFU_GETSTATUS request */
+ if (vendor == VENDOR_GIGADEVICE &&
+ product == PRODUCT_GD32) {
+ quirks |= QUIRK_UTF8_SERIAL;
+ quirks |= QUIRK_DFUSE_LAYOUT;
+ quirks |= QUIRK_DFUSE_LEAVE;
+ }
+
return (quirks);
}
+
+#define GD32VF103_FLASH_BASE 0x08000000
+
+void fixup_dfuse_layout(struct dfu_if *dif, struct memsegment **segment_list)
+{
+ if (dif->vendor == VENDOR_GIGADEVICE &&
+ dif->product == PRODUCT_GD32 &&
+ dif->altsetting == 0 &&
+ dif->serial_name &&
+ strlen(dif->serial_name) == 4 &&
+ dif->serial_name[0] == '3' &&
+ dif->serial_name[3] == 'J') {
+ struct memsegment *seg;
+ int count;
+
+ printf("Found GD32VF103, which reports a bad page size and "
+ "count for its internal memory.\n");
+
+ seg = find_segment(*segment_list, GD32VF103_FLASH_BASE);
+ if (!seg) {
+ warnx("Could not fix GD32VF103 layout because there "
+ "is no segment at 0x%08x", GD32VF103_FLASH_BASE);
+ return;
+ }
+
+ /* All GD32VF103 have this page size, according to Nucleisys's
+ * dfu-util (https://github.com/riscv-mcu/gd32-dfu-utils/). */
+ seg->pagesize = 1024;
+
+ /* From Tables 2-1 and 2-2 ("devices features and peripheral
+ * list") in the GD32VF103 Datasheet */
+ if (dif->serial_name[2] == 'B') {
+ count = 128;
+ } else if (dif->serial_name[2] == '8') {
+ count = 64;
+ } else if (dif->serial_name[2] == '6') {
+ count = 32;
+ } else if (dif->serial_name[2] == '4') {
+ count = 16;
+ } else {
+ warnx("Unknown flash size '%c' in part number; "
+ "defaulting to 128KB.", dif->serial_name[2]);
+ count = 128;
+ }
+
+ seg->end = seg->start + (count * seg->pagesize) - 1;
+
+ printf("Fixed layout based on part number: page size %d, "
+ "count %d.\n", seg->pagesize, count);
+ }
+}
diff --git a/src/quirks.h b/src/quirks.h
index 0e4b3ec..9f0dc4f 100755
--- a/src/quirks.h
+++ b/src/quirks.h
@@ -1,27 +1,38 @@
#ifndef DFU_QUIRKS_H
#define DFU_QUIRKS_H
-#define VENDOR_OPENMOKO 0x1d50 /* Openmoko Freerunner / GTA02 */
-#define VENDOR_FIC 0x1457 /* Openmoko Freerunner / GTA02 */
-#define VENDOR_VOTI 0x16c0 /* OpenPCD Reader */
-#define VENDOR_LEAFLABS 0x1eaf /* Maple */
-#define VENDOR_SIEMENS 0x0908 /* Siemens AG */
-#define VENDOR_MIDIMAN 0x0763 /* Midiman */
+#include "dfu.h"
+#include "dfuse_mem.h"
+
+#define VENDOR_OPENMOKO 0x1d50 /* Openmoko Freerunner / GTA02 */
+#define VENDOR_FIC 0x1457 /* Openmoko Freerunner / GTA02 */
+#define VENDOR_VOTI 0x16c0 /* OpenPCD Reader */
+#define VENDOR_LEAFLABS 0x1eaf /* Maple */
+#define VENDOR_SIEMENS 0x0908 /* Siemens AG */
+#define VENDOR_MIDIMAN 0x0763 /* Midiman */
+#define VENDOR_GIGADEVICE 0x28e9 /* GigaDevice */
#define PRODUCT_FREERUNNER_FIRST 0x5117
#define PRODUCT_FREERUNNER_LAST 0x5126
-#define PRODUCT_OPENPCD 0x076b
-#define PRODUCT_MAPLE3 0x0003 /* rev 3 and 5 */
-#define PRODUCT_PXM40 0x02c4 /* Siemens AG, PXM 40 */
-#define PRODUCT_PXM50 0x02c5 /* Siemens AG, PXM 50 */
-#define PRODUCT_TRANSIT 0x2806 /* M-Audio Transit (Midiman) */
+#define PRODUCT_SIMTRACE 0x0762
+#define PRODUCT_OPENPCD 0x076b
+#define PRODUCT_OPENPICC 0x076c
+#define PRODUCT_MAPLE3 0x0003 /* rev 3 and 5 */
+#define PRODUCT_PXM40 0x02c4 /* Siemens AG, PXM 40 */
+#define PRODUCT_PXM50 0x02c5 /* Siemens AG, PXM 50 */
+#define PRODUCT_TRANSIT 0x2806 /* M-Audio Transit (Midiman) */
+#define PRODUCT_GD32 0x0189 /* GigaDevice GD32VF103 rev 1 */
#define QUIRK_POLLTIMEOUT (1<<0)
#define QUIRK_FORCE_DFU11 (1<<1)
+#define QUIRK_UTF8_SERIAL (1<<2)
+#define QUIRK_DFUSE_LAYOUT (1<<3)
+#define QUIRK_DFUSE_LEAVE (1<<4)
/* Fallback value, works for OpenMoko */
#define DEFAULT_POLLTIMEOUT 5
uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice);
+void fixup_dfuse_layout(struct dfu_if *dif, struct memsegment **segment_list);
#endif /* DFU_QUIRKS_H */
diff --git a/src/suffix.c b/src/suffix.c
index 0df248f..fc26e25 100644
--- a/src/suffix.c
+++ b/src/suffix.c
@@ -3,7 +3,7 @@
*
* Copyright 2011-2012 Stefan Schmidt <stefan@datenfreihafen.org>
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
- * Copyright 2014 Tormod Volden <debian.tormod@gmail.com>
+ * Copyright 2014-2020 Tormod Volden <debian.tormod@gmail.com>
*
* 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
@@ -20,6 +20,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
@@ -51,13 +55,12 @@ static void help(void)
" -d --did <deviceID>\t\tAdd device ID into DFU suffix in <file>\n"
" -S --spec <specID>\t\tAdd DFU specification ID into DFU suffix in <file>\n"
);
- exit(EX_USAGE);
}
static void print_version(void)
{
printf("dfu-suffix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION);
- printf("Copyright 2011-2012 Stefan Schmidt, 2013-2014 Tormod Volden\n"
+ printf("Copyright 2011-2012 Stefan Schmidt, 2013-2020 Tormod Volden\n"
"This program is Free Software and has ABSOLUTELY NO WARRANTY\n"
"Please report bugs to %s\n\n", PACKAGE_BUGREPORT);
@@ -73,6 +76,7 @@ static struct option opts[] = {
{ "vid", 1, 0, 'v' },
{ "did", 1, 0, 'd' },
{ "spec", 1, 0, 'S' },
+ { 0, 0, 0, 0 }
};
int main(int argc, char **argv)
@@ -100,9 +104,10 @@ int main(int argc, char **argv)
switch (c) {
case 'h':
help();
+ exit(EX_OK);
break;
case 'V':
- exit(0);
+ exit(EX_OK);
break;
case 'D':
file.name = optarg;
@@ -130,6 +135,7 @@ int main(int argc, char **argv)
break;
default:
help();
+ exit(EX_USAGE);
break;
}
}
@@ -137,11 +143,13 @@ int main(int argc, char **argv)
if (!file.name) {
fprintf(stderr, "You need to specify a filename\n");
help();
+ exit(EX_USAGE);
}
if (spec != 0x0100 && spec != 0x011a) {
fprintf(stderr, "Only DFU specification 0x0100 and 0x011a supported\n");
help();
+ exit(EX_USAGE);
}
switch(mode) {
@@ -170,7 +178,8 @@ int main(int argc, char **argv)
default:
help();
+ exit(EX_USAGE);
break;
}
- return (0);
+ return EX_OK;
}
diff --git a/src/usb_dfu.h b/src/usb_dfu.h
index 660bedc..6deae91 100644
--- a/src/usb_dfu.h
+++ b/src/usb_dfu.h
@@ -46,7 +46,11 @@ struct usb_dfu_func_descriptor {
};
# pragma pack(pop)
#elif defined __GNUC__
-} __attribute__ ((packed));
+# if defined __MINGW32__
+} __attribute__ ((__packed__, __gcc_struct__));
+# else
+} __attribute__ ((__packed__));
+# endif
#else
#warning "No way to pack struct on this compiler? This will break!"
#endif /* _MSC_VER */