summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2013-09-05 20:18:59 +0000
committersjg <sjg@FreeBSD.org>2013-09-05 20:18:59 +0000
commit62bb1062226d3ce6a2350808256a25508978352d (patch)
tree22b131dceb13c3df96da594fbaadb693504797c7 /tools
parent72ab90509b3a51ab361bf710338f2ef44a4e360d (diff)
parent04932445481c2cb89ff69a83b961bdef3d64757e (diff)
downloadFreeBSD-src-62bb1062226d3ce6a2350808256a25508978352d.zip
FreeBSD-src-62bb1062226d3ce6a2350808256a25508978352d.tar.gz
Merge from head
Diffstat (limited to 'tools')
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc127
-rw-r--r--tools/build/options/WITHOUT_ARM_EABI2
-rw-r--r--tools/build/options/WITHOUT_BMAKE (renamed from tools/build/options/WITH_BMAKE)2
-rw-r--r--tools/build/options/WITHOUT_CROSS_COMPILER3
-rw-r--r--tools/build/options/WITHOUT_FORMAT_EXTENSIONS5
-rw-r--r--tools/build/options/WITHOUT_ICONV2
-rw-r--r--tools/build/options/WITHOUT_JAIL2
-rw-r--r--tools/build/options/WITHOUT_KERBEROS_SUPPORT1
-rw-r--r--tools/build/options/WITHOUT_LEGACY_CONSOLE2
-rw-r--r--tools/build/options/WITHOUT_SVNLITE (renamed from tools/build/options/WITHOUT_PKGTOOLS)2
-rw-r--r--tools/build/options/WITH_ARM_EABI2
-rw-r--r--tools/build/options/WITH_BSDCONFIG2
-rw-r--r--tools/build/options/WITH_BSD_PATCH2
-rw-r--r--tools/build/options/WITH_DEBUG_FILES7
-rw-r--r--tools/build/options/WITH_ICONV2
-rw-r--r--tools/build/options/WITH_IDEA6
-rw-r--r--tools/build/options/WITH_LIBICONV_COMPAT2
-rw-r--r--tools/build/options/WITH_PKGTOOLS4
-rw-r--r--tools/build/options/WITH_SVN5
-rw-r--r--tools/build/options/WITH_USB_GADGET_EXAMPLES2
-rwxr-xr-xtools/build/options/makeman24
-rw-r--r--tools/regression/aio/aiop/aiop.c3
-rw-r--r--tools/regression/aio/aiotest/aiotest.c18
-rw-r--r--tools/regression/bin/sh/builtins/alias4.04
-rw-r--r--tools/regression/bin/sh/builtins/break4.47
-rw-r--r--tools/regression/bin/sh/builtins/break5.412
-rw-r--r--tools/regression/bin/sh/builtins/jobid1.07
-rw-r--r--tools/regression/bin/sh/builtins/jobid2.09
-rw-r--r--tools/regression/bin/sh/builtins/local2.017
-rw-r--r--tools/regression/bin/sh/builtins/local3.026
-rw-r--r--tools/regression/bin/sh/builtins/local4.012
-rw-r--r--tools/regression/bin/sh/builtins/read7.05
-rw-r--r--tools/regression/bin/sh/builtins/return8.013
-rw-r--r--tools/regression/bin/sh/builtins/type3.03
-rw-r--r--tools/regression/bin/sh/builtins/wait10.05
-rw-r--r--tools/regression/bin/sh/builtins/wait8.07
-rw-r--r--tools/regression/bin/sh/builtins/wait9.1273
-rw-r--r--tools/regression/bin/sh/execution/int-cmd1.03
-rw-r--r--tools/regression/bin/sh/expansion/arith13.06
-rw-r--r--tools/regression/bin/sh/parser/empty-cmd1.03
-rw-r--r--tools/regression/bin/sh/parser/only-redir2.02
-rw-r--r--tools/regression/bin/sh/parser/only-redir3.02
-rw-r--r--tools/regression/bin/sh/parser/only-redir4.02
-rw-r--r--tools/regression/bin/test/regress.sh65
-rw-r--r--tools/regression/file/dup/dup.c163
-rw-r--r--tools/regression/file/fcntlflags/Makefile7
-rw-r--r--tools/regression/file/fcntlflags/fcntlflags.c110
-rw-r--r--tools/regression/file/fcntlflags/fcntlflags.t10
-rw-r--r--tools/regression/filemon/Makefile62
-rw-r--r--tools/regression/filemon/filemontest.c8
-rwxr-xr-xtools/regression/filemon/test_script.sh1
-rw-r--r--tools/regression/filemon/timed-forkb.c2
-rw-r--r--tools/regression/geom_uzip/.cvsignore2
-rw-r--r--tools/regression/include/stdatomic/Makefile7
-rw-r--r--tools/regression/include/stdatomic/logic.c128
-rw-r--r--tools/regression/lib/libc/gen/Makefile2
-rw-r--r--tools/regression/lib/libc/gen/test-fnmatch.c4
-rw-r--r--tools/regression/lib/libc/gen/test-fpclassify.c1
-rw-r--r--tools/regression/lib/libc/gen/test-ftw.c2
-rw-r--r--tools/regression/lib/libc/gen/test-popen.c227
-rw-r--r--tools/regression/lib/libc/gen/test-wordexp.c12
-rw-r--r--tools/regression/lib/libc/locale/Makefile4
-rw-r--r--tools/regression/lib/libc/locale/test-btowc.c1
-rw-r--r--tools/regression/lib/libc/locale/test-c16rtomb.c145
-rw-r--r--tools/regression/lib/libc/locale/test-iswctype.c1
-rw-r--r--tools/regression/lib/libc/locale/test-mbrtoc16.c195
-rw-r--r--tools/regression/lib/libc/locale/test-towctrans.c1
-rw-r--r--tools/regression/lib/libc/nss/test-getaddr.c2
-rw-r--r--tools/regression/lib/libc/nss/test-getgr.c2
-rw-r--r--tools/regression/lib/libc/nss/test-gethostby.c2
-rw-r--r--tools/regression/lib/libc/nss/test-getproto.c2
-rw-r--r--tools/regression/lib/libc/nss/test-getpw.c2
-rw-r--r--tools/regression/lib/libc/nss/test-getrpc.c2
-rw-r--r--tools/regression/lib/libc/nss/test-getusershell.c2
-rw-r--r--tools/regression/lib/libc/nss/testutil.h1
-rw-r--r--tools/regression/lib/libc/stdio/Makefile6
-rw-r--r--tools/regression/lib/libc/stdio/test-mkostemp.c164
-rw-r--r--tools/regression/lib/msun/Makefile5
-rw-r--r--tools/regression/lib/msun/test-cexp.c231
-rw-r--r--tools/regression/lib/msun/test-conj.c23
-rw-r--r--tools/regression/lib/msun/test-csqrt.c102
-rw-r--r--tools/regression/lib/msun/test-ctrig.c358
-rw-r--r--tools/regression/lib/msun/test-exponential.c16
-rw-r--r--tools/regression/lib/msun/test-fma.c65
-rw-r--r--tools/regression/lib/msun/test-fmaxmin.c16
-rw-r--r--tools/regression/lib/msun/test-invctrig.c372
-rw-r--r--tools/regression/lib/msun/test-invtrig.c38
-rw-r--r--tools/regression/lib/msun/test-logarithm.c131
-rw-r--r--tools/regression/lib/msun/test-nearbyint.c26
-rw-r--r--tools/regression/lib/msun/test-next.c6
-rw-r--r--tools/regression/lib/msun/test-rem.c4
-rw-r--r--tools/regression/lib/msun/test-trig.c18
-rw-r--r--tools/regression/lib/msun/test-utils.h174
-rw-r--r--tools/regression/pjdfstest/pjdfstest.c34
-rw-r--r--tools/regression/priv/Makefile2
-rw-r--r--tools/regression/pthread/cv_cancel1/cv_cancel1.c1
-rw-r--r--tools/regression/sbin/dhclient/Makefile1
-rw-r--r--tools/regression/usr.bin/xargs/regress.0.inbin0 -> 86 bytes
-rw-r--r--tools/regression/usr.bin/xargs/regress.0.out8
-rw-r--r--tools/regression/usr.bin/xargs/regress.0I.out18
-rw-r--r--tools/regression/usr.bin/xargs/regress.0J.out4
-rw-r--r--tools/regression/usr.bin/xargs/regress.0L.out6
-rw-r--r--tools/regression/usr.bin/xargs/regress.n1.out8
-rw-r--r--tools/regression/usr.bin/xargs/regress.n2.out4
-rw-r--r--tools/regression/usr.bin/xargs/regress.n3.out3
-rw-r--r--tools/regression/usr.bin/xargs/regress.quotes.in4
-rw-r--r--tools/regression/usr.bin/xargs/regress.quotes.out7
-rw-r--r--tools/regression/usr.bin/xargs/regress.sh10
-rw-r--r--tools/regression/usr.bin/yacc/grammar.y2
-rw-r--r--tools/regression/usr.bin/yacc/regress.08.out2
-rw-r--r--tools/test/dtrace/Makefile1
-rwxr-xr-xtools/test/hwpmc/pmctest.py6
-rw-r--r--tools/test/posixshm/shm_test.c27
-rw-r--r--tools/tools/README1
-rw-r--r--tools/tools/ath/Makefile2
-rw-r--r--tools/tools/ath/Makefile.inc1
-rw-r--r--tools/tools/ath/ath_ee_9300_print/Makefile19
-rw-r--r--tools/tools/ath/ath_ee_9300_print/main.c229
-rw-r--r--tools/tools/ath/athalq/Makefile4
-rw-r--r--tools/tools/ath/athalq/ar9300_ds.c2
-rw-r--r--tools/tools/ath/athalq/main.c43
-rwxr-xr-xtools/tools/ath/athalq/txdiff.pl34
-rw-r--r--tools/tools/ath/athspectral/athspectral.c12
-rw-r--r--tools/tools/ath/athstats/athstats.c7
-rw-r--r--tools/tools/bootparttest/bootparttest.c2
-rw-r--r--tools/tools/bus_autoconf/bus_load_file.c2
-rw-r--r--tools/tools/crypto/ipsecstats.c57
-rw-r--r--tools/tools/cxgbetool/cxgbetool.c216
-rw-r--r--tools/tools/drm/README5
-rwxr-xr-xtools/tools/drm/gen-drm_pciids183
-rw-r--r--tools/tools/drm/radeon/README4
-rw-r--r--tools/tools/drm/radeon/firmwares/README9
-rwxr-xr-xtools/tools/drm/radeon/firmwares/encode-firmwares17
-rw-r--r--tools/tools/drm/radeon/mkregtable/Makefile58
-rw-r--r--tools/tools/drm/radeon/mkregtable/README7
-rw-r--r--tools/tools/drm/radeon/mkregtable/mkregtable.c733
-rw-r--r--tools/tools/ifinfo/ifinfo.c11
-rw-r--r--tools/tools/makeroot/Makefile8
-rw-r--r--tools/tools/makeroot/makeroot.8131
-rwxr-xr-xtools/tools/makeroot/makeroot.sh236
-rw-r--r--tools/tools/nanobsd/gateworks/common1
-rw-r--r--tools/tools/nanobsd/nanobsd.sh23
-rw-r--r--tools/tools/netmap/Makefile2
-rw-r--r--tools/tools/netmap/README1
-rw-r--r--tools/tools/netmap/bridge.c15
-rw-r--r--tools/tools/netmap/nm_util.c1
-rw-r--r--tools/tools/netmap/pcap.c3
-rw-r--r--tools/tools/netmap/pkt-gen.c255
-rw-r--r--tools/tools/netmap/vale-ctl.c163
-rw-r--r--tools/tools/notescheck/notescheck.py2
-rw-r--r--tools/tools/pciroms/pciroms.c29
-rw-r--r--tools/tools/sysbuild/sysbuild.sh2
-rw-r--r--tools/tools/sysdoc/sysdoc.sh12
-rw-r--r--tools/tools/sysdoc/tunables.mdoc10
-rw-r--r--tools/tools/umastat/umastat.c4
-rw-r--r--tools/tools/usbtest/Makefile40
-rw-r--r--tools/tools/usbtest/usb_control_ep_test.c673
-rw-r--r--tools/tools/usbtest/usb_modem_test.c585
-rw-r--r--tools/tools/usbtest/usb_msc_test.c1290
-rw-r--r--tools/tools/usbtest/usb_msc_test.h120
-rw-r--r--tools/tools/usbtest/usbtest.c809
-rw-r--r--tools/tools/usbtest/usbtest.h62
-rw-r--r--tools/tools/zfsboottest/Makefile3
-rw-r--r--tools/tools/zfsboottest/zfsboottest.c7
-rwxr-xr-xtools/tools/zfsboottest/zfsboottest.sh18
165 files changed, 8659 insertions, 957 deletions
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index b464c98..633ead0 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -206,7 +206,9 @@ OLD_FILES+=usr/share/man/man8/auditd.8.gz
.if ${MK_AUTHPF} == no
OLD_FILES+=usr/sbin/authpf
+OLD_FILES+=usr/sbin/authpf-noip
OLD_FILES+=usr/share/man/man8/authpf.8.gz
+OLD_FILES+=usr/share/man/man8/authpf-noip.8.gz
.endif
.if ${MK_BIND} == no
@@ -388,6 +390,9 @@ OLD_FILES+=var/named/etc/namedb/PROTO.localhost.rev
OLD_FILES+=var/named/etc/namedb/make-localhost
#OLD_FILES+=var/named/etc/namedb/named.conf # intentionally left out
OLD_FILES+=var/named/etc/namedb/named.root
+OLD_FILES+=var/named/etc/namedb/master/empty.db
+OLD_FILES+=var/named/etc/namedb/master/localhost-forward.db
+OLD_FILES+=var/named/etc/namedb/master/localhost-reverse.db
OLD_DIRS+=var/named/etc/namedb/slave
OLD_DIRS+=var/named/etc/namedb/master
OLD_DIRS+=var/named/etc/namedb/dynamic
@@ -786,6 +791,38 @@ OLD_FILES+=usr/include/clang/3.2/x86intrin.h
OLD_FILES+=usr/include/clang/3.2/xmmintrin.h
OLD_FILES+=usr/include/clang/3.2/xopintrin.h
OLD_DIRS+=usr/include/clang/3.2
+OLD_FILES+=usr/include/clang/3.3/__wmmintrin_aes.h
+OLD_FILES+=usr/include/clang/3.3/__wmmintrin_pclmul.h
+OLD_FILES+=usr/include/clang/3.3/altivec.h
+OLD_FILES+=usr/include/clang/3.3/ammintrin.h
+OLD_FILES+=usr/include/clang/3.3/avx2intrin.h
+OLD_FILES+=usr/include/clang/3.3/avxintrin.h
+OLD_FILES+=usr/include/clang/3.3/bmi2intrin.h
+OLD_FILES+=usr/include/clang/3.3/bmiintrin.h
+OLD_FILES+=usr/include/clang/3.3/cpuid.h
+OLD_FILES+=usr/include/clang/3.3/emmintrin.h
+OLD_FILES+=usr/include/clang/3.3/f16cintrin.h
+OLD_FILES+=usr/include/clang/3.3/fma4intrin.h
+OLD_FILES+=usr/include/clang/3.3/fmaintrin.h
+OLD_FILES+=usr/include/clang/3.3/immintrin.h
+OLD_FILES+=usr/include/clang/3.3/lzcntintrin.h
+OLD_FILES+=usr/include/clang/3.3/mm3dnow.h
+OLD_FILES+=usr/include/clang/3.3/mm_malloc.h
+OLD_FILES+=usr/include/clang/3.3/mmintrin.h
+OLD_FILES+=usr/include/clang/3.3/module.map
+OLD_FILES+=usr/include/clang/3.3/nmmintrin.h
+OLD_FILES+=usr/include/clang/3.3/pmmintrin.h
+OLD_FILES+=usr/include/clang/3.3/popcntintrin.h
+OLD_FILES+=usr/include/clang/3.3/prfchwintrin.h
+OLD_FILES+=usr/include/clang/3.3/rdseedintrin.h
+OLD_FILES+=usr/include/clang/3.3/rtmintrin.h
+OLD_FILES+=usr/include/clang/3.3/smmintrin.h
+OLD_FILES+=usr/include/clang/3.3/tmmintrin.h
+OLD_FILES+=usr/include/clang/3.3/wmmintrin.h
+OLD_FILES+=usr/include/clang/3.3/x86intrin.h
+OLD_FILES+=usr/include/clang/3.3/xmmintrin.h
+OLD_FILES+=usr/include/clang/3.3/xopintrin.h
+OLD_DIRS+=usr/include/clang/3.3
OLD_DIRS+=usr/include/clang
OLD_FILES+=usr/share/doc/llvm/clang/LICENSE.TXT
OLD_DIRS+=usr/share/doc/llvm/clang
@@ -857,35 +894,6 @@ OLD_FILES+=usr/share/man/man1/ctm_smail.1.gz
OLD_FILES+=usr/share/man/man5/ctm.5.gz
.endif
-.if ${MK_CVS} == no
-OLD_FILES+=usr/bin/cvs
-OLD_FILES+=usr/bin/cvsbug
-OLD_FILES+=usr/share/examples/cvs/contrib/README
-OLD_FILES+=usr/share/examples/cvs/contrib/clmerge
-OLD_FILES+=usr/share/examples/cvs/contrib/cln_hist
-OLD_FILES+=usr/share/examples/cvs/contrib/commit_prep
-OLD_FILES+=usr/share/examples/cvs/contrib/cvs2vendor
-OLD_FILES+=usr/share/examples/cvs/contrib/cvs_acls
-OLD_FILES+=usr/share/examples/cvs/contrib/cvscheck
-OLD_FILES+=usr/share/examples/cvs/contrib/cvscheck.man
-OLD_FILES+=usr/share/examples/cvs/contrib/cvshelp.man
-OLD_FILES+=usr/share/examples/cvs/contrib/descend.man
-OLD_FILES+=usr/share/examples/cvs/contrib/easy-import
-OLD_FILES+=usr/share/examples/cvs/contrib/intro.doc
-OLD_FILES+=usr/share/examples/cvs/contrib/log
-OLD_FILES+=usr/share/examples/cvs/contrib/log_accum
-OLD_FILES+=usr/share/examples/cvs/contrib/mfpipe
-OLD_FILES+=usr/share/examples/cvs/contrib/rcs-to-cvs
-OLD_FILES+=usr/share/examples/cvs/contrib/rcs2log
-OLD_FILES+=usr/share/examples/cvs/contrib/rcslock
-OLD_FILES+=usr/share/examples/cvs/contrib/sccs2rcs
-OLD_FILES+=usr/share/info/cvs.info.gz
-OLD_FILES+=usr/share/info/cvsclient.info.gz
-OLD_FILES+=usr/share/man/man1/cvs.1.gz
-OLD_FILES+=usr/share/man/man5/cvs.5.gz
-OLD_FILES+=usr/share/man/man8/cvsbug.8.gz
-.endif
-
# devd(8) and gperf(1) not listed here on purpose
.if ${MK_CXX} == no
OLD_FILES+=usr/bin/CC
@@ -1484,6 +1492,7 @@ OLD_FILES+=usr/share/man/man8/fdcontrol.8.gz
OLD_FILES+=etc/freebsd-update.conf
OLD_FILES+=usr/sbin/freebsd-update
OLD_FILES+=usr/share/examples/etc/freebsd-update.conf
+OLD_FILES+=usr/share/man/man5/freebsd-update.conf.5.gz
OLD_FILES+=usr/share/man/man8/freebsd-update.8.gz
.endif
@@ -1549,6 +1558,7 @@ OLD_FILES+=usr/include/gcc/4.2/mmintrin.h
OLD_FILES+=usr/include/gcc/4.2/pmmintrin.h
OLD_FILES+=usr/include/gcc/4.2/tmmintrin.h
OLD_FILES+=usr/include/gcc/4.2/xmmintrin.h
+OLD_FILES+=usr/include/gcc/4.2/mm3dnow.h
.elif ${TARGET_ARCH} == "ia64"
OLD_FILES+=usr/include/gcc/4.2/ia64intrin.h
.elif ${TARGET_ARCH} == "arm"
@@ -2188,8 +2198,25 @@ OLD_FILES+=usr/share/man/man5/hesiod.conf.5.gz
# to be filled in
#.endif
-.if ${MK_IDEA} == no
-OLD_FILES+=usr/include/openssl/idea.h
+.if ${MK_ICONV} == no
+OLD_FILES+=usr/bin/iconv
+OLD_FILES+=usr/bin/mkcsmapper
+OLD_FILES+=usr/bin/mkesdb
+OLD_FILES+=usr/include/_libiconv_compat.h
+OLD_FILES+=usr/include/iconv.h
+OLD_FILES+=usr/share/man/man1/iconv.1.gz
+OLD_FILES+=usr/share/man/man1/mkcsmapper.1.gz
+OLD_FILES+=usr/share/man/man1/mkesdb.1.gz
+OLD_FILES+=usr/share/man/man3/__iconv.3.gz
+OLD_FILES+=usr/share/man/man3/__iconv_free_list.3.gz
+OLD_FILES+=usr/share/man/man3/__iconv_get_list.3.gz
+OLD_FILES+=usr/share/man/man3/iconv.3.gz
+OLD_FILES+=usr/share/man/man3/iconv_canonicalize.3.gz
+OLD_FILES+=usr/share/man/man3/iconv_close.3.gz
+OLD_FILES+=usr/share/man/man3/iconv_open.3.gz
+OLD_FILES+=usr/share/man/man3/iconv_open_into.3.gz
+OLD_FILES+=usr/share/man/man3/iconvctl.3.gz
+OLD_FILES+=usr/share/man/man3/iconvlist.3.gz
.endif
.if ${MK_INET6} == no
@@ -3332,6 +3359,13 @@ OLD_FILES+=usr/share/man/man8/verify_krb5_conf.8.gz
# to be filled in
#.endif
+.if ${MK_LIBICONV_COMPAT} == no
+OLD_FILES+=usr/lib/libiconv.a
+OLD_FILES+=usr/lib/libiconv.so
+OLD_FILES+=usr/lib/libiconv.so.3
+OLD_FILES+=usr/lib/libiconv_p.a
+.endif
+
.if ${MK_LIBCPLUSPLUS} == no
OLD_LIBS+=lib/libcxxrt.so.1
OLD_FILES+=usr/lib/libc++.a
@@ -3646,9 +3680,9 @@ OLD_FILES+=usr/share/man/man8/ntptime.8.gz
# to be filled in
#.endif
-#.if ${MK_OPENSSH} == no
-# to be filled in
-#.endif
+.if ${MK_OPENSSH} == no
+OLD_FILES+=usr.bin/ssh-copy-id
+.endif
#.if ${MK_OPENSSL} == no
# to be filled in
@@ -3989,7 +4023,6 @@ OLD_FILES+=usr/share/man/man8/rtquery.8.gz
.if ${MK_SENDMAIL} == no
OLD_FILES+=etc/periodic/daily/150.clean-hoststat
-OLD_FILES+=etc/periodic/daily/210.backup-aliases
OLD_FILES+=etc/periodic/daily/440.status-mailq
OLD_FILES+=etc/periodic/daily/460.status-mail-rejects
OLD_FILES+=etc/periodic/daily/500.queuerun
@@ -4318,3 +4351,27 @@ OLD_FILES+=usr/share/man/man8/wpa_cli.8.gz
OLD_FILES+=usr/share/man/man8/wpa_passphrase.8.gz
OLD_FILES+=usr/share/man/man8/wpa_supplicant.8.gz
.endif
+
+.if ${MK_SVNLITE} == no || ${MK_SVN} == yes
+OLD_FILES+=usr/bin/svnlite
+OLD_FILES+=usr/bin/svnliteadmin
+OLD_FILES+=usr/bin/svnlitedumpfilter
+OLD_FILES+=usr/bin/svnlitelook
+OLD_FILES+=usr/bin/svnlitemucc
+OLD_FILES+=usr/bin/svnliterdump
+OLD_FILES+=usr/bin/svnliteserve
+OLD_FILES+=usr/bin/svnlitesync
+OLD_FILES+=usr/bin/svnliteversion
+.endif
+
+.if ${MK_SVN} == no
+OLD_FILES+=usr/bin/svn
+OLD_FILES+=usr/bin/svnadmin
+OLD_FILES+=usr/bin/svndumpfilter
+OLD_FILES+=usr/bin/svnlook
+OLD_FILES+=usr/bin/svnmucc
+OLD_FILES+=usr/bin/svnrdump
+OLD_FILES+=usr/bin/svnserve
+OLD_FILES+=usr/bin/svnsync
+OLD_FILES+=usr/bin/svnversion
+.endif
diff --git a/tools/build/options/WITHOUT_ARM_EABI b/tools/build/options/WITHOUT_ARM_EABI
new file mode 100644
index 0000000..58e8348
--- /dev/null
+++ b/tools/build/options/WITHOUT_ARM_EABI
@@ -0,0 +1,2 @@
+.\" $FreeBSD$
+Set the ARM ABI to OABI.
diff --git a/tools/build/options/WITH_BMAKE b/tools/build/options/WITHOUT_BMAKE
index 2b47121..ab3cece 100644
--- a/tools/build/options/WITH_BMAKE
+++ b/tools/build/options/WITHOUT_BMAKE
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-Build and install the portable BSD make (bmake) as
+Set to not build and install the portable BSD make (bmake) as
.Xr make 1
instead of the traditional FreeBSD make.
This build option is temporary.
diff --git a/tools/build/options/WITHOUT_CROSS_COMPILER b/tools/build/options/WITHOUT_CROSS_COMPILER
new file mode 100644
index 0000000..1ded25b
--- /dev/null
+++ b/tools/build/options/WITHOUT_CROSS_COMPILER
@@ -0,0 +1,3 @@
+.\" $FreeBSD$
+Set to not build a cross compiler in the cross-tools stage of
+buildworld, buildkernel, etc.
diff --git a/tools/build/options/WITHOUT_FORMAT_EXTENSIONS b/tools/build/options/WITHOUT_FORMAT_EXTENSIONS
new file mode 100644
index 0000000..7ae02e1
--- /dev/null
+++ b/tools/build/options/WITHOUT_FORMAT_EXTENSIONS
@@ -0,0 +1,5 @@
+.\" $FreeBSD$
+Set to not enable
+.Fl fformat-extensions
+when compiling the kernel.
+Also disables all format checking.
diff --git a/tools/build/options/WITHOUT_ICONV b/tools/build/options/WITHOUT_ICONV
new file mode 100644
index 0000000..a43dd3a
--- /dev/null
+++ b/tools/build/options/WITHOUT_ICONV
@@ -0,0 +1,2 @@
+.\" $FreeBSD$
+Set to not build iconv as part of libc.
diff --git a/tools/build/options/WITHOUT_JAIL b/tools/build/options/WITHOUT_JAIL
index 27774e8..355b716 100644
--- a/tools/build/options/WITHOUT_JAIL
+++ b/tools/build/options/WITHOUT_JAIL
@@ -1,3 +1,3 @@
.\" $FreeBSD$
-Set to not build tools for the support of jails; e.g.
+Set to not build tools for the support of jails; e.g.,
.Xr jail 8 .
diff --git a/tools/build/options/WITHOUT_KERBEROS_SUPPORT b/tools/build/options/WITHOUT_KERBEROS_SUPPORT
index a724fbf..e8dd495 100644
--- a/tools/build/options/WITHOUT_KERBEROS_SUPPORT
+++ b/tools/build/options/WITHOUT_KERBEROS_SUPPORT
@@ -1,6 +1,5 @@
.\" $FreeBSD$
Set to build some programs without Kerberos support, like
-.Xr cvs 1 ,
.Xr ssh 1 ,
.Xr telnet 1 ,
.Xr sshd 8 ,
diff --git a/tools/build/options/WITHOUT_LEGACY_CONSOLE b/tools/build/options/WITHOUT_LEGACY_CONSOLE
index 85e8604..8f21d1e 100644
--- a/tools/build/options/WITHOUT_LEGACY_CONSOLE
+++ b/tools/build/options/WITHOUT_LEGACY_CONSOLE
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-Set to not build programs that support a legacy PC console; e.g.
+Set to not build programs that support a legacy PC console; e.g.,
.Xr kbdcontrol 8
and
.Xr vidcontrol 8 .
diff --git a/tools/build/options/WITHOUT_PKGTOOLS b/tools/build/options/WITHOUT_SVNLITE
index a1c7c56..61b66dc 100644
--- a/tools/build/options/WITHOUT_PKGTOOLS
+++ b/tools/build/options/WITHOUT_SVNLITE
@@ -1,4 +1,4 @@
.\" $FreeBSD$
Set to not build
-.Xr pkg_add 8
+.Xr svnlite 1
and related programs.
diff --git a/tools/build/options/WITH_ARM_EABI b/tools/build/options/WITH_ARM_EABI
deleted file mode 100644
index dba6e5f..0000000
--- a/tools/build/options/WITH_ARM_EABI
+++ /dev/null
@@ -1,2 +0,0 @@
-.\" $FreeBSD$
-Set the ARM ABI to EABI.
diff --git a/tools/build/options/WITH_BSDCONFIG b/tools/build/options/WITH_BSDCONFIG
deleted file mode 100644
index f3e6e25..0000000
--- a/tools/build/options/WITH_BSDCONFIG
+++ /dev/null
@@ -1,2 +0,0 @@
-.\" $FreeBSD$
-Set to install bsdconfig(8), a BSD-licensed configuration/management utility.
diff --git a/tools/build/options/WITH_BSD_PATCH b/tools/build/options/WITH_BSD_PATCH
deleted file mode 100644
index 8430d2a..0000000
--- a/tools/build/options/WITH_BSD_PATCH
+++ /dev/null
@@ -1,2 +0,0 @@
-.\" $FreeBSD$
-Install BSD-licensed patch as 'patch' instead of GNU patch.
diff --git a/tools/build/options/WITH_DEBUG_FILES b/tools/build/options/WITH_DEBUG_FILES
new file mode 100644
index 0000000..16eee2a
--- /dev/null
+++ b/tools/build/options/WITH_DEBUG_FILES
@@ -0,0 +1,7 @@
+.\" $FreeBSD$
+Set to strip debug info into a separate file for each executable binary
+and shared library.
+The debug files will be placed in a subdirectory of
+.Pa /usr/lib/debug
+and are located automatically by
+.Xr gdb 1 .
diff --git a/tools/build/options/WITH_ICONV b/tools/build/options/WITH_ICONV
deleted file mode 100644
index 7acbe44..0000000
--- a/tools/build/options/WITH_ICONV
+++ /dev/null
@@ -1,2 +0,0 @@
-.\" $FreeBSD$
-Set to build iconv as part of libc.
diff --git a/tools/build/options/WITH_IDEA b/tools/build/options/WITH_IDEA
deleted file mode 100644
index 785dfc6..0000000
--- a/tools/build/options/WITH_IDEA
+++ /dev/null
@@ -1,6 +0,0 @@
-.\" $FreeBSD$
-Set to build the IDEA encryption code.
-This code is patented in the USA and many European countries.
-It is
-.Em "YOUR RESPONSIBILITY"
-to determine if you can legally use IDEA.
diff --git a/tools/build/options/WITH_LIBICONV_COMPAT b/tools/build/options/WITH_LIBICONV_COMPAT
new file mode 100644
index 0000000..f414798
--- /dev/null
+++ b/tools/build/options/WITH_LIBICONV_COMPAT
@@ -0,0 +1,2 @@
+.\" $FreeBSD$
+Set to build libiconv API and link time compatibility.
diff --git a/tools/build/options/WITH_PKGTOOLS b/tools/build/options/WITH_PKGTOOLS
new file mode 100644
index 0000000..0c09224
--- /dev/null
+++ b/tools/build/options/WITH_PKGTOOLS
@@ -0,0 +1,4 @@
+.\" $FreeBSD$
+Set to build
+.Xr pkg_add 8
+and related programs.
diff --git a/tools/build/options/WITH_SVN b/tools/build/options/WITH_SVN
new file mode 100644
index 0000000..829a3a7
--- /dev/null
+++ b/tools/build/options/WITH_SVN
@@ -0,0 +1,5 @@
+.\" $FreeBSD$
+Set to install
+.Xr svnlite 1
+as
+.Xr svn 1 .
diff --git a/tools/build/options/WITH_USB_GADGET_EXAMPLES b/tools/build/options/WITH_USB_GADGET_EXAMPLES
new file mode 100644
index 0000000..2ecbdb7
--- /dev/null
+++ b/tools/build/options/WITH_USB_GADGET_EXAMPLES
@@ -0,0 +1,2 @@
+.\" $FreeBSD$
+Set to build USB gadget kernel modules.
diff --git a/tools/build/options/makeman b/tools/build/options/makeman
index 61c0776..cb4d946 100755
--- a/tools/build/options/makeman
+++ b/tools/build/options/makeman
@@ -3,6 +3,7 @@
# This file is in the public domain.
set -o errexit
+LC_ALL=C
ident='$FreeBSD$'
@@ -198,7 +199,12 @@ that can be used for source builds.
.Bl -tag -width indent
EOF
show settings SRCCONF=/dev/null | sort > $t/config_default
- show with SRCCONF=/dev/null | sort > $t/config_WITH_ALL
+ # Work around WITH_LDNS_UTILS forcing BIND_UTILS off by parsing the
+ # actual config that results from enabling every WITH_ option. This
+ # can be reverted if/when we no longer have options that disable
+ # others.
+ show with SRCCONF=/dev/null | sort | sed 's/$/=/' > $t/src.conf
+ show settings SRCCONF=$t/src.conf | sort > $t/config_WITH_ALL
show without SRCCONF=/dev/null | sort > $t/config_WITHOUT_ALL
show_options |
@@ -229,6 +235,18 @@ EOF
exit 1
fi
+ show settings SRCCONF=/dev/null -D${opt} | sort > $t/config_${opt}
+ comm -13 $t/config_default $t/config_${opt} | sed -n "/^${opt}$/!p" |
+ comm -13 $t/deps - > $t/deps2
+
+ # Work around BIND_UTILS=no being the default when every WITH_
+ # option is enabled.
+ if [ "$(cat $t/deps2)" = WITHOUT_BIND_UTILS ]; then
+ sort $t/deps $t/deps2 > $t/_deps
+ mv $t/_deps $t/deps
+ :> $t/deps2
+ fi
+
if [ -s $t/deps ] ; then
echo 'When set, it also enforces the following options:'
echo '.Pp'
@@ -240,10 +258,6 @@ EOF
echo '.El'
fi
- show settings SRCCONF=/dev/null -D${opt} | sort > $t/config_${opt}
- comm -13 $t/config_default $t/config_${opt} | sed -n "/^${opt}$/!p" |
- comm -13 $t/deps - > $t/deps2
-
if [ -s $t/deps2 ] ; then
if [ -s $t/deps ] ; then
echo '.Pp'
diff --git a/tools/regression/aio/aiop/aiop.c b/tools/regression/aio/aiop/aiop.c
index 31a977e..3e64dbe 100644
--- a/tools/regression/aio/aiop/aiop.c
+++ b/tools/regression/aio/aiop/aiop.c
@@ -39,6 +39,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -186,7 +187,7 @@ main(int argc, char *argv[])
perror("unknown file type\n");
exit(1);
}
- printf("File: %s; File size %qd bytes\n", fn, file_size);
+ printf("File: %s; File size %jd bytes\n", fn, (intmax_t)file_size);
aio = calloc(aio_len, sizeof(struct aiocb));
abuf = calloc(aio_len, sizeof(char *));
diff --git a/tools/regression/aio/aiotest/aiotest.c b/tools/regression/aio/aiotest/aiotest.c
index 60de273..48c7aba 100644
--- a/tools/regression/aio/aiotest/aiotest.c
+++ b/tools/regression/aio/aiotest/aiotest.c
@@ -49,6 +49,7 @@
#include <fcntl.h>
#include <libutil.h>
#include <limits.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -269,7 +270,7 @@ aio_write_test(struct aio_context *ac)
if (len != ac->ac_buflen) {
aio_cleanup(ac);
errx(-1, "FAIL: %s: aio_write_test: aio_waitcomplete: short "
- "write (%d)", ac->ac_test, len);
+ "write (%jd)", ac->ac_test, (intmax_t)len);
}
}
@@ -329,7 +330,7 @@ aio_read_test(struct aio_context *ac)
if (len != ac->ac_buflen) {
aio_cleanup(ac);
errx(-1, "FAIL: %s: aio_read_test: aio_waitcomplete: short "
- "read (%d)", ac->ac_test, len);
+ "read (%jd)", ac->ac_test, (intmax_t)len);
}
if (aio_test_buffer(ac->ac_buffer, ac->ac_buflen, ac->ac_seed) == 0) {
@@ -366,7 +367,7 @@ aio_file_cleanup(void *arg)
#define FILE_LEN GLOBAL_MAX
#define FILE_TIMEOUT 30
-static int
+static void
aio_file_test(void)
{
char pathname[PATH_MAX];
@@ -414,7 +415,7 @@ aio_fifo_cleanup(void *arg)
#define FIFO_LEN 256
#define FIFO_TIMEOUT 30
-static int
+static void
aio_fifo_test(void)
{
int error, read_fd = -1, write_fd = -1;
@@ -481,7 +482,7 @@ aio_unix_socketpair_cleanup(void *arg)
#define UNIX_SOCKETPAIR_LEN 256
#define UNIX_SOCKETPAIR_TIMEOUT 30
-static int
+static void
aio_unix_socketpair_test(void)
{
struct aio_unix_socketpair_arg arg;
@@ -515,13 +516,14 @@ aio_pty_cleanup(void *arg)
{
struct aio_pty_arg *apa;
+ apa = arg;
close(apa->apa_read_fd);
close(apa->apa_write_fd);
};
#define PTY_LEN 256
#define PTY_TIMEOUT 30
-static int
+static void
aio_pty_test(void)
{
struct aio_pty_arg arg;
@@ -573,7 +575,7 @@ aio_pipe_cleanup(void *arg)
#define PIPE_LEN 256
#define PIPE_TIMEOUT 30
-static int
+static void
aio_pipe_test(void)
{
struct aio_context ac;
@@ -628,7 +630,7 @@ aio_md_cleanup(void *arg)
#define MD_LEN GLOBAL_MAX
#define MD_TIMEOUT 30
-static int
+static void
aio_md_test(void)
{
int error, fd, i, mdctl_fd, unit;
diff --git a/tools/regression/bin/sh/builtins/alias4.0 b/tools/regression/bin/sh/builtins/alias4.0
new file mode 100644
index 0000000..3d5efec
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/alias4.0
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+unalias -a
+alias --
diff --git a/tools/regression/bin/sh/builtins/break4.4 b/tools/regression/bin/sh/builtins/break4.4
new file mode 100644
index 0000000..d52ff52
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/break4.4
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+# Although this is not specified by POSIX, some configure scripts (gawk 4.1.0)
+# appear to depend on it.
+
+break
+exit 4
diff --git a/tools/regression/bin/sh/builtins/break5.4 b/tools/regression/bin/sh/builtins/break5.4
new file mode 100644
index 0000000..7df8e18
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/break5.4
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+# Although this is not specified by POSIX, some configure scripts (gawk 4.1.0)
+# appear to depend on it.
+# In some uncommitted code, the subshell environment corrupted the outer
+# shell environment's state.
+
+(for i in a b c; do
+ exit 3
+done)
+break
+exit 4
diff --git a/tools/regression/bin/sh/builtins/jobid1.0 b/tools/regression/bin/sh/builtins/jobid1.0
new file mode 100644
index 0000000..483fda2
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/jobid1.0
@@ -0,0 +1,7 @@
+# $FreeBSD$
+# Non-standard builtin.
+
+: &
+p1=$!
+p2=$(jobid)
+[ "${p1:?}" = "${p2:?}" ]
diff --git a/tools/regression/bin/sh/builtins/jobid2.0 b/tools/regression/bin/sh/builtins/jobid2.0
new file mode 100644
index 0000000..101831a
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/jobid2.0
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+: &
+p1=$(jobid)
+p2=$(jobid --)
+p3=$(jobid %+)
+p4=$(jobid -- %+)
+[ "${p1:?}" = "${p2:?}" ] && [ "${p2:?}" = "${p3:?}" ] &&
+[ "${p3:?}" = "${p4:?}" ] && [ "${p4:?}" = "${p1:?}" ]
diff --git a/tools/regression/bin/sh/builtins/local2.0 b/tools/regression/bin/sh/builtins/local2.0
new file mode 100644
index 0000000..cc8c10f
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/local2.0
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+f() {
+ local -
+ set -a
+ case $- in
+ *a*) : ;;
+ *) echo In-function \$- bad
+ esac
+}
+case $- in
+*a*) echo Initial \$- bad
+esac
+f
+case $- in
+*a*) echo Final \$- bad
+esac
diff --git a/tools/regression/bin/sh/builtins/local3.0 b/tools/regression/bin/sh/builtins/local3.0
new file mode 100644
index 0000000..39ee370
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/local3.0
@@ -0,0 +1,26 @@
+# $FreeBSD$
+
+f() {
+ local "$@"
+ set -a
+ x=7
+ case $- in
+ *a*) : ;;
+ *) echo In-function \$- bad
+ esac
+ [ "$x" = 7 ] || echo In-function \$x bad
+}
+x=1
+case $- in
+*a*) echo Initial \$- bad
+esac
+f x -
+case $- in
+*a*) echo Intermediate \$- bad
+esac
+[ "$x" = 1 ] || echo Intermediate \$x bad
+f - x
+case $- in
+*a*) echo Final \$- bad
+esac
+[ "$x" = 1 ] || echo Final \$x bad
diff --git a/tools/regression/bin/sh/builtins/local4.0 b/tools/regression/bin/sh/builtins/local4.0
new file mode 100644
index 0000000..3955aaa
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/local4.0
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+f() {
+ local -- x
+ x=2
+ [ "$x" = 2 ]
+}
+x=1
+f || exit 3
+[ "$x" = 1 ] || exit 3
+f || exit 3
+[ "$x" = 1 ] || exit 3
diff --git a/tools/regression/bin/sh/builtins/read7.0 b/tools/regression/bin/sh/builtins/read7.0
new file mode 100644
index 0000000..e78f887
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/read7.0
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+{ errmsg=`read x <&- 2>&1 >&3`; } 3>&1
+r=$?
+[ "$r" -ge 2 ] && [ "$r" -le 128 ] && [ -n "$errmsg" ]
diff --git a/tools/regression/bin/sh/builtins/return8.0 b/tools/regression/bin/sh/builtins/return8.0
new file mode 100644
index 0000000..f00e859
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/return8.0
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+if [ "$1" = nested ]; then
+ return 17
+fi
+
+f() {
+ set -- nested
+ . "$0"
+ return $(($? ^ 1))
+}
+f
+exit $(($? ^ 16))
diff --git a/tools/regression/bin/sh/builtins/type3.0 b/tools/regression/bin/sh/builtins/type3.0
new file mode 100644
index 0000000..87cccdd
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/type3.0
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+[ "$(type type)" = "$(type -- type)" ]
diff --git a/tools/regression/bin/sh/builtins/wait10.0 b/tools/regression/bin/sh/builtins/wait10.0
new file mode 100644
index 0000000..864fc78
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/wait10.0
@@ -0,0 +1,5 @@
+# $FreeBSD$
+# Init cannot be a child of the shell.
+exit 49 & p49=$!
+wait 1 "$p49"
+[ "$?" = 49 ]
diff --git a/tools/regression/bin/sh/builtins/wait8.0 b/tools/regression/bin/sh/builtins/wait8.0
new file mode 100644
index 0000000..b59ff59
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/wait8.0
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+exit 44 & p44=$!
+exit 45 & p45=$!
+exit 7 & p7=$!
+wait "$p44" "$p7" "$p45"
+[ "$?" = 45 ]
diff --git a/tools/regression/bin/sh/builtins/wait9.127 b/tools/regression/bin/sh/builtins/wait9.127
new file mode 100644
index 0000000..661f275
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/wait9.127
@@ -0,0 +1,3 @@
+# $FreeBSD$
+# Init cannot be a child of the shell.
+wait 1
diff --git a/tools/regression/bin/sh/execution/int-cmd1.0 b/tools/regression/bin/sh/execution/int-cmd1.0
new file mode 100644
index 0000000..a1f097b
--- /dev/null
+++ b/tools/regression/bin/sh/execution/int-cmd1.0
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+! echo echo bad | $SH -ic 'fi' 2>/dev/null
diff --git a/tools/regression/bin/sh/expansion/arith13.0 b/tools/regression/bin/sh/expansion/arith13.0
new file mode 100644
index 0000000..207e488
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/arith13.0
@@ -0,0 +1,6 @@
+# $FreeBSD$
+# Pre-increment and pre-decrement in arithmetic expansion are not in POSIX.
+# Require either an error or a correct implementation.
+
+! (eval 'x=4; [ $((++x)) != 5 ] || [ $x != 5 ]') 2>/dev/null &&
+! (eval 'x=2; [ $((--x)) != 1 ] || [ $x != 1 ]') 2>/dev/null
diff --git a/tools/regression/bin/sh/parser/empty-cmd1.0 b/tools/regression/bin/sh/parser/empty-cmd1.0
new file mode 100644
index 0000000..f8b01e9
--- /dev/null
+++ b/tools/regression/bin/sh/parser/empty-cmd1.0
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+! (eval ': || f()') 2>/dev/null
diff --git a/tools/regression/bin/sh/parser/only-redir2.0 b/tools/regression/bin/sh/parser/only-redir2.0
new file mode 100644
index 0000000..b9e9501
--- /dev/null
+++ b/tools/regression/bin/sh/parser/only-redir2.0
@@ -0,0 +1,2 @@
+# $FreeBSD$
+</dev/null | :
diff --git a/tools/regression/bin/sh/parser/only-redir3.0 b/tools/regression/bin/sh/parser/only-redir3.0
new file mode 100644
index 0000000..128a483
--- /dev/null
+++ b/tools/regression/bin/sh/parser/only-redir3.0
@@ -0,0 +1,2 @@
+# $FreeBSD$
+case x in x) </dev/null ;; esac
diff --git a/tools/regression/bin/sh/parser/only-redir4.0 b/tools/regression/bin/sh/parser/only-redir4.0
new file mode 100644
index 0000000..d804e12
--- /dev/null
+++ b/tools/regression/bin/sh/parser/only-redir4.0
@@ -0,0 +1,2 @@
+# $FreeBSD$
+case x in x) </dev/null ;& esac
diff --git a/tools/regression/bin/test/regress.sh b/tools/regression/bin/test/regress.sh
index 117a7e2..9229551 100644
--- a/tools/regression/bin/test/regress.sh
+++ b/tools/regression/bin/test/regress.sh
@@ -52,7 +52,7 @@ t ()
}
count=0
-echo "1..266"
+echo "1..130"
t 0 'b = b'
t 0 'b == b'
@@ -194,66 +194,3 @@ t 1 '\( ! -a \)'
t 0 '\( -n -o \)'
t 1 '\( -z -o \)'
t 1 '\( ! -o \)'
-
-# Test all file timestamp comparison operators
-s() {
- t ${1} "${35} -nt ${36}"
- t ${2} "${35} -ntaa ${36}"
- t ${3} "${35} -ntab ${36}"
- t ${4} "${35} -ntac ${36}"
- t ${5} "${35} -ntam ${36}"
- t ${6} "${35} -ntba ${36}"
- t ${7} "${35} -ntbb ${36}"
- t ${8} "${35} -ntbc ${36}"
- t ${9} "${35} -ntbm ${36}"
- t ${10} "${35} -ntca ${36}"
- t ${11} "${35} -ntcb ${36}"
- t ${12} "${35} -ntcc ${36}"
- t ${13} "${35} -ntcm ${36}"
- t ${14} "${35} -ntma ${36}"
- t ${15} "${35} -ntmb ${36}"
- t ${16} "${35} -ntmc ${36}"
- t ${17} "${35} -ntmm ${36}"
- t ${18} "${35} -ot ${36}"
- t ${19} "${35} -otaa ${36}"
- t ${20} "${35} -otab ${36}"
- t ${21} "${35} -otac ${36}"
- t ${22} "${35} -otam ${36}"
- t ${23} "${35} -otba ${36}"
- t ${24} "${35} -otbb ${36}"
- t ${25} "${35} -otbc ${36}"
- t ${26} "${35} -otbm ${36}"
- t ${27} "${35} -otca ${36}"
- t ${28} "${35} -otcb ${36}"
- t ${29} "${35} -otcc ${36}"
- t ${30} "${35} -otcm ${36}"
- t ${31} "${35} -otma ${36}"
- t ${32} "${35} -otmb ${36}"
- t ${33} "${35} -otmc ${36}"
- t ${34} "${35} -otmm ${36}"
-}
-
-a=/tmp/test$$.1
-b=/tmp/test$$.2
-trap "rm -f $a $b" EXIT
-
-# Tests 131-164
-s 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 $a $b
-
-touch $a
-# Tests 165-198
-s 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 $a $b
-
-sleep 2 # Ensure $b is newer than $a
-touch $b
-# Tests 199-232
-s 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 $a $b
-
-sleep 2
-echo >$b # Updates mtime & ctime
-sleep 2
-touch -A 01 -a $b
-
-# $b now has ctime > mtime > atime > btime
-# Tests 233-266
-s 1 1 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1 $b $b
diff --git a/tools/regression/file/dup/dup.c b/tools/regression/file/dup/dup.c
index b0d9af2..8173818 100644
--- a/tools/regression/file/dup/dup.c
+++ b/tools/regression/file/dup/dup.c
@@ -29,6 +29,25 @@
* duped fd.
* Test #17: check if fcntl(F_DUP2FD) to a fd > current maximum number of open
* files limit work.
+ * Test #18: check if fcntl(F_DUPFD_CLOEXEC) works.
+ * Test #19: check if fcntl(F_DUPFD_CLOEXEC) set close-on-exec flag for duped
+ * fd.
+ * Test #20: check if fcntl(F_DUP2FD_CLOEXEC) works.
+ * Test #21: check if fcntl(F_DUP2FD_CLOEXEC) returned a fd we asked for.
+ * Test #22: check if fcntl(F_DUP2FD_CLOEXEC) set close-on-exec flag for duped
+ * fd.
+ * Test #23: check if fcntl(F_DUP2FD_CLOEXEC) to a fd > current maximum number
+ * of open files limit work.
+ * Test #24: check if dup3(O_CLOEXEC) works.
+ * Test #25: check if dup3(O_CLOEXEC) returned a fd we asked for.
+ * Test #26: check if dup3(O_CLOEXEC) set close-on-exec flag for duped fd.
+ * Test #27: check if dup3(0) works.
+ * Test #28: check if dup3(0) returned a fd we asked for.
+ * Test #29: check if dup3(0) cleared close-on-exec flag for duped fd.
+ * Test #30: check if dup3(O_CLOEXEC) fails if oldfd == newfd.
+ * Test #31: check if dup3(0) fails if oldfd == newfd.
+ * Test #32: check if dup3(O_CLOEXEC) to a fd > current maximum number of
+ * open files limit work.
*/
#include <sys/types.h>
@@ -65,7 +84,7 @@ main(int __unused argc, char __unused *argv[])
orgfd = getafile();
- printf("1..17\n");
+ printf("1..32\n");
/* If dup(2) ever work? */
if ((fd1 = dup(orgfd)) < 0)
@@ -144,9 +163,13 @@ main(int __unused argc, char __unused *argv[])
printf("ok %d - dup2(2) didn't clear close-on-exec\n", test);
/* Does fcntl(F_DUPFD) work? */
- if ((fd2 = fcntl(fd1, F_DUPFD)) < 0)
+ if ((fd2 = fcntl(fd1, F_DUPFD, 10)) < 0)
err(1, "fcntl(F_DUPFD)");
- printf("ok %d - fcntl(F_DUPFD) works\n", ++test);
+ if (fd2 < 10)
+ printf("not ok %d - fcntl(F_DUPFD) returned wrong fd %d\n",
+ ++test, fd2);
+ else
+ printf("ok %d - fcntl(F_DUPFD) works\n", ++test);
/* Was close-on-exec cleared? */
++test;
@@ -225,5 +248,139 @@ main(int __unused argc, char __unused *argv[])
printf("ok %d - fcntl(F_DUP2FD) didn't bypass NOFILE limit\n",
test);
+ /* Does fcntl(F_DUPFD_CLOEXEC) work? */
+ if ((fd2 = fcntl(fd1, F_DUPFD_CLOEXEC, 10)) < 0)
+ err(1, "fcntl(F_DUPFD_CLOEXEC)");
+ if (fd2 < 10)
+ printf("not ok %d - fcntl(F_DUPFD_CLOEXEC) returned wrong fd %d\n",
+ ++test, fd2);
+ else
+ printf("ok %d - fcntl(F_DUPFD_CLOEXEC) works\n", ++test);
+
+ /* Was close-on-exec cleared? */
+ ++test;
+ if (fcntl(fd2, F_GETFD) != 1)
+ printf(
+ "not ok %d - fcntl(F_DUPFD_CLOEXEC) didn't set close-on-exec\n",
+ test);
+ else
+ printf("ok %d - fcntl(F_DUPFD_CLOEXEC) set close-on-exec\n",
+ test);
+
+ /* If fcntl(F_DUP2FD_CLOEXEC) ever work? */
+ if ((fd2 = fcntl(fd1, F_DUP2FD_CLOEXEC, fd1 + 1)) < 0)
+ err(1, "fcntl(F_DUP2FD_CLOEXEC)");
+ printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) works\n", ++test);
+
+ /* Do we get the right fd? */
+ ++test;
+ if (fd2 != fd1 + 1)
+ printf(
+ "no ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't give us the right fd\n",
+ test);
+ else
+ printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) returned a correct fd\n",
+ test);
+
+ /* Was close-on-exec set? */
+ ++test;
+ if (fcntl(fd2, F_GETFD) != FD_CLOEXEC)
+ printf(
+ "not ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't set close-on-exec\n",
+ test);
+ else
+ printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) set close-on-exec\n",
+ test);
+
+ /*
+ * It is unclear what F_DUP2FD_CLOEXEC should do when duplicating a
+ * file descriptor onto itself.
+ */
+
+ ++test;
+ if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
+ err(1, "getrlimit");
+ if ((fd2 = fcntl(fd1, F_DUP2FD_CLOEXEC, rlp.rlim_cur + 1)) >= 0)
+ printf("not ok %d - fcntl(F_DUP2FD_CLOEXEC) bypassed NOFILE limit\n",
+ test);
+ else
+ printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't bypass NOFILE limit\n",
+ test);
+
+ /* Does dup3(O_CLOEXEC) ever work? */
+ if ((fd2 = dup3(fd1, fd1 + 1, O_CLOEXEC)) < 0)
+ err(1, "dup3(O_CLOEXEC)");
+ printf("ok %d - dup3(O_CLOEXEC) works\n", ++test);
+
+ /* Do we get the right fd? */
+ ++test;
+ if (fd2 != fd1 + 1)
+ printf(
+ "no ok %d - dup3(O_CLOEXEC) didn't give us the right fd\n",
+ test);
+ else
+ printf("ok %d - dup3(O_CLOEXEC) returned a correct fd\n",
+ test);
+
+ /* Was close-on-exec set? */
+ ++test;
+ if (fcntl(fd2, F_GETFD) != FD_CLOEXEC)
+ printf(
+ "not ok %d - dup3(O_CLOEXEC) didn't set close-on-exec\n",
+ test);
+ else
+ printf("ok %d - dup3(O_CLOEXEC) set close-on-exec\n",
+ test);
+
+ /* Does dup3(0) ever work? */
+ if ((fd2 = dup3(fd1, fd1 + 1, 0)) < 0)
+ err(1, "dup3(0)");
+ printf("ok %d - dup3(0) works\n", ++test);
+
+ /* Do we get the right fd? */
+ ++test;
+ if (fd2 != fd1 + 1)
+ printf(
+ "no ok %d - dup3(0) didn't give us the right fd\n",
+ test);
+ else
+ printf("ok %d - dup3(0) returned a correct fd\n",
+ test);
+
+ /* Was close-on-exec cleared? */
+ ++test;
+ if (fcntl(fd2, F_GETFD) != 0)
+ printf(
+ "not ok %d - dup3(0) didn't clear close-on-exec\n",
+ test);
+ else
+ printf("ok %d - dup3(0) cleared close-on-exec\n",
+ test);
+
+ /* dup3() does not allow duplicating to the same fd */
+ ++test;
+ if (dup3(fd1, fd1, O_CLOEXEC) != -1)
+ printf(
+ "not ok %d - dup3(fd1, fd1, O_CLOEXEC) succeeded\n", test);
+ else
+ printf("ok %d - dup3(fd1, fd1, O_CLOEXEC) failed\n", test);
+
+ ++test;
+ if (dup3(fd1, fd1, 0) != -1)
+ printf(
+ "not ok %d - dup3(fd1, fd1, 0) succeeded\n", test);
+ else
+ printf("ok %d - dup3(fd1, fd1, 0) failed\n", test);
+
+ ++test;
+ if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
+ err(1, "getrlimit");
+ if ((fd2 = dup3(fd1, rlp.rlim_cur + 1, O_CLOEXEC)) >= 0)
+ printf("not ok %d - dup3(O_CLOEXEC) bypassed NOFILE limit\n",
+ test);
+ else
+ printf("ok %d - dup3(O_CLOEXEC) didn't bypass NOFILE limit\n",
+ test);
+
return (0);
}
diff --git a/tools/regression/file/fcntlflags/Makefile b/tools/regression/file/fcntlflags/Makefile
new file mode 100644
index 0000000..9e7fc3e
--- /dev/null
+++ b/tools/regression/file/fcntlflags/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+PROG= fcntlflags
+MAN=
+WARNS?= 6
+
+.include <bsd.prog.mk>
diff --git a/tools/regression/file/fcntlflags/fcntlflags.c b/tools/regression/file/fcntlflags/fcntlflags.c
new file mode 100644
index 0000000..bcb3b54
--- /dev/null
+++ b/tools/regression/file/fcntlflags/fcntlflags.c
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2013 Jilles Tjoelker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/*
+ * O_ACCMODE is currently defined incorrectly. This is what it should be.
+ * Various code depends on the incorrect value.
+ */
+#define CORRECT_O_ACCMODE (O_ACCMODE | O_EXEC)
+
+static int testnum;
+
+static void
+subtests(const char *path, int omode, const char *omodetext)
+{
+ int fd, flags1, flags2, flags3;
+
+ fd = open(path, omode);
+ if (fd == -1)
+ printf("not ok %d - open(\"%s\", %s) failed\n",
+ testnum++, path, omodetext);
+ else
+ printf("ok %d - open(\"%s\", %s) succeeded\n",
+ testnum++, path, omodetext);
+ flags1 = fcntl(fd, F_GETFL);
+ if (flags1 == -1)
+ printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
+ else if ((flags1 & CORRECT_O_ACCMODE) == omode)
+ printf("ok %d - fcntl(F_GETFL) gave correct result\n",
+ testnum++);
+ else
+ printf("not ok %d - fcntl(F_GETFL) gave incorrect result "
+ "(%#x & %#x != %#x)\n",
+ testnum++, flags1, CORRECT_O_ACCMODE, omode);
+ if (fcntl(fd, F_SETFL, flags1) == -1)
+ printf("not ok %d - fcntl(F_SETFL) same flags failed\n",
+ testnum++);
+ else
+ printf("ok %d - fcntl(F_SETFL) same flags succeeded\n",
+ testnum++);
+ flags2 = fcntl(fd, F_GETFL);
+ if (flags2 == -1)
+ printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
+ else if (flags2 == flags1)
+ printf("ok %d - fcntl(F_GETFL) gave same result\n",
+ testnum++);
+ else
+ printf("not ok %d - fcntl(F_SETFL) caused fcntl(F_GETFL) to "
+ "change from %#x to %#x\n",
+ testnum++, flags1, flags2);
+ if (fcntl(fd, F_SETFL, flags2 | O_NONBLOCK) == -1)
+ printf("not ok %d - fcntl(F_SETFL) O_NONBLOCK failed\n",
+ testnum++);
+ else
+ printf("ok %d - fcntl(F_SETFL) O_NONBLOCK succeeded\n",
+ testnum++);
+ flags3 = fcntl(fd, F_GETFL);
+ if (flags3 == -1)
+ printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
+ else if (flags3 == (flags2 | O_NONBLOCK))
+ printf("ok %d - fcntl(F_GETFL) gave expected result\n",
+ testnum++);
+ else
+ printf("not ok %d - fcntl(F_SETFL) gave unexpected result "
+ "(%#x != %#x)\n",
+ testnum++, flags3, flags2 | O_NONBLOCK);
+ (void)close(fd);
+}
+
+int
+main(int argc __unused, char **argv __unused)
+{
+ printf("1..24\n");
+ testnum = 1;
+ subtests("/dev/null", O_RDONLY, "O_RDONLY");
+ subtests("/dev/null", O_WRONLY, "O_WRONLY");
+ subtests("/dev/null", O_RDWR, "O_RDWR");
+ subtests("/bin/sh", O_EXEC, "O_EXEC");
+ return (0);
+}
diff --git a/tools/regression/file/fcntlflags/fcntlflags.t b/tools/regression/file/fcntlflags/fcntlflags.t
new file mode 100644
index 0000000..8bdfd03
--- /dev/null
+++ b/tools/regression/file/fcntlflags/fcntlflags.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+executable=`basename $0 .t`
+
+make $executable 2>&1 > /dev/null
+
+exec ./$executable
diff --git a/tools/regression/filemon/Makefile b/tools/regression/filemon/Makefile
index d92d20f..62a5296 100644
--- a/tools/regression/filemon/Makefile
+++ b/tools/regression/filemon/Makefile
@@ -1,10 +1,20 @@
# $FreeBSD$
-BINS= \
+.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64"
+BI_BITS=
+.endif
+
+_BINS= \
filemontest \
- timed-forkb
+ timed-forkb \
+ sizeof_long
+
+BINS= ${_BINS}
+.if defined(BI_BITS)
+BINS+= ${_BINS:C/$/32/g}
+.endif
-bins: filemontest timed-forkb
+bins: ${BINS}
all: bins
NO_MAN=
@@ -18,20 +28,25 @@ WITHOUT_CDDL=
CLEANFILES+= ${BINS}
-tests: bins
+
+.for f32 in ${BINS}
+${f32}32: ${f32}.c
+ ${CC} -m32 -DBIT=\"32\" -o ${.TARGET} ${CFLAGS} ${.ALLSRC}
+.endfor
+
+tests:
kldstat | grep filemon
- ${MAKE} test
- @echo "Without filemon(4) active:"
- ./timed-forkb
- @echo "With filemon(4) active:"
- script -f typescript-timed-forkb ./timed-forkb
- ls -l typescript-timed-forkb.filemon
+ @echo ""
+ ${MAKE} test01
+ ${MAKE} test02
+.if defined(BI_BITS)
+ ${MAKE} test32
+.endif
@echo "filemon(4) tests passed."
# Cannot use .OBJDIR -- 'filemontest' expects 'test_script.sh' in .
-#FILEMONTEST32= filemontest32
-test: filemontest clean-test
-.for BIN in filemontest ${FILEMONTEST32}
+test01: ${BINS:Mfilemontest*} ${BINS:Msizeof_long*} clean-test
+.for BIN in ${BINS:Mfilemontest}
cd ${.CURDIR} ; \
for A in 1 2 3 4 5 6 7 8 9 0; do \
for B in 1 2 3 4 5 6 7 8 9 0; do \
@@ -41,13 +56,30 @@ test: filemontest clean-test
done ;\
done
@cd ${.CURDIR} ; set +e ; egrep '(Start|Stop) .*\.' filemon_log.* | \
- grep -q -v '\.[0-9][0-9][0-9][0-9][0-9][0-9]$$' || echo "Time stamp format OK"
+ grep -q -v '\.[0-9][0-9][0-9][0-9][0-9][0-9]$$' || printf "Time stamp format OK\n\n"
.endfor
+ @cd ${.CURDIR} ; set +e ; for F in filemon_log.* ; do \
+ tail -1 $$F | grep -q '# Bye bye' || echo "$$F missing filemon bye-bye" ; \
+ NL=`wc -l $$F | awk '{print $$1}'` ; \
+ if [ "$${NL}" != 97 ]; then echo "$$F BAD, contains $${NL} lines" ; exit 1 ; fi ; done
+
+test02: ${BINS:Mtimed-forkb*}
+ @echo "Without filemon(4) active:"
+ ./timed-forkb
+ @echo "With filemon(4) active:"
+ script -f typescript-timed-forkb ./timed-forkb
+ ls -l typescript-timed-forkb.filemon
+
+test32: ${BINS:M*32*}
+ script -f typescript.${.TARGET} ./sizeof_long32 >/dev/null
+ @tail -1 typescript.test32.filemon | grep -q '# Bye bye' || (echo '32-bit comapt filemon Missing "bye-bye"' ; exit 1)
+ @egrep -q '^X [0-9]+ 0$$' typescript.test32.filemon || (echo "32-bit binary exit ERROR" ; exit 1)
+ @printf "filemon(4) 32bit FreeBSD support passed.\n\n"
CLEANFILES+= typescript-timed-forkb typescript-timed-forkb.filemon
clean-test:
- cd ${.CURDIR} ; rm -f filemon_log.*
+ cd ${.CURDIR} ; rm -f filemon_log*.*
clean-tests: clean-test
diff --git a/tools/regression/filemon/filemontest.c b/tools/regression/filemon/filemontest.c
index 6f02547..03b53e2 100644
--- a/tools/regression/filemon/filemontest.c
+++ b/tools/regression/filemon/filemontest.c
@@ -43,9 +43,13 @@ __FBSDID("$FreeBSD$");
* "test_script.sh" in the cwd.
*/
+#ifndef BIT
+#define BIT ""
+#endif
+
int
main(void) {
- char log_name[] = "filemon_log.XXXXXX";
+ char log_name[] = "filemon_log" BIT ".XXXXXX";
pid_t child;
int fm_fd, fm_log;
@@ -66,7 +70,7 @@ main(void) {
child = getpid();
if (ioctl(fm_fd, FILEMON_SET_PID, &child) == -1)
err(1, "Cannot set filemon PID to %d", child);
- system("./test_script.sh");
+ system("env BIT=" BIT " ./test_script.sh");
break;
case -1:
err(1, "Cannot fork");
diff --git a/tools/regression/filemon/test_script.sh b/tools/regression/filemon/test_script.sh
index df34ec4..b69c238 100755
--- a/tools/regression/filemon/test_script.sh
+++ b/tools/regression/filemon/test_script.sh
@@ -41,3 +41,4 @@ ed -s $f1 < $f2
#w" | ed -s $f1
#rm $f1 $f2
uptime > /dev/null
+sizeof_long${BIT} > /dev/null
diff --git a/tools/regression/filemon/timed-forkb.c b/tools/regression/filemon/timed-forkb.c
index a7df999..b7a0221 100644
--- a/tools/regression/filemon/timed-forkb.c
+++ b/tools/regression/filemon/timed-forkb.c
@@ -45,7 +45,7 @@
#define SLEEP 20 /* seconds */
#endif
-int verbose;
+static int verbose;
static void
usage(void)
diff --git a/tools/regression/geom_uzip/.cvsignore b/tools/regression/geom_uzip/.cvsignore
deleted file mode 100644
index 1e4f164..0000000
--- a/tools/regression/geom_uzip/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-test-1.img
-test-1.img.gz
diff --git a/tools/regression/include/stdatomic/Makefile b/tools/regression/include/stdatomic/Makefile
new file mode 100644
index 0000000..1ddd01a
--- /dev/null
+++ b/tools/regression/include/stdatomic/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+PROG= logic
+WARNS=6
+NO_MAN=
+
+.include <bsd.prog.mk>
diff --git a/tools/regression/include/stdatomic/logic.c b/tools/regression/include/stdatomic/logic.c
new file mode 100644
index 0000000..9659983
--- /dev/null
+++ b/tools/regression/include/stdatomic/logic.c
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 2013 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <stdatomic.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Tool for testing the logical behaviour of operations on atomic
+ * integer types. These tests make no attempt to actually test whether
+ * the functions are atomic or provide the right barrier semantics.
+ *
+ * For every type, we create an array of 16 elements and repeat the test
+ * on every element in the array. This allows us to test whether the
+ * atomic operations have no effect on surrounding values. This is
+ * especially useful for the smaller integer types, as it may be the
+ * case that these operations are implemented by processing entire words
+ * (e.g. on MIPS).
+ */
+
+static inline intmax_t
+rndnum(void)
+{
+ intmax_t v;
+
+ arc4random_buf(&v, sizeof(v));
+ return (v);
+}
+
+#define DO_FETCH_TEST(T, a, name, result) do { \
+ T v1 = atomic_load(a); \
+ T v2 = rndnum(); \
+ assert(atomic_##name(a, v2) == v1); \
+ assert(atomic_load(a) == (T)(result)); \
+} while (0)
+
+#define DO_COMPARE_EXCHANGE_TEST(T, a, name) do { \
+ T v1 = atomic_load(a); \
+ T v2 = rndnum(); \
+ T v3 = rndnum(); \
+ if (atomic_compare_exchange_##name(a, &v2, v3)) \
+ assert(v1 == v2); \
+ else \
+ assert(atomic_compare_exchange_##name(a, &v2, v3)); \
+ assert(atomic_load(a) == v3); \
+} while (0)
+
+#define DO_ALL_TESTS(T, a) do { \
+ { \
+ T v1 = rndnum(); \
+ atomic_init(a, v1); \
+ assert(atomic_load(a) == v1); \
+ } \
+ { \
+ T v1 = rndnum(); \
+ atomic_store(a, v1); \
+ assert(atomic_load(a) == v1); \
+ } \
+ \
+ DO_FETCH_TEST(T, a, exchange, v2); \
+ DO_FETCH_TEST(T, a, fetch_add, v1 + v2); \
+ DO_FETCH_TEST(T, a, fetch_and, v1 & v2); \
+ DO_FETCH_TEST(T, a, fetch_or, v1 | v2); \
+ DO_FETCH_TEST(T, a, fetch_sub, v1 - v2); \
+ DO_FETCH_TEST(T, a, fetch_xor, v1 ^ v2); \
+ \
+ DO_COMPARE_EXCHANGE_TEST(T, a, weak); \
+ DO_COMPARE_EXCHANGE_TEST(T, a, strong); \
+} while (0)
+
+#define TEST_TYPE(T) do { \
+ int j; \
+ struct { _Atomic(T) v[16]; } list, cmp; \
+ arc4random_buf(&cmp, sizeof(cmp)); \
+ for (j = 0; j < 16; j++) { \
+ list = cmp; \
+ DO_ALL_TESTS(T, &list.v[j]); \
+ list.v[j] = cmp.v[j]; \
+ assert(memcmp(&list, &cmp, sizeof(list)) == 0); \
+ } \
+} while (0)
+
+int
+main(void)
+{
+ int i;
+
+ for (i = 0; i < 1000; i++) {
+ TEST_TYPE(int8_t);
+ TEST_TYPE(uint8_t);
+ TEST_TYPE(int16_t);
+ TEST_TYPE(uint16_t);
+ TEST_TYPE(int32_t);
+ TEST_TYPE(uint32_t);
+ TEST_TYPE(int64_t);
+ TEST_TYPE(uint64_t);
+ }
+
+ return (0);
+}
diff --git a/tools/regression/lib/libc/gen/Makefile b/tools/regression/lib/libc/gen/Makefile
index 4b29ad0..4cba5de 100644
--- a/tools/regression/lib/libc/gen/Makefile
+++ b/tools/regression/lib/libc/gen/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
TESTS= test-arc4random test-fmtcheck test-fmtmsg test-fnmatch \
- test-fpclassify test-ftw test-posix_spawn test-wordexp
+ test-fpclassify test-ftw test-popen test-posix_spawn test-wordexp
.PHONY: tests
tests: ${TESTS}
diff --git a/tools/regression/lib/libc/gen/test-fnmatch.c b/tools/regression/lib/libc/gen/test-fnmatch.c
index 2544067..fd33574 100644
--- a/tools/regression/lib/libc/gen/test-fnmatch.c
+++ b/tools/regression/lib/libc/gen/test-fnmatch.c
@@ -135,6 +135,8 @@ struct testcase {
"\\[", "\\[", 0, FNM_NOMATCH,
"\\(", "\\(", 0, FNM_NOMATCH,
"\\a", "\\a", 0, FNM_NOMATCH,
+ "\\", "\\", 0, FNM_NOMATCH,
+ "\\", "", 0, 0,
"\\*", "\\*", FNM_NOESCAPE, 0,
"\\?", "\\?", FNM_NOESCAPE, 0,
"\\", "\\", FNM_NOESCAPE, 0,
@@ -236,6 +238,8 @@ write_sh_tests(const char *progname, int num)
if (strchr(t->pattern, '\'') != NULL ||
strchr(t->string, '\'') != NULL)
continue;
+ if (t->flags == 0 && strcmp(t->pattern, "\\") == 0)
+ continue;
if (num == 1 && t->flags == 0)
printf("test%smatch '%s' '%s'\n",
t->result == FNM_NOMATCH ? "no" : "",
diff --git a/tools/regression/lib/libc/gen/test-fpclassify.c b/tools/regression/lib/libc/gen/test-fpclassify.c
index 8431fe8..799c134 100644
--- a/tools/regression/lib/libc/gen/test-fpclassify.c
+++ b/tools/regression/lib/libc/gen/test-fpclassify.c
@@ -28,6 +28,7 @@
#include <assert.h>
#include <math.h>
+#include <stdio.h>
#include <stdlib.h>
int
diff --git a/tools/regression/lib/libc/gen/test-ftw.c b/tools/regression/lib/libc/gen/test-ftw.c
index adb0a17..209f033 100644
--- a/tools/regression/lib/libc/gen/test-ftw.c
+++ b/tools/regression/lib/libc/gen/test-ftw.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/wait.h>
#include <assert.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <ftw.h>
@@ -41,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <spawn.h>
+#include <unistd.h>
extern char **environ;
diff --git a/tools/regression/lib/libc/gen/test-popen.c b/tools/regression/lib/libc/gen/test-popen.c
new file mode 100644
index 0000000..bf301d2
--- /dev/null
+++ b/tools/regression/lib/libc/gen/test-popen.c
@@ -0,0 +1,227 @@
+/*-
+ * Copyright (c) 2013 Jilles Tjoelker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Limited test program for popen() as specified by IEEE Std. 1003.1-2008,
+ * with BSD extensions.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int failures;
+static volatile sig_atomic_t got_sigpipe;
+
+static void
+sigpipe_handler(int sig __unused)
+{
+ got_sigpipe = 1;
+}
+
+static void
+check_cloexec(FILE *fp, const char *mode)
+{
+ int flags;
+
+ flags = fcntl(fileno(fp), F_GETFD);
+ if (flags == -1)
+ fprintf(stderr, "fcntl(F_GETFD) failed\n"), failures++;
+ else if ((flags & FD_CLOEXEC) !=
+ (strchr(mode, 'e') != NULL ? FD_CLOEXEC : 0))
+ fprintf(stderr, "Bad cloexec flag\n"), failures++;
+}
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fp, *fp2;
+ int i, j, status;
+ const char *mode;
+ const char *allmodes[] = { "r", "w", "r+", "re", "we", "r+e", "re+" };
+ const char *rmodes[] = { "r", "r+", "re", "r+e", "re+" };
+ const char *wmodes[] = { "w", "r+", "we", "r+e", "re+" };
+ const char *rwmodes[] = { "r+", "r+e", "re+" };
+ char buf[80];
+ struct sigaction act, oact;
+
+ for (i = 0; i < sizeof(allmodes) / sizeof(allmodes[0]); i++) {
+ mode = allmodes[i];
+ fp = popen("exit 7", mode);
+ if (fp == NULL) {
+ fprintf(stderr, "popen(, \"%s\") failed", mode);
+ failures++;
+ continue;
+ }
+ check_cloexec(fp, mode);
+ status = pclose(fp);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 7)
+ fprintf(stderr, "Bad exit status (no I/O)\n"), failures++;
+ }
+
+ for (i = 0; i < sizeof(rmodes) / sizeof(rmodes[0]); i++) {
+ mode = rmodes[i];
+ fp = popen("exit 9", mode);
+ if (fp == NULL) {
+ fprintf(stderr, "popen(, \"%s\") failed", mode);
+ failures++;
+ continue;
+ }
+ check_cloexec(fp, mode);
+ if (fgetc(fp) != EOF || !feof(fp) || ferror(fp))
+ fprintf(stderr, "Input error 1\n"), failures++;
+ status = pclose(fp);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 9)
+ fprintf(stderr, "Bad exit status (input)\n"), failures++;
+ }
+
+ for (i = 0; i < sizeof(rmodes) / sizeof(rmodes[0]); i++) {
+ mode = rmodes[i];
+ fp = popen("echo hi there", mode);
+ if (fp == NULL) {
+ fprintf(stderr, "popen(, \"%s\") failed", mode);
+ failures++;
+ continue;
+ }
+ check_cloexec(fp, mode);
+ if (fgets(buf, sizeof(buf), fp) == NULL)
+ fprintf(stderr, "Input error 2\n"), failures++;
+ else if (strcmp(buf, "hi there\n") != 0)
+ fprintf(stderr, "Bad input 1\n"), failures++;
+ status = pclose(fp);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ fprintf(stderr, "Bad exit status (input)\n"), failures++;
+ }
+
+ for (i = 0; i < sizeof(wmodes) / sizeof(wmodes[0]); i++) {
+ mode = wmodes[i];
+ fp = popen("read x && [ \"$x\" = abcd ]", mode);
+ if (fp == NULL) {
+ fprintf(stderr, "popen(, \"%s\") failed", mode);
+ failures++;
+ continue;
+ }
+ check_cloexec(fp, mode);
+ if (fputs("abcd\n", fp) == EOF)
+ fprintf(stderr, "Output error 1\n"), failures++;
+ status = pclose(fp);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ fprintf(stderr, "Bad exit status (output)\n"), failures++;
+ }
+
+ act.sa_handler = sigpipe_handler;
+ act.sa_flags = SA_RESTART;
+ sigemptyset(&act.sa_mask);
+ if (sigaction(SIGPIPE, &act, &oact) == -1)
+ fprintf(stderr, "sigaction() failed\n"), failures++;
+ for (i = 0; i < sizeof(wmodes) / sizeof(wmodes[0]); i++) {
+ mode = wmodes[i];
+ fp = popen("exit 88", mode);
+ if (fp == NULL) {
+ fprintf(stderr, "popen(, \"%s\") failed", mode);
+ failures++;
+ continue;
+ }
+ check_cloexec(fp, mode);
+ got_sigpipe = 0;
+ while (fputs("abcd\n", fp) != EOF)
+ ;
+ if (!ferror(fp) || errno != EPIPE)
+ fprintf(stderr, "Expected EPIPE\n"), failures++;
+ if (!got_sigpipe)
+ fprintf(stderr, "Expected SIGPIPE\n"), failures++;
+ status = pclose(fp);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 88)
+ fprintf(stderr, "Bad exit status (EPIPE)\n"), failures++;
+ }
+ if (sigaction(SIGPIPE, &oact, NULL) == -1)
+ fprintf(stderr, "sigaction() failed\n"), failures++;
+
+ for (i = 0; i < sizeof(rwmodes) / sizeof(rwmodes[0]); i++) {
+ mode = rwmodes[i];
+ fp = popen("read x && printf '%s\\n' \"Q${x#a}\"", mode);
+ if (fp == NULL) {
+ fprintf(stderr, "popen(, \"%s\") failed", mode);
+ failures++;
+ continue;
+ }
+ check_cloexec(fp, mode);
+ if (fputs("abcd\n", fp) == EOF)
+ fprintf(stderr, "Output error 2\n"), failures++;
+ if (fgets(buf, sizeof(buf), fp) == NULL)
+ fprintf(stderr, "Input error 3\n"), failures++;
+ else if (strcmp(buf, "Qbcd\n") != 0)
+ fprintf(stderr, "Bad input 2\n"), failures++;
+ status = pclose(fp);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ fprintf(stderr, "Bad exit status (I/O)\n"), failures++;
+ }
+
+ for (i = 0; i < sizeof(wmodes) / sizeof(wmodes[0]); i++) {
+ for (j = 0; j < sizeof(wmodes) / sizeof(wmodes[0]); j++) {
+ mode = wmodes[i];
+ fp = popen("read x", mode);
+ if (fp == NULL) {
+ fprintf(stderr, "popen(, \"%s\") failed", mode);
+ failures++;
+ continue;
+ }
+ mode = wmodes[j];
+ fp2 = popen("read x", mode);
+ if (fp2 == NULL) {
+ fprintf(stderr, "popen(, \"%s\") failed", mode);
+ failures++;
+ pclose(fp);
+ continue;
+ }
+ /* If fp2 inherits fp's pipe, we will deadlock here. */
+ status = pclose(fp);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 1) {
+ fprintf(stderr, "Bad exit status (2 pipes)\n");
+ failures++;
+ }
+ status = pclose(fp2);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 1) {
+ fprintf(stderr, "Bad exit status (2 pipes)\n");
+ failures++;
+ }
+ }
+ }
+
+ if (failures == 0)
+ printf("PASS popen()\n");
+
+ return (failures != 0);
+}
diff --git a/tools/regression/lib/libc/gen/test-wordexp.c b/tools/regression/lib/libc/gen/test-wordexp.c
index d94f870..15d1b7c 100644
--- a/tools/regression/lib/libc/gen/test-wordexp.c
+++ b/tools/regression/lib/libc/gen/test-wordexp.c
@@ -195,6 +195,18 @@ main(int argc, char *argv[])
r = wordexp("test } test", &we, 0);
assert(r == WRDE_BADCHAR);
+ /* WRDE_SYNTAX */
+ r = wordexp("'", &we, 0);
+ assert(r == WRDE_SYNTAX);
+ r = wordexp("'", &we, WRDE_UNDEF);
+ assert(r == WRDE_SYNTAX);
+ r = wordexp("'\\'", &we, 0);
+ assert(r == 0);
+ assert(we.we_wordc == 1);
+ assert(strcmp(we.we_wordv[0], "\\") == 0);
+ assert(we.we_wordv[1] == NULL);
+ wordfree(&we);
+
/* With a SIGCHLD handler that reaps all zombies. */
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
diff --git a/tools/regression/lib/libc/locale/Makefile b/tools/regression/lib/libc/locale/Makefile
index 5fb9a94..ebbd537 100644
--- a/tools/regression/lib/libc/locale/Makefile
+++ b/tools/regression/lib/libc/locale/Makefile
@@ -14,7 +14,9 @@ TESTS= test-mbrtowc \
test-wcstombs \
test-mblen \
test-iswctype \
- test-towctrans
+ test-towctrans \
+ test-c16rtomb \
+ test-mbrtoc16
.PHONY: tests
tests: ${TESTS}
diff --git a/tools/regression/lib/libc/locale/test-btowc.c b/tools/regression/lib/libc/locale/test-btowc.c
index 9ed4582..b01c043 100644
--- a/tools/regression/lib/libc/locale/test-btowc.c
+++ b/tools/regression/lib/libc/locale/test-btowc.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <wchar.h>
int
diff --git a/tools/regression/lib/libc/locale/test-c16rtomb.c b/tools/regression/lib/libc/locale/test-c16rtomb.c
new file mode 100644
index 0000000..2c188fa
--- /dev/null
+++ b/tools/regression/lib/libc/locale/test-c16rtomb.c
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Copyright (c) 2013 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Test program for c16rtomb() as specified by ISO/IEC 9899:2011.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <uchar.h>
+
+int
+main(int argc, char *argv[])
+{
+ mbstate_t s;
+ char buf[MB_LEN_MAX + 1];
+
+ /*
+ * C/POSIX locale.
+ */
+
+ printf("1..1\n");
+
+ /*
+ * If the buffer argument is NULL, c16 is implicitly 0,
+ * c16rtomb() resets its internal state.
+ */
+ assert(c16rtomb(NULL, L'\0', NULL) == 1);
+ assert(c16rtomb(NULL, 0xdc00, NULL) == 1);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ assert(c16rtomb(buf, 0, &s) == 1);
+ assert((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
+
+ /* Latin letter A, internal state. */
+ assert(c16rtomb(NULL, L'\0', NULL) == 1);
+ assert(c16rtomb(NULL, L'A', NULL) == 1);
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ assert(c16rtomb(buf, L'A', &s) == 1);
+ assert((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
+
+ /* Unicode character 'Pile of poo'. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ assert(c16rtomb(buf, 0xd83d, &s) == 0);
+ assert(c16rtomb(buf, 0xdca9, &s) == (size_t)-1);
+ assert(errno == EILSEQ);
+ assert((unsigned char)buf[0] == 0xcc);
+
+ /*
+ * ISO8859-1.
+ */
+
+ assert(strcmp(setlocale(LC_CTYPE, "en_US.ISO8859-1"),
+ "en_US.ISO8859-1") == 0);
+
+ /* Unicode character 'Euro sign'. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ assert(c16rtomb(buf, 0x20ac, &s) == (size_t)-1);
+ assert(errno == EILSEQ);
+ assert((unsigned char)buf[0] == 0xcc);
+
+ /*
+ * ISO8859-15.
+ */
+
+ assert(strcmp(setlocale(LC_CTYPE, "en_US.ISO8859-15"),
+ "en_US.ISO8859-15") == 0);
+
+ /* Unicode character 'Euro sign'. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ assert(c16rtomb(buf, 0x20ac, &s) == 1);
+ assert((unsigned char)buf[0] == 0xa4 && (unsigned char)buf[1] == 0xcc);
+
+ /*
+ * UTF-8.
+ */
+
+ assert(strcmp(setlocale(LC_CTYPE, "en_US.UTF-8"), "en_US.UTF-8") == 0);
+
+ /* Unicode character 'Pile of poo'. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ assert(c16rtomb(buf, 0xd83d, &s) == 0);
+ assert(c16rtomb(buf, 0xdca9, &s) == 4);
+ assert((unsigned char)buf[0] == 0xf0 && (unsigned char)buf[1] == 0x9f &&
+ (unsigned char)buf[2] == 0x92 && (unsigned char)buf[3] == 0xa9 &&
+ (unsigned char)buf[4] == 0xcc);
+
+ /* Invalid code; 'Pile of poo' without the trail surrogate. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ assert(c16rtomb(buf, 0xd83d, &s) == 0);
+ assert(c16rtomb(buf, L'A', &s) == (size_t)-1);
+ assert(errno == EILSEQ);
+ assert((unsigned char)buf[0] == 0xcc);
+
+ /* Invalid code; 'Pile of poo' without the lead surrogate. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ assert(c16rtomb(buf, 0xdca9, &s) == (size_t)-1);
+ assert(errno == EILSEQ);
+ assert((unsigned char)buf[0] == 0xcc);
+
+ printf("ok 1 - c16rtomb()\n");
+}
diff --git a/tools/regression/lib/libc/locale/test-iswctype.c b/tools/regression/lib/libc/locale/test-iswctype.c
index ca9621a..1c56b88 100644
--- a/tools/regression/lib/libc/locale/test-iswctype.c
+++ b/tools/regression/lib/libc/locale/test-iswctype.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <assert.h>
#include <locale.h>
#include <stdio.h>
+#include <string.h>
#include <wchar.h>
#include <wctype.h>
diff --git a/tools/regression/lib/libc/locale/test-mbrtoc16.c b/tools/regression/lib/libc/locale/test-mbrtoc16.c
new file mode 100644
index 0000000..f709a9c
--- /dev/null
+++ b/tools/regression/lib/libc/locale/test-mbrtoc16.c
@@ -0,0 +1,195 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Copyright (c) 2013 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Test program for mbrtoc16() as specified by ISO/IEC 9899:2011.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <uchar.h>
+
+int
+main(int argc, char *argv[])
+{
+ mbstate_t s;
+ size_t len;
+ char16_t c16;
+
+ /*
+ * C/POSIX locale.
+ */
+
+ printf("1..1\n");
+
+ /* Null wide character, internal state. */
+ assert(mbrtoc16(&c16, "", 1, NULL) == 0);
+ assert(c16 == 0);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "", 1, &s) == 0);
+ assert(c16 == 0);
+
+ /* Latin letter A, internal state. */
+ assert(mbrtoc16(NULL, 0, 0, NULL) == 0);
+ assert(mbrtoc16(&c16, "A", 1, NULL) == 1);
+ assert(c16 == L'A');
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "A", 1, &s) == 1);
+ assert(c16 == L'A');
+
+ /* Incomplete character sequence. */
+ c16 = L'z';
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "", 0, &s) == (size_t)-2);
+ assert(c16 == L'z');
+
+ /* Check that mbrtoc16() doesn't access the buffer when n == 0. */
+ c16 = L'z';
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "", 0, &s) == (size_t)-2);
+ assert(c16 == L'z');
+
+ /* Check that mbrtoc16() doesn't read ahead too aggressively. */
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "AB", 2, &s) == 1);
+ assert(c16 == L'A');
+ assert(mbrtoc16(&c16, "C", 1, &s) == 1);
+ assert(c16 == L'C');
+
+ /*
+ * ISO-8859-1.
+ */
+
+ assert(strcmp(setlocale(LC_CTYPE, "en_US.ISO8859-1"),
+ "en_US.ISO8859-1") == 0);
+
+ /* Currency sign. */
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "\xa4", 1, &s) == 1);
+ assert(c16 == 0xa4);
+
+ /*
+ * ISO-8859-15.
+ */
+
+ assert(strcmp(setlocale(LC_CTYPE, "en_US.ISO8859-15"),
+ "en_US.ISO8859-15") == 0);
+
+ /* Euro sign. */
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "\xa4", 1, &s) == 1);
+ assert(c16 == 0x20ac);
+
+ /*
+ * UTF-8.
+ */
+
+ assert(strcmp(setlocale(LC_CTYPE, "en_US.UTF-8"), "en_US.UTF-8") == 0);
+
+ /* Null wide character, internal state. */
+ assert(mbrtoc16(NULL, 0, 0, NULL) == 0);
+ assert(mbrtoc16(&c16, "", 1, NULL) == 0);
+ assert(c16 == 0);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "", 1, &s) == 0);
+ assert(c16 == 0);
+
+ /* Latin letter A, internal state. */
+ assert(mbrtoc16(NULL, 0, 0, NULL) == 0);
+ assert(mbrtoc16(&c16, "A", 1, NULL) == 1);
+ assert(c16 == L'A');
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "A", 1, &s) == 1);
+ assert(c16 == L'A');
+
+ /* Incomplete character sequence (zero length). */
+ c16 = L'z';
+ memset(&s, 0, sizeof(s));
+ assert(mbrtoc16(&c16, "", 0, &s) == (size_t)-2);
+ assert(c16 == L'z');
+
+ /* Incomplete character sequence (truncated double-byte). */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ assert(mbrtoc16(&c16, "\xc3", 1, &s) == (size_t)-2);
+
+ /* Same as above, but complete. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ assert(mbrtoc16(&c16, "\xc3\x84", 2, &s) == 2);
+ assert(c16 == 0xc4);
+
+ /* Test restarting behaviour. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ assert(mbrtoc16(&c16, "\xc3", 1, &s) == (size_t)-2);
+ assert(c16 == 0);
+ assert(mbrtoc16(&c16, "\xb7", 1, &s) == 1);
+ assert(c16 == 0xf7);
+
+ /* Surrogate pair. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ assert(mbrtoc16(&c16, "\xf0\x9f\x92\xa9", 4, &s) == 4);
+ assert(c16 == 0xd83d);
+ assert(mbrtoc16(&c16, "", 0, &s) == (size_t)-3);
+ assert(c16 == 0xdca9);
+
+ /* Letter e with acute, precomposed. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ assert(mbrtoc16(&c16, "\xc3\xa9", 2, &s) == 2);
+ assert(c16 == 0xe9);
+
+ /* Letter e with acute, combined. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ assert(mbrtoc16(&c16, "\x65\xcc\x81", 3, &s) == 1);
+ assert(c16 == 0x65);
+ assert(mbrtoc16(&c16, "\xcc\x81", 2, &s) == 2);
+ assert(c16 == 0x301);
+
+ printf("ok 1 - mbrtoc16()\n");
+
+ return (0);
+}
diff --git a/tools/regression/lib/libc/locale/test-towctrans.c b/tools/regression/lib/libc/locale/test-towctrans.c
index 6c0e428..fabb343 100644
--- a/tools/regression/lib/libc/locale/test-towctrans.c
+++ b/tools/regression/lib/libc/locale/test-towctrans.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <assert.h>
#include <locale.h>
#include <stdio.h>
+#include <string.h>
#include <wchar.h>
#include <wctype.h>
diff --git a/tools/regression/lib/libc/nss/test-getaddr.c b/tools/regression/lib/libc/nss/test-getaddr.c
index 046d9db..309c94b 100644
--- a/tools/regression/lib/libc/nss/test-getaddr.c
+++ b/tools/regression/lib/libc/nss/test-getaddr.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
- * All rights rehted.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/tools/regression/lib/libc/nss/test-getgr.c b/tools/regression/lib/libc/nss/test-getgr.c
index 1b573e8..322c636 100644
--- a/tools/regression/lib/libc/nss/test-getgr.c
+++ b/tools/regression/lib/libc/nss/test-getgr.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
- * All rights regrped.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/tools/regression/lib/libc/nss/test-gethostby.c b/tools/regression/lib/libc/nss/test-gethostby.c
index 5a0c925..77455e7 100644
--- a/tools/regression/lib/libc/nss/test-gethostby.c
+++ b/tools/regression/lib/libc/nss/test-gethostby.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
- * All rights rehted.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/tools/regression/lib/libc/nss/test-getproto.c b/tools/regression/lib/libc/nss/test-getproto.c
index b94f204..89ad087 100644
--- a/tools/regression/lib/libc/nss/test-getproto.c
+++ b/tools/regression/lib/libc/nss/test-getproto.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
- * All rights repeed.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/tools/regression/lib/libc/nss/test-getpw.c b/tools/regression/lib/libc/nss/test-getpw.c
index 88277d3..bb88f6a 100644
--- a/tools/regression/lib/libc/nss/test-getpw.c
+++ b/tools/regression/lib/libc/nss/test-getpw.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
- * All rights repwded.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/tools/regression/lib/libc/nss/test-getrpc.c b/tools/regression/lib/libc/nss/test-getrpc.c
index df0bc83..4041e88 100644
--- a/tools/regression/lib/libc/nss/test-getrpc.c
+++ b/tools/regression/lib/libc/nss/test-getrpc.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
- * All rights repeed.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/tools/regression/lib/libc/nss/test-getusershell.c b/tools/regression/lib/libc/nss/test-getusershell.c
index 20faaac..8682591 100644
--- a/tools/regression/lib/libc/nss/test-getusershell.c
+++ b/tools/regression/lib/libc/nss/test-getusershell.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
- * All rights repwded.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/tools/regression/lib/libc/nss/testutil.h b/tools/regression/lib/libc/nss/testutil.h
index f1e91c2..acd69ac 100644
--- a/tools/regression/lib/libc/nss/testutil.h
+++ b/tools/regression/lib/libc/nss/testutil.h
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
- * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/tools/regression/lib/libc/stdio/Makefile b/tools/regression/lib/libc/stdio/Makefile
index f496f73..4b252b9 100644
--- a/tools/regression/lib/libc/stdio/Makefile
+++ b/tools/regression/lib/libc/stdio/Makefile
@@ -1,8 +1,8 @@
# $FreeBSD$
-TESTS= test-fmemopen test-getdelim test-open_memstream test-open_wmemstream \
- test-perror test-print-positional test-printbasic test-printfloat \
- test-scanfloat
+TESTS= test-fmemopen test-getdelim test-mkostemp test-open_memstream \
+ test-open_wmemstream test-perror test-print-positional test-printbasic \
+ test-printfloat test-scanfloat
CFLAGS+= -lm
.PHONY: tests
diff --git a/tools/regression/lib/libc/stdio/test-mkostemp.c b/tools/regression/lib/libc/stdio/test-mkostemp.c
new file mode 100644
index 0000000..5f67c72
--- /dev/null
+++ b/tools/regression/lib/libc/stdio/test-mkostemp.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2013 Jilles Tjoelker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for mkostemp().
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char template[] = _PATH_TMP "mkostemp.XXXXXXXX";
+static int testnum;
+
+#define MISCFLAGS (O_APPEND | O_DIRECT | O_SHLOCK | O_EXLOCK | O_SYNC)
+
+static void
+test_one(int oflags)
+{
+ char tmpf[sizeof(template)];
+ struct stat st1, st2;
+ int fd;
+
+ memcpy(tmpf, template, sizeof(tmpf));
+ fd = mkostemp(tmpf, oflags);
+ if (fd < 0) {
+ printf("not ok %d - oflags=%#x "
+ "mkostemp() reported failure: %s\n",
+ testnum++, oflags, strerror(errno));
+ return;
+ }
+ if (memcmp(tmpf, template, sizeof(tmpf) - 8 - 1) != 0) {
+ printf("not ok %d - oflags=%#x "
+ "returned pathname does not match template: %s\n",
+ testnum++, oflags, tmpf);
+ return;
+ }
+ do {
+ if (fcntl(fd, F_GETFD) !=
+ (oflags & O_CLOEXEC ? FD_CLOEXEC : 0)) {
+ printf("not ok %d - oflags=%#x "
+ "close-on-exec flag incorrect\n",
+ testnum++, oflags);
+ break;
+ }
+ if ((fcntl(fd, F_GETFL) & MISCFLAGS) != (oflags & MISCFLAGS)) {
+ printf("not ok %d - oflags=%#x "
+ "open flags incorrect\n",
+ testnum++, oflags);
+ break;
+ }
+ if (stat(tmpf, &st1) == -1) {
+ printf("not ok %d - oflags=%#x "
+ "cannot stat returned pathname %s: %s\n",
+ testnum++, oflags, tmpf, strerror(errno));
+ break;
+ }
+ if (fstat(fd, &st2) == -1) {
+ printf("not ok %d - oflags=%#x "
+ "cannot fstat returned fd %d: %s\n",
+ testnum++, oflags, fd, strerror(errno));
+ break;
+ }
+ if (!S_ISREG(st1.st_mode) || (st1.st_mode & 0777) != 0600 ||
+ st1.st_nlink != 1 || st1.st_size != 0) {
+ printf("not ok %d - oflags=%#x "
+ "named file attributes incorrect\n",
+ testnum++, oflags);
+ break;
+ }
+ if (!S_ISREG(st2.st_mode) || (st2.st_mode & 0777) != 0600 ||
+ st2.st_nlink != 1 || st2.st_size != 0) {
+ printf("not ok %d - oflags=%#x "
+ "opened file attributes incorrect\n",
+ testnum++, oflags);
+ break;
+ }
+ if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
+ printf("not ok %d - oflags=%#x "
+ "named and opened file do not match\n",
+ testnum++, oflags);
+ break;
+ }
+ (void)unlink(tmpf);
+ if (fstat(fd, &st2) == -1)
+ printf("not ok %d - oflags=%#x "
+ "cannot fstat returned fd %d again: %s\n",
+ testnum++, oflags, fd, strerror(errno));
+ else if (st2.st_nlink != 0)
+ printf("not ok %d - oflags=%#x "
+ "st_nlink is not 0 after unlink\n",
+ testnum++, oflags);
+ else
+ printf("ok %d - oflags=%#x\n", testnum++, oflags);
+ (void)close(fd);
+ return;
+ } while (0);
+ (void)close(fd);
+ (void)unlink(tmpf);
+}
+
+static void
+test_badflags(void)
+{
+ char tmpf[sizeof(template)];
+
+ memcpy(tmpf, template, sizeof(tmpf));
+ if (mkostemp(tmpf, O_CREAT) == -1)
+ printf("ok %d - mkostemp(O_CREAT) correctly failed\n",
+ testnum++);
+ else
+ printf("not ok %d - mkostemp(O_CREAT) wrongly succeeded\n",
+ testnum++);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int i;
+ const char *e;
+
+ printf("1..5\n");
+ testnum = 1;
+
+ test_one(0);
+ test_one(O_CLOEXEC);
+ test_one(O_APPEND);
+ test_one(O_APPEND | O_CLOEXEC);
+ test_badflags();
+
+ return (0);
+}
diff --git a/tools/regression/lib/msun/Makefile b/tools/regression/lib/msun/Makefile
index 261b1cb..dbf582f 100644
--- a/tools/regression/lib/msun/Makefile
+++ b/tools/regression/lib/msun/Makefile
@@ -2,9 +2,10 @@
TESTS= test-cexp test-conj test-csqrt test-ctrig \
test-exponential test-fenv test-fma \
- test-fmaxmin test-ilogb test-invtrig test-logarithm test-lrint \
+ test-fmaxmin test-ilogb test-invtrig test-invctrig \
+ test-logarithm test-lrint \
test-lround test-nan test-nearbyint test-next test-rem test-trig
-CFLAGS+= -O0 -lm
+CFLAGS+= -O0 -lm -Wno-unknown-pragmas
.PHONY: tests
tests: ${TESTS}
diff --git a/tools/regression/lib/msun/test-cexp.c b/tools/regression/lib/msun/test-cexp.c
index 2913fbd..78c3f1a 100644
--- a/tools/regression/lib/msun/test-cexp.c
+++ b/tools/regression/lib/msun/test-cexp.c
@@ -38,11 +38,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
-#define FLT_ULP() ldexpl(1.0, 1 - FLT_MANT_DIG)
-#define DBL_ULP() ldexpl(1.0, 1 - DBL_MANT_DIG)
-#define LDBL_ULP() ldexpl(1.0, 1 - LDBL_MANT_DIG)
+#include "test-utils.h"
#define N(i) (sizeof(i) / sizeof((i)[0]))
@@ -50,23 +46,6 @@ __FBSDID("$FreeBSD$");
#pragma STDC CX_LIMITED_RANGE OFF
/*
- * XXX gcc implements complex multiplication incorrectly. In
- * particular, it implements it as if the CX_LIMITED_RANGE pragma
- * were ON. Consequently, we need this function to form numbers
- * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
- * NaN + INFINITY * I.
- */
-static inline long double complex
-cpackl(long double x, long double y)
-{
- long double complex z;
-
- __real__ z = x;
- __imag__ z = y;
- return (z);
-}
-
-/*
* Test that a function returns the correct value and sets the
* exception flags correctly. The exceptmask specifies which
* exceptions we should check. We need to be lenient for several
@@ -83,14 +62,15 @@ cpackl(long double x, long double y)
#define test(func, z, result, exceptmask, excepts, checksign) do { \
volatile long double complex _d = z; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(cfpequal((func)(_d), (result), (checksign))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(cfpequal_cs((func)(_d), (result), (checksign))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
/* Test within a given tolerance. */
#define test_tol(func, z, result, tol) do { \
volatile long double complex _d = z; \
- assert(cfpequal_tol((func)(_d), (result), (tol))); \
+ assert(cfpequal_tol((func)(_d), (result), (tol), \
+ FPE_ABS_ZERO | CS_BOTH)); \
} while (0)
/* Test all the functions that compute cexp(x). */
@@ -110,68 +90,7 @@ cpackl(long double x, long double y)
/* Various finite non-zero numbers to test. */
static const float finites[] =
-{ -42.0e20, -1.0 -1.0e-10, -0.0, 0.0, 1.0e-10, 1.0, 42.0e20 };
-
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- * If checksign is 0, we compare the absolute values instead.
- */
-static int
-fpequal(long double x, long double y, int checksign)
-{
- if (isnan(x) || isnan(y))
- return (1);
- if (checksign)
- return (x == y && !signbit(x) == !signbit(y));
- else
- return (fabsl(x) == fabsl(y));
-}
-
-static int
-fpequal_tol(long double x, long double y, long double tol)
-{
- fenv_t env;
- int ret;
-
- if (isnan(x) && isnan(y))
- return (1);
- if (!signbit(x) != !signbit(y))
- return (0);
- if (x == y)
- return (1);
- if (tol == 0)
- return (0);
-
- /* Hard case: need to check the tolerance. */
- feholdexcept(&env);
- /*
- * For our purposes here, if y=0, we interpret tol as an absolute
- * tolerance. This is to account for roundoff in the input, e.g.,
- * cos(Pi/2) ~= 0.
- */
- if (y == 0.0)
- ret = fabsl(x - y) <= fabsl(tol);
- else
- ret = fabsl(x - y) <= fabsl(y * tol);
- fesetenv(&env);
- return (ret);
-}
-
-static int
-cfpequal(long double complex x, long double complex y, int checksign)
-{
- return (fpequal(creal(x), creal(y), checksign)
- && fpequal(cimag(x), cimag(y), checksign));
-}
-
-static int
-cfpequal_tol(long double complex x, long double complex y, long double tol)
-{
- return (fpequal_tol(creal(x), creal(y), tol)
- && fpequal_tol(cimag(x), cimag(y), tol));
-}
+{ -42.0e20, -1.0, -1.0e-10, -0.0, 0.0, 1.0e-10, 1.0, 42.0e20 };
/* Tests for 0 */
@@ -182,8 +101,8 @@ test_zero(void)
/* cexp(0) = 1, no exceptions raised */
testall(0.0, 1.0, ALL_STD_EXCEPT, 0, 1);
testall(-0.0, 1.0, ALL_STD_EXCEPT, 0, 1);
- testall(cpackl(0.0, -0.0), cpackl(1.0, -0.0), ALL_STD_EXCEPT, 0, 1);
- testall(cpackl(-0.0, -0.0), cpackl(1.0, -0.0), ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(0.0, -0.0), CMPLXL(1.0, -0.0), ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(-0.0, -0.0), CMPLXL(1.0, -0.0), ALL_STD_EXCEPT, 0, 1);
}
/*
@@ -198,27 +117,27 @@ test_nan()
/* cexp(x + NaNi) = NaN + NaNi and optionally raises invalid */
/* cexp(NaN + yi) = NaN + NaNi and optionally raises invalid (|y|>0) */
for (i = 0; i < N(finites); i++) {
- testall(cpackl(finites[i], NAN), cpackl(NAN, NAN),
+ testall(CMPLXL(finites[i], NAN), CMPLXL(NAN, NAN),
ALL_STD_EXCEPT & ~FE_INVALID, 0, 0);
if (finites[i] == 0.0)
continue;
/* XXX FE_INEXACT shouldn't be raised here */
- testall(cpackl(NAN, finites[i]), cpackl(NAN, NAN),
+ testall(CMPLXL(NAN, finites[i]), CMPLXL(NAN, NAN),
ALL_STD_EXCEPT & ~(FE_INVALID | FE_INEXACT), 0, 0);
}
/* cexp(NaN +- 0i) = NaN +- 0i */
- testall(cpackl(NAN, 0.0), cpackl(NAN, 0.0), ALL_STD_EXCEPT, 0, 1);
- testall(cpackl(NAN, -0.0), cpackl(NAN, -0.0), ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(NAN, 0.0), CMPLXL(NAN, 0.0), ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(NAN, -0.0), CMPLXL(NAN, -0.0), ALL_STD_EXCEPT, 0, 1);
/* cexp(inf + NaN i) = inf + nan i */
- testall(cpackl(INFINITY, NAN), cpackl(INFINITY, NAN),
+ testall(CMPLXL(INFINITY, NAN), CMPLXL(INFINITY, NAN),
ALL_STD_EXCEPT, 0, 0);
/* cexp(-inf + NaN i) = 0 */
- testall(cpackl(-INFINITY, NAN), cpackl(0.0, 0.0),
+ testall(CMPLXL(-INFINITY, NAN), CMPLXL(0.0, 0.0),
ALL_STD_EXCEPT, 0, 0);
/* cexp(NaN + NaN i) = NaN + NaN i */
- testall(cpackl(NAN, NAN), cpackl(NAN, NAN),
+ testall(CMPLXL(NAN, NAN), CMPLXL(NAN, NAN),
ALL_STD_EXCEPT, 0, 0);
}
@@ -228,24 +147,38 @@ test_inf(void)
int i;
/* cexp(x + inf i) = NaN + NaNi and raises invalid */
- /* cexp(inf + yi) = 0 + 0yi */
- /* cexp(-inf + yi) = inf + inf yi (except y=0) */
for (i = 0; i < N(finites); i++) {
- testall(cpackl(finites[i], INFINITY), cpackl(NAN, NAN),
+ testall(CMPLXL(finites[i], INFINITY), CMPLXL(NAN, NAN),
ALL_STD_EXCEPT, FE_INVALID, 1);
- /* XXX shouldn't raise an inexact exception */
- testall(cpackl(-INFINITY, finites[i]),
- cpackl(0.0, 0.0 * finites[i]),
- ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- if (finites[i] == 0)
- continue;
- testall(cpackl(INFINITY, finites[i]),
- cpackl(INFINITY, INFINITY * finites[i]),
- ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
}
- testall(cpackl(INFINITY, 0.0), cpackl(INFINITY, 0.0),
+ /* cexp(-inf + yi) = 0 * (cos(y) + sin(y)i) */
+ /* XXX shouldn't raise an inexact exception */
+ testall(CMPLXL(-INFINITY, M_PI_4), CMPLXL(0.0, 0.0),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(-INFINITY, 3 * M_PI_4), CMPLXL(-0.0, 0.0),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(-INFINITY, 5 * M_PI_4), CMPLXL(-0.0, -0.0),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(-INFINITY, 7 * M_PI_4), CMPLXL(0.0, -0.0),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(-INFINITY, 0.0), CMPLXL(0.0, 0.0),
+ ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(-INFINITY, -0.0), CMPLXL(0.0, -0.0),
+ ALL_STD_EXCEPT, 0, 1);
+ /* cexp(inf + yi) = inf * (cos(y) + sin(y)i) (except y=0) */
+ /* XXX shouldn't raise an inexact exception */
+ testall(CMPLXL(INFINITY, M_PI_4), CMPLXL(INFINITY, INFINITY),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(INFINITY, 3 * M_PI_4), CMPLXL(-INFINITY, INFINITY),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(INFINITY, 5 * M_PI_4), CMPLXL(-INFINITY, -INFINITY),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(INFINITY, 7 * M_PI_4), CMPLXL(INFINITY, -INFINITY),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ /* cexp(inf + 0i) = inf + 0i */
+ testall(CMPLXL(INFINITY, 0.0), CMPLXL(INFINITY, 0.0),
ALL_STD_EXCEPT, 0, 1);
- testall(cpackl(INFINITY, -0.0), cpackl(INFINITY, -0.0),
+ testall(CMPLXL(INFINITY, -0.0), CMPLXL(INFINITY, -0.0),
ALL_STD_EXCEPT, 0, 1);
}
@@ -256,17 +189,17 @@ test_reals(void)
for (i = 0; i < N(finites); i++) {
/* XXX could check exceptions more meticulously */
- test(cexp, cpackl(finites[i], 0.0),
- cpackl(exp(finites[i]), 0.0),
+ test(cexp, CMPLXL(finites[i], 0.0),
+ CMPLXL(exp(finites[i]), 0.0),
FE_INVALID | FE_DIVBYZERO, 0, 1);
- test(cexp, cpackl(finites[i], -0.0),
- cpackl(exp(finites[i]), -0.0),
+ test(cexp, CMPLXL(finites[i], -0.0),
+ CMPLXL(exp(finites[i]), -0.0),
FE_INVALID | FE_DIVBYZERO, 0, 1);
- test(cexpf, cpackl(finites[i], 0.0),
- cpackl(expf(finites[i]), 0.0),
+ test(cexpf, CMPLXL(finites[i], 0.0),
+ CMPLXL(expf(finites[i]), 0.0),
FE_INVALID | FE_DIVBYZERO, 0, 1);
- test(cexpf, cpackl(finites[i], -0.0),
- cpackl(expf(finites[i]), -0.0),
+ test(cexpf, CMPLXL(finites[i], -0.0),
+ CMPLXL(expf(finites[i]), -0.0),
FE_INVALID | FE_DIVBYZERO, 0, 1);
}
}
@@ -277,17 +210,17 @@ test_imaginaries(void)
int i;
for (i = 0; i < N(finites); i++) {
- test(cexp, cpackl(0.0, finites[i]),
- cpackl(cos(finites[i]), sin(finites[i])),
+ test(cexp, CMPLXL(0.0, finites[i]),
+ CMPLXL(cos(finites[i]), sin(finites[i])),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- test(cexp, cpackl(-0.0, finites[i]),
- cpackl(cos(finites[i]), sin(finites[i])),
+ test(cexp, CMPLXL(-0.0, finites[i]),
+ CMPLXL(cos(finites[i]), sin(finites[i])),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- test(cexpf, cpackl(0.0, finites[i]),
- cpackl(cosf(finites[i]), sinf(finites[i])),
+ test(cexpf, CMPLXL(0.0, finites[i]),
+ CMPLXL(cosf(finites[i]), sinf(finites[i])),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- test(cexpf, cpackl(-0.0, finites[i]),
- cpackl(cosf(finites[i]), sinf(finites[i])),
+ test(cexpf, CMPLXL(-0.0, finites[i]),
+ CMPLXL(cosf(finites[i]), sinf(finites[i])),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
}
}
@@ -312,12 +245,12 @@ test_small(void)
b = tests[i + 1];
x = tests[i + 2];
y = tests[i + 3];
- test_tol(cexp, cpackl(a, b), cpackl(x, y), 3 * DBL_ULP());
+ test_tol(cexp, CMPLXL(a, b), CMPLXL(x, y), 3 * DBL_ULP());
/* float doesn't have enough precision to pass these tests */
if (x == 0 || y == 0)
continue;
- test_tol(cexpf, cpackl(a, b), cpackl(x, y), 1 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(a, b), CMPLXL(x, y), 1 * FLT_ULP());
}
}
@@ -326,27 +259,27 @@ void
test_large(void)
{
- test_tol(cexp, cpackl(709.79, 0x1p-1074),
- cpackl(INFINITY, 8.94674309915433533273e-16), DBL_ULP());
- test_tol(cexp, cpackl(1000, 0x1p-1074),
- cpackl(INFINITY, 9.73344457300016401328e+110), DBL_ULP());
- test_tol(cexp, cpackl(1400, 0x1p-1074),
- cpackl(INFINITY, 5.08228858149196559681e+284), DBL_ULP());
- test_tol(cexp, cpackl(900, 0x1.23456789abcdep-1020),
- cpackl(INFINITY, 7.42156649354218408074e+83), DBL_ULP());
- test_tol(cexp, cpackl(1300, 0x1.23456789abcdep-1020),
- cpackl(INFINITY, 3.87514844965996756704e+257), DBL_ULP());
-
- test_tol(cexpf, cpackl(88.73, 0x1p-149),
- cpackl(INFINITY, 4.80265603e-07), 2 * FLT_ULP());
- test_tol(cexpf, cpackl(90, 0x1p-149),
- cpackl(INFINITY, 1.7101492622e-06f), 2 * FLT_ULP());
- test_tol(cexpf, cpackl(192, 0x1p-149),
- cpackl(INFINITY, 3.396809344e+38f), 2 * FLT_ULP());
- test_tol(cexpf, cpackl(120, 0x1.234568p-120),
- cpackl(INFINITY, 1.1163382522e+16f), 2 * FLT_ULP());
- test_tol(cexpf, cpackl(170, 0x1.234568p-120),
- cpackl(INFINITY, 5.7878851079e+37f), 2 * FLT_ULP());
+ test_tol(cexp, CMPLXL(709.79, 0x1p-1074),
+ CMPLXL(INFINITY, 8.94674309915433533273e-16), DBL_ULP());
+ test_tol(cexp, CMPLXL(1000, 0x1p-1074),
+ CMPLXL(INFINITY, 9.73344457300016401328e+110), DBL_ULP());
+ test_tol(cexp, CMPLXL(1400, 0x1p-1074),
+ CMPLXL(INFINITY, 5.08228858149196559681e+284), DBL_ULP());
+ test_tol(cexp, CMPLXL(900, 0x1.23456789abcdep-1020),
+ CMPLXL(INFINITY, 7.42156649354218408074e+83), DBL_ULP());
+ test_tol(cexp, CMPLXL(1300, 0x1.23456789abcdep-1020),
+ CMPLXL(INFINITY, 3.87514844965996756704e+257), DBL_ULP());
+
+ test_tol(cexpf, CMPLXL(88.73, 0x1p-149),
+ CMPLXL(INFINITY, 4.80265603e-07), 2 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(90, 0x1p-149),
+ CMPLXL(INFINITY, 1.7101492622e-06f), 2 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(192, 0x1p-149),
+ CMPLXL(INFINITY, 3.396809344e+38f), 2 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(120, 0x1.234568p-120),
+ CMPLXL(INFINITY, 1.1163382522e+16f), 2 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(170, 0x1.234568p-120),
+ CMPLXL(INFINITY, 5.7878851079e+37f), 2 * FLT_ULP());
}
int
diff --git a/tools/regression/lib/msun/test-conj.c b/tools/regression/lib/msun/test-conj.c
index 909e810..c261f60 100644
--- a/tools/regression/lib/msun/test-conj.c
+++ b/tools/regression/lib/msun/test-conj.c
@@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
+#include "test-utils.h"
+
#pragma STDC CX_LIMITED_RANGE off
/* Make sure gcc doesn't use builtin versions of these or honor __pure2. */
@@ -50,27 +52,6 @@ static float (*libcimagf)(float complex) = cimagf;
static double (*libcimag)(double complex) = cimag;
static long double (*libcimagl)(long double complex) = cimagl;
-/*
- * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
- * Fail an assertion if they differ.
- */
-static int
-fpequal(long double d1, long double d2)
-{
-
- if (d1 != d2)
- return (isnan(d1) && isnan(d2));
- return (copysignl(1.0, d1) == copysignl(1.0, d2));
-}
-
-static int
-cfpequal(long double complex d1, long double complex d2)
-{
-
- return (fpequal(creall(d1), creall(d2)) &&
- fpequal(cimagl(d1), cimagl(d2)));
-}
-
static const double tests[] = {
/* a + bI */
0.0, 0.0,
diff --git a/tools/regression/lib/msun/test-csqrt.c b/tools/regression/lib/msun/test-csqrt.c
index 9877b9d..39176eb 100644
--- a/tools/regression/lib/msun/test-csqrt.c
+++ b/tools/regression/lib/msun/test-csqrt.c
@@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
+#include "test-utils.h"
+
#define N(i) (sizeof(i) / sizeof((i)[0]))
/*
@@ -63,23 +65,6 @@ _csqrt(long double complex d)
#pragma STDC CX_LIMITED_RANGE off
/*
- * XXX gcc implements complex multiplication incorrectly. In
- * particular, it implements it as if the CX_LIMITED_RANGE pragma
- * were ON. Consequently, we need this function to form numbers
- * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
- * NaN + INFINITY * I.
- */
-static inline long double complex
-cpackl(long double x, long double y)
-{
- long double complex z;
-
- __real__ z = x;
- __imag__ z = y;
- return (z);
-}
-
-/*
* Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
* Fail an assertion if they differ.
*/
@@ -87,20 +72,7 @@ static void
assert_equal(long double complex d1, long double complex d2)
{
- if (isnan(creall(d1))) {
- assert(isnan(creall(d2)));
- } else {
- assert(creall(d1) == creall(d2));
- assert(copysignl(1.0, creall(d1)) ==
- copysignl(1.0, creall(d2)));
- }
- if (isnan(cimagl(d1))) {
- assert(isnan(cimagl(d2)));
- } else {
- assert(cimagl(d1) == cimagl(d2));
- assert(copysignl(1.0, cimagl(d1)) ==
- copysignl(1.0, cimagl(d2)));
- }
+ assert(cfpequal(d1, d2));
}
/*
@@ -161,7 +133,7 @@ test_finite()
b = tests[i + 1] * mults[j] * mults[j];
x = tests[i + 2] * mults[j];
y = tests[i + 3] * mults[j];
- assert(t_csqrt(cpackl(a, b)) == cpackl(x, y));
+ assert(t_csqrt(CMPLXL(a, b)) == CMPLXL(x, y));
}
}
@@ -174,10 +146,10 @@ static void
test_zeros()
{
- assert_equal(t_csqrt(cpackl(0.0, 0.0)), cpackl(0.0, 0.0));
- assert_equal(t_csqrt(cpackl(-0.0, 0.0)), cpackl(0.0, 0.0));
- assert_equal(t_csqrt(cpackl(0.0, -0.0)), cpackl(0.0, -0.0));
- assert_equal(t_csqrt(cpackl(-0.0, -0.0)), cpackl(0.0, -0.0));
+ assert_equal(t_csqrt(CMPLXL(0.0, 0.0)), CMPLXL(0.0, 0.0));
+ assert_equal(t_csqrt(CMPLXL(-0.0, 0.0)), CMPLXL(0.0, 0.0));
+ assert_equal(t_csqrt(CMPLXL(0.0, -0.0)), CMPLXL(0.0, -0.0));
+ assert_equal(t_csqrt(CMPLXL(-0.0, -0.0)), CMPLXL(0.0, -0.0));
}
/*
@@ -199,15 +171,15 @@ test_infinities()
for (i = 0; i < N(vals); i++) {
if (isfinite(vals[i])) {
- assert_equal(t_csqrt(cpackl(-INFINITY, vals[i])),
- cpackl(0.0, copysignl(INFINITY, vals[i])));
- assert_equal(t_csqrt(cpackl(INFINITY, vals[i])),
- cpackl(INFINITY, copysignl(0.0, vals[i])));
+ assert_equal(t_csqrt(CMPLXL(-INFINITY, vals[i])),
+ CMPLXL(0.0, copysignl(INFINITY, vals[i])));
+ assert_equal(t_csqrt(CMPLXL(INFINITY, vals[i])),
+ CMPLXL(INFINITY, copysignl(0.0, vals[i])));
}
- assert_equal(t_csqrt(cpackl(vals[i], INFINITY)),
- cpackl(INFINITY, INFINITY));
- assert_equal(t_csqrt(cpackl(vals[i], -INFINITY)),
- cpackl(INFINITY, -INFINITY));
+ assert_equal(t_csqrt(CMPLXL(vals[i], INFINITY)),
+ CMPLXL(INFINITY, INFINITY));
+ assert_equal(t_csqrt(CMPLXL(vals[i], -INFINITY)),
+ CMPLXL(INFINITY, -INFINITY));
}
}
@@ -218,26 +190,26 @@ static void
test_nans()
{
- assert(creall(t_csqrt(cpackl(INFINITY, NAN))) == INFINITY);
- assert(isnan(cimagl(t_csqrt(cpackl(INFINITY, NAN)))));
-
- assert(isnan(creall(t_csqrt(cpackl(-INFINITY, NAN)))));
- assert(isinf(cimagl(t_csqrt(cpackl(-INFINITY, NAN)))));
-
- assert_equal(t_csqrt(cpackl(NAN, INFINITY)),
- cpackl(INFINITY, INFINITY));
- assert_equal(t_csqrt(cpackl(NAN, -INFINITY)),
- cpackl(INFINITY, -INFINITY));
-
- assert_equal(t_csqrt(cpackl(0.0, NAN)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(-0.0, NAN)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(42.0, NAN)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(-42.0, NAN)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, 0.0)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, -0.0)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, 42.0)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, -42.0)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, NAN)), cpackl(NAN, NAN));
+ assert(creall(t_csqrt(CMPLXL(INFINITY, NAN))) == INFINITY);
+ assert(isnan(cimagl(t_csqrt(CMPLXL(INFINITY, NAN)))));
+
+ assert(isnan(creall(t_csqrt(CMPLXL(-INFINITY, NAN)))));
+ assert(isinf(cimagl(t_csqrt(CMPLXL(-INFINITY, NAN)))));
+
+ assert_equal(t_csqrt(CMPLXL(NAN, INFINITY)),
+ CMPLXL(INFINITY, INFINITY));
+ assert_equal(t_csqrt(CMPLXL(NAN, -INFINITY)),
+ CMPLXL(INFINITY, -INFINITY));
+
+ assert_equal(t_csqrt(CMPLXL(0.0, NAN)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(-0.0, NAN)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(42.0, NAN)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(-42.0, NAN)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, 0.0)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, -0.0)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, 42.0)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, -42.0)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, NAN)), CMPLXL(NAN, NAN));
}
/*
@@ -254,7 +226,7 @@ test_overflow(int maxexp)
a = ldexpl(115 * 0x1p-8, maxexp);
b = ldexpl(252 * 0x1p-8, maxexp);
- result = t_csqrt(cpackl(a, b));
+ result = t_csqrt(CMPLXL(a, b));
assert(creall(result) == ldexpl(14 * 0x1p-4, maxexp / 2));
assert(cimagl(result) == ldexpl(9 * 0x1p-4, maxexp / 2));
}
diff --git a/tools/regression/lib/msun/test-ctrig.c b/tools/regression/lib/msun/test-ctrig.c
index ed78661..9f9b88d 100644
--- a/tools/regression/lib/msun/test-ctrig.c
+++ b/tools/regression/lib/msun/test-ctrig.c
@@ -38,46 +38,12 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
-#define OPT_INVALID (ALL_STD_EXCEPT & ~FE_INVALID)
-#define OPT_INEXACT (ALL_STD_EXCEPT & ~FE_INEXACT)
-#define FLT_ULP() ldexpl(1.0, 1 - FLT_MANT_DIG)
-#define DBL_ULP() ldexpl(1.0, 1 - DBL_MANT_DIG)
-#define LDBL_ULP() ldexpl(1.0, 1 - LDBL_MANT_DIG)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
#pragma STDC CX_LIMITED_RANGE OFF
/*
- * XXX gcc implements complex multiplication incorrectly. In
- * particular, it implements it as if the CX_LIMITED_RANGE pragma
- * were ON. Consequently, we need this function to form numbers
- * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
- * NaN + INFINITY * I.
- */
-static inline long double complex
-cpackl(long double x, long double y)
-{
- long double complex z;
-
- __real__ z = x;
- __imag__ z = y;
- return (z);
-}
-
-/* Flags that determine whether to check the signs of the result. */
-#define CS_REAL 1
-#define CS_IMAG 2
-#define CS_BOTH (CS_REAL | CS_IMAG)
-
-#ifdef DEBUG
-#define debug(...) printf(__VA_ARGS__)
-#else
-#define debug(...) (void)0
-#endif
-
-/*
* Test that a function returns the correct value and sets the
* exception flags correctly. The exceptmask specifies which
* exceptions we should check. We need to be lenient for several
@@ -95,8 +61,8 @@ cpackl(long double x, long double y)
debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(cfpequal((func)(_d), (result), (checksign))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(cfpequal_cs((func)(_d), (result), (checksign))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
/*
@@ -108,7 +74,7 @@ cpackl(long double x, long double y)
volatile long double complex _d = z; \
debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \
- assert(cfpequal_tol((func)(_d), (result), (tol))); \
+ assert(cfpequal_tol((func)(_d), (result), (tol), FPE_ABS_ZERO)); \
} while (0)
/* These wrappers apply the identities f(conj(z)) = conj(f(z)). */
@@ -120,6 +86,14 @@ cpackl(long double x, long double y)
test_p_tol(func, z, result, tol); \
test_p_tol(func, conjl(z), conjl(result), tol); \
} while (0)
+#define test_odd_tol(func, z, result, tol) do { \
+ test_tol(func, z, result, tol); \
+ test_tol(func, -(z), -(result), tol); \
+} while (0)
+#define test_even_tol(func, z, result, tol) do { \
+ test_tol(func, z, result, tol); \
+ test_tol(func, -(z), result, tol); \
+} while (0)
/* Test the given function in all precisions. */
#define testall(func, x, result, exceptmask, excepts, checksign) do { \
@@ -144,87 +118,26 @@ cpackl(long double x, long double y)
test_tol(func##f, x, result, tol * FLT_ULP()); \
} while (0)
#define testall_odd_tol(func, x, result, tol) do { \
- test_tol(func, x, result, tol * DBL_ULP()); \
- test_tol(func, -x, -result, tol * DBL_ULP()); \
+ test_odd_tol(func, x, result, tol * DBL_ULP()); \
+ test_odd_tol(func##f, x, result, tol * FLT_ULP()); \
} while (0)
#define testall_even_tol(func, x, result, tol) do { \
- test_tol(func, x, result, tol * DBL_ULP()); \
- test_tol(func, -x, result, tol * DBL_ULP()); \
+ test_even_tol(func, x, result, tol * DBL_ULP()); \
+ test_even_tol(func##f, x, result, tol * FLT_ULP()); \
} while (0)
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- * If checksign is 0, we compare the absolute values instead.
- */
-static int
-fpequal(long double x, long double y, int checksign)
-{
- if (isnan(x) && isnan(y))
- return (1);
- if (checksign)
- return (x == y && !signbit(x) == !signbit(y));
- else
- return (fabsl(x) == fabsl(y));
-}
-
-static int
-fpequal_tol(long double x, long double y, long double tol)
-{
- fenv_t env;
- int ret;
-
- if (isnan(x) && isnan(y))
- return (1);
- if (!signbit(x) != !signbit(y) && tol == 0)
- return (0);
- if (x == y)
- return (1);
- if (tol == 0)
- return (0);
-
- /* Hard case: need to check the tolerance. */
- feholdexcept(&env);
- /*
- * For our purposes here, if y=0, we interpret tol as an absolute
- * tolerance. This is to account for roundoff in the input, e.g.,
- * cos(Pi/2) ~= 0.
- */
- if (y == 0.0)
- ret = fabsl(x - y) <= fabsl(tol);
- else
- ret = fabsl(x - y) <= fabsl(y * tol);
- fesetenv(&env);
- return (ret);
-}
-
-static int
-cfpequal(long double complex x, long double complex y, int checksign)
-{
- return (fpequal(creal(x), creal(y), checksign & CS_REAL)
- && fpequal(cimag(x), cimag(y), checksign & CS_IMAG));
-}
-
-static int
-cfpequal_tol(long double complex x, long double complex y, long double tol)
-{
- return (fpequal_tol(creal(x), creal(y), tol)
- && fpequal_tol(cimag(x), cimag(y), tol));
-}
-
/* Tests for 0 */
void
test_zero(void)
{
- long double complex zero = cpackl(0.0, 0.0);
+ long double complex zero = CMPLXL(0.0, 0.0);
/* csinh(0) = ctanh(0) = 0; ccosh(0) = 1 (no exceptions raised) */
testall_odd(csinh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
testall_odd(csin, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
testall_even(ccosh, zero, 1.0, ALL_STD_EXCEPT, 0, CS_BOTH);
- testall_even(ccos, zero, cpackl(1.0, -0.0), ALL_STD_EXCEPT, 0, CS_BOTH);
+ testall_even(ccos, zero, CMPLXL(1.0, -0.0), ALL_STD_EXCEPT, 0, CS_BOTH);
testall_odd(ctanh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
testall_odd(ctan, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
}
@@ -235,7 +148,7 @@ test_zero(void)
void
test_nan()
{
- long double complex nan_nan = cpackl(NAN, NAN);
+ long double complex nan_nan = CMPLXL(NAN, NAN);
long double complex z;
/*
@@ -256,7 +169,7 @@ test_nan()
testall_even(ccos, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
testall_odd(ctan, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
- z = cpackl(42, NAN);
+ z = CMPLXL(42, NAN);
testall_odd(csinh, z, nan_nan, OPT_INVALID, 0, 0);
testall_even(ccosh, z, nan_nan, OPT_INVALID, 0, 0);
/* XXX We allow a spurious inexact exception here. */
@@ -265,7 +178,7 @@ test_nan()
testall_even(ccos, z, nan_nan, OPT_INVALID, 0, 0);
testall_odd(ctan, z, nan_nan, OPT_INVALID, 0, 0);
- z = cpackl(NAN, 42);
+ z = CMPLXL(NAN, 42);
testall_odd(csinh, z, nan_nan, OPT_INVALID, 0, 0);
testall_even(ccosh, z, nan_nan, OPT_INVALID, 0, 0);
testall_odd(ctanh, z, nan_nan, OPT_INVALID, 0, 0);
@@ -274,38 +187,38 @@ test_nan()
/* XXX We allow a spurious inexact exception here. */
testall_odd(ctan, z, nan_nan, OPT_INVALID & ~FE_INEXACT, 0, 0);
- z = cpackl(NAN, INFINITY);
+ z = CMPLXL(NAN, INFINITY);
testall_odd(csinh, z, nan_nan, OPT_INVALID, 0, 0);
testall_even(ccosh, z, nan_nan, OPT_INVALID, 0, 0);
testall_odd(ctanh, z, nan_nan, OPT_INVALID, 0, 0);
- testall_odd(csin, z, cpackl(NAN, INFINITY), ALL_STD_EXCEPT, 0, 0);
- testall_even(ccos, z, cpackl(INFINITY, NAN), ALL_STD_EXCEPT, 0,
+ testall_odd(csin, z, CMPLXL(NAN, INFINITY), ALL_STD_EXCEPT, 0, 0);
+ testall_even(ccos, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0,
CS_IMAG);
- testall_odd(ctan, z, cpackl(0, 1), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall_odd(ctan, z, CMPLXL(0, 1), ALL_STD_EXCEPT, 0, CS_IMAG);
- z = cpackl(INFINITY, NAN);
- testall_odd(csinh, z, cpackl(INFINITY, NAN), ALL_STD_EXCEPT, 0, 0);
- testall_even(ccosh, z, cpackl(INFINITY, NAN), ALL_STD_EXCEPT, 0,
+ z = CMPLXL(INFINITY, NAN);
+ testall_odd(csinh, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0, 0);
+ testall_even(ccosh, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0,
CS_REAL);
- testall_odd(ctanh, z, cpackl(1, 0), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_odd(ctanh, z, CMPLXL(1, 0), ALL_STD_EXCEPT, 0, CS_REAL);
testall_odd(csin, z, nan_nan, OPT_INVALID, 0, 0);
testall_even(ccos, z, nan_nan, OPT_INVALID, 0, 0);
testall_odd(ctan, z, nan_nan, OPT_INVALID, 0, 0);
- z = cpackl(0, NAN);
- testall_odd(csinh, z, cpackl(0, NAN), ALL_STD_EXCEPT, 0, 0);
- testall_even(ccosh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ z = CMPLXL(0, NAN);
+ testall_odd(csinh, z, CMPLXL(0, NAN), ALL_STD_EXCEPT, 0, 0);
+ testall_even(ccosh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
testall_odd(ctanh, z, nan_nan, OPT_INVALID, 0, 0);
- testall_odd(csin, z, cpackl(0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
- testall_even(ccos, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
- testall_odd(ctan, z, cpackl(0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
-
- z = cpackl(NAN, 0);
- testall_odd(csinh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
- testall_even(ccosh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
- testall_odd(ctanh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
- testall_odd(csin, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
- testall_even(ccos, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ testall_odd(csin, z, CMPLXL(0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_even(ccos, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ testall_odd(ctan, z, CMPLXL(0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
+
+ z = CMPLXL(NAN, 0);
+ testall_odd(csinh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall_even(ccosh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ testall_odd(ctanh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall_odd(csin, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ testall_even(ccos, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
testall_odd(ctan, z, nan_nan, OPT_INVALID, 0, 0);
}
@@ -325,53 +238,53 @@ test_inf(void)
* 0,Inf +-0,NaN inval NaN,+-0 inval NaN,NaN inval
* finite,Inf NaN,NaN inval NaN,NaN inval NaN,NaN inval
*/
- z = cpackl(INFINITY, INFINITY);
- testall_odd(csinh, z, cpackl(INFINITY, NAN),
+ z = CMPLXL(INFINITY, INFINITY);
+ testall_odd(csinh, z, CMPLXL(INFINITY, NAN),
ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccosh, z, cpackl(INFINITY, NAN),
+ testall_even(ccosh, z, CMPLXL(INFINITY, NAN),
ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_odd(ctanh, z, cpackl(1, 0), ALL_STD_EXCEPT, 0, CS_REAL);
- testall_odd(csin, z, cpackl(NAN, INFINITY),
+ testall_odd(ctanh, z, CMPLXL(1, 0), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_odd(csin, z, CMPLXL(NAN, INFINITY),
ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccos, z, cpackl(INFINITY, NAN),
+ testall_even(ccos, z, CMPLXL(INFINITY, NAN),
ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_odd(ctan, z, cpackl(0, 1), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_odd(ctan, z, CMPLXL(0, 1), ALL_STD_EXCEPT, 0, CS_REAL);
/* XXX We allow spurious inexact exceptions here (hard to avoid). */
for (i = 0; i < sizeof(finites) / sizeof(finites[0]); i++) {
- z = cpackl(INFINITY, finites[i]);
+ z = CMPLXL(INFINITY, finites[i]);
c = INFINITY * cosl(finites[i]);
s = finites[i] == 0 ? finites[i] : INFINITY * sinl(finites[i]);
- testall_odd(csinh, z, cpackl(c, s), OPT_INEXACT, 0, CS_BOTH);
- testall_even(ccosh, z, cpackl(c, s), OPT_INEXACT, 0, CS_BOTH);
- testall_odd(ctanh, z, cpackl(1, 0 * sin(finites[i] * 2)),
+ testall_odd(csinh, z, CMPLXL(c, s), OPT_INEXACT, 0, CS_BOTH);
+ testall_even(ccosh, z, CMPLXL(c, s), OPT_INEXACT, 0, CS_BOTH);
+ testall_odd(ctanh, z, CMPLXL(1, 0 * sin(finites[i] * 2)),
OPT_INEXACT, 0, CS_BOTH);
- z = cpackl(finites[i], INFINITY);
- testall_odd(csin, z, cpackl(s, c), OPT_INEXACT, 0, CS_BOTH);
- testall_even(ccos, z, cpackl(c, -s), OPT_INEXACT, 0, CS_BOTH);
- testall_odd(ctan, z, cpackl(0 * sin(finites[i] * 2), 1),
+ z = CMPLXL(finites[i], INFINITY);
+ testall_odd(csin, z, CMPLXL(s, c), OPT_INEXACT, 0, CS_BOTH);
+ testall_even(ccos, z, CMPLXL(c, -s), OPT_INEXACT, 0, CS_BOTH);
+ testall_odd(ctan, z, CMPLXL(0 * sin(finites[i] * 2), 1),
OPT_INEXACT, 0, CS_BOTH);
}
- z = cpackl(0, INFINITY);
- testall_odd(csinh, z, cpackl(0, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccosh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_odd(ctanh, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
- z = cpackl(INFINITY, 0);
- testall_odd(csin, z, cpackl(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccos, z, cpackl(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_odd(ctan, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
-
- z = cpackl(42, INFINITY);
- testall_odd(csinh, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccosh, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ z = CMPLXL(0, INFINITY);
+ testall_odd(csinh, z, CMPLXL(0, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_even(ccosh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_odd(ctanh, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ z = CMPLXL(INFINITY, 0);
+ testall_odd(csin, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_even(ccos, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_odd(ctan, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+
+ z = CMPLXL(42, INFINITY);
+ testall_odd(csinh, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_even(ccosh, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
/* XXX We allow a spurious inexact exception here. */
- testall_odd(ctanh, z, cpackl(NAN, NAN), OPT_INEXACT, FE_INVALID, 0);
- z = cpackl(INFINITY, 42);
- testall_odd(csin, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccos, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_odd(ctanh, z, CMPLXL(NAN, NAN), OPT_INEXACT, FE_INVALID, 0);
+ z = CMPLXL(INFINITY, 42);
+ testall_odd(csin, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_even(ccos, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
/* XXX We allow a spurious inexact exception here. */
- testall_odd(ctan, z, cpackl(NAN, NAN), OPT_INEXACT, FE_INVALID, 0);
+ testall_odd(ctan, z, CMPLXL(NAN, NAN), OPT_INEXACT, FE_INVALID, 0);
}
/* Tests along the real and imaginary axes. */
@@ -387,26 +300,50 @@ test_axes(void)
for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) {
/* Real axis */
- z = cpackl(nums[i], 0.0);
- testall_odd_tol(csinh, z, cpackl(sinh(nums[i]), 0), 0);
- testall_even_tol(ccosh, z, cpackl(cosh(nums[i]), 0), 0);
- testall_odd_tol(ctanh, z, cpackl(tanh(nums[i]), 0), 1);
- testall_odd_tol(csin, z, cpackl(sin(nums[i]),
- copysign(0, cos(nums[i]))), 0);
- testall_even_tol(ccos, z, cpackl(cos(nums[i]),
- -copysign(0, sin(nums[i]))), 0);
- testall_odd_tol(ctan, z, cpackl(tan(nums[i]), 0), 1);
+ z = CMPLXL(nums[i], 0.0);
+ test_odd_tol(csinh, z, CMPLXL(sinh(nums[i]), 0), DBL_ULP());
+ test_even_tol(ccosh, z, CMPLXL(cosh(nums[i]), 0), DBL_ULP());
+ test_odd_tol(ctanh, z, CMPLXL(tanh(nums[i]), 0), DBL_ULP());
+ test_odd_tol(csin, z, CMPLXL(sin(nums[i]),
+ copysign(0, cos(nums[i]))), DBL_ULP());
+ test_even_tol(ccos, z, CMPLXL(cos(nums[i]),
+ -copysign(0, sin(nums[i]))), DBL_ULP());
+ test_odd_tol(ctan, z, CMPLXL(tan(nums[i]), 0), DBL_ULP());
+
+ test_odd_tol(csinhf, z, CMPLXL(sinhf(nums[i]), 0), FLT_ULP());
+ test_even_tol(ccoshf, z, CMPLXL(coshf(nums[i]), 0), FLT_ULP());
+ printf("%a %a\n", creal(z), cimag(z));
+ printf("%a %a\n", creal(ctanhf(z)), cimag(ctanhf(z)));
+ printf("%a\n", nextafterf(tanhf(nums[i]), INFINITY));
+ test_odd_tol(ctanhf, z, CMPLXL(tanhf(nums[i]), 0),
+ 1.3 * FLT_ULP());
+ test_odd_tol(csinf, z, CMPLXL(sinf(nums[i]),
+ copysign(0, cosf(nums[i]))), FLT_ULP());
+ test_even_tol(ccosf, z, CMPLXL(cosf(nums[i]),
+ -copysign(0, sinf(nums[i]))), 2 * FLT_ULP());
+ test_odd_tol(ctanf, z, CMPLXL(tanf(nums[i]), 0), FLT_ULP());
/* Imaginary axis */
- z = cpackl(0.0, nums[i]);
- testall_odd_tol(csinh, z, cpackl(copysign(0, cos(nums[i])),
- sin(nums[i])), 0);
- testall_even_tol(ccosh, z, cpackl(cos(nums[i]),
- copysign(0, sin(nums[i]))), 0);
- testall_odd_tol(ctanh, z, cpackl(0, tan(nums[i])), 1);
- testall_odd_tol(csin, z, cpackl(0, sinh(nums[i])), 0);
- testall_even_tol(ccos, z, cpackl(cosh(nums[i]), -0.0), 0);
- testall_odd_tol(ctan, z, cpackl(0, tanh(nums[i])), 1);
+ z = CMPLXL(0.0, nums[i]);
+ test_odd_tol(csinh, z, CMPLXL(copysign(0, cos(nums[i])),
+ sin(nums[i])), DBL_ULP());
+ test_even_tol(ccosh, z, CMPLXL(cos(nums[i]),
+ copysign(0, sin(nums[i]))), DBL_ULP());
+ test_odd_tol(ctanh, z, CMPLXL(0, tan(nums[i])), DBL_ULP());
+ test_odd_tol(csin, z, CMPLXL(0, sinh(nums[i])), DBL_ULP());
+ test_even_tol(ccos, z, CMPLXL(cosh(nums[i]), -0.0), DBL_ULP());
+ test_odd_tol(ctan, z, CMPLXL(0, tanh(nums[i])), DBL_ULP());
+
+ test_odd_tol(csinhf, z, CMPLXL(copysign(0, cosf(nums[i])),
+ sinf(nums[i])), FLT_ULP());
+ test_even_tol(ccoshf, z, CMPLXL(cosf(nums[i]),
+ copysign(0, sinf(nums[i]))), FLT_ULP());
+ test_odd_tol(ctanhf, z, CMPLXL(0, tanf(nums[i])), FLT_ULP());
+ test_odd_tol(csinf, z, CMPLXL(0, sinhf(nums[i])), FLT_ULP());
+ test_even_tol(ccosf, z, CMPLXL(coshf(nums[i]), -0.0),
+ FLT_ULP());
+ test_odd_tol(ctanf, z, CMPLXL(0, tanhf(nums[i])),
+ 1.3 * FLT_ULP());
}
}
@@ -462,13 +399,13 @@ test_small(void)
int i;
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
- z = cpackl(tests[i].a, tests[i].b);
+ z = CMPLXL(tests[i].a, tests[i].b);
testall_odd_tol(csinh, z,
- cpackl(tests[i].sinh_a, tests[i].sinh_b), 1.1);
+ CMPLXL(tests[i].sinh_a, tests[i].sinh_b), 1.1);
testall_even_tol(ccosh, z,
- cpackl(tests[i].cosh_a, tests[i].cosh_b), 1.1);
+ CMPLXL(tests[i].cosh_a, tests[i].cosh_b), 1.1);
testall_odd_tol(ctanh, z,
- cpackl(tests[i].tanh_a, tests[i].tanh_b), 1.1);
+ CMPLXL(tests[i].tanh_a, tests[i].tanh_b), 1.4);
}
}
@@ -479,36 +416,39 @@ test_large(void)
long double complex z;
/* tanh() uses a threshold around x=22, so check both sides. */
- z = cpackl(21, 0.78539816339744830961566084581987572L);
+ z = CMPLXL(21, 0.78539816339744830961566084581987572L);
testall_odd_tol(ctanh, z,
- cpackl(1.0, 1.14990445285871196133287617611468468e-18L), 1);
+ CMPLXL(1.0, 1.14990445285871196133287617611468468e-18L), 1.2);
z++;
testall_odd_tol(ctanh, z,
- cpackl(1.0, 1.55622644822675930314266334585597964e-19L), 1);
-
- z = cpackl(355, 0.78539816339744830961566084581987572L);
- testall_odd_tol(ctanh, z,
- cpackl(1.0, 8.95257245135025991216632140458264468e-309L), 1);
- z = cpackl(30, 0x1p1023L);
- testall_odd_tol(ctanh, z,
- cpackl(1.0, -1.62994325413993477997492170229268382e-26L), 1);
- z = cpackl(1, 0x1p1023L);
- testall_odd_tol(ctanh, z,
- cpackl(0.878606311888306869546254022621986509L,
- -0.225462792499754505792678258169527424L), 1);
-
- z = cpackl(710.6, 0.78539816339744830961566084581987572L);
- testall_odd_tol(csinh, z,
- cpackl(1.43917579766621073533185387499658944e308L,
- 1.43917579766621073533185387499658944e308L), 1);
- testall_even_tol(ccosh, z,
- cpackl(1.43917579766621073533185387499658944e308L,
- 1.43917579766621073533185387499658944e308L), 1);
-
- z = cpackl(1500, 0.78539816339744830961566084581987572L);
- testall_odd(csinh, z, cpackl(INFINITY, INFINITY), OPT_INEXACT,
+ CMPLXL(1.0, 1.55622644822675930314266334585597964e-19L), 1);
+
+ z = CMPLXL(355, 0.78539816339744830961566084581987572L);
+ test_odd_tol(ctanh, z,
+ CMPLXL(1.0, 8.95257245135025991216632140458264468e-309L),
+ DBL_ULP());
+ z = CMPLXL(30, 0x1p1023L);
+ test_odd_tol(ctanh, z,
+ CMPLXL(1.0, -1.62994325413993477997492170229268382e-26L),
+ DBL_ULP());
+ z = CMPLXL(1, 0x1p1023L);
+ test_odd_tol(ctanh, z,
+ CMPLXL(0.878606311888306869546254022621986509L,
+ -0.225462792499754505792678258169527424L),
+ DBL_ULP());
+
+ z = CMPLXL(710.6, 0.78539816339744830961566084581987572L);
+ test_odd_tol(csinh, z,
+ CMPLXL(1.43917579766621073533185387499658944e308L,
+ 1.43917579766621073533185387499658944e308L), DBL_ULP());
+ test_even_tol(ccosh, z,
+ CMPLXL(1.43917579766621073533185387499658944e308L,
+ 1.43917579766621073533185387499658944e308L), DBL_ULP());
+
+ z = CMPLXL(1500, 0.78539816339744830961566084581987572L);
+ testall_odd(csinh, z, CMPLXL(INFINITY, INFINITY), OPT_INEXACT,
FE_OVERFLOW, CS_BOTH);
- testall_even(ccosh, z, cpackl(INFINITY, INFINITY), OPT_INEXACT,
+ testall_even(ccosh, z, CMPLXL(INFINITY, INFINITY), OPT_INEXACT,
FE_OVERFLOW, CS_BOTH);
}
diff --git a/tools/regression/lib/msun/test-exponential.c b/tools/regression/lib/msun/test-exponential.c
index 53a6116..010e0fd 100644
--- a/tools/regression/lib/msun/test-exponential.c
+++ b/tools/regression/lib/msun/test-exponential.c
@@ -41,8 +41,7 @@ __FBSDID("$FreeBSD$");
#include <ieeefp.h>
#endif
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
@@ -63,7 +62,7 @@ __FBSDID("$FreeBSD$");
volatile long double _d = x; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
assert(fpequal((func)(_d), (result))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
/* Test all the functions that compute b^x. */
@@ -81,17 +80,6 @@ __FBSDID("$FreeBSD$");
test(expm1f, x, result, exceptmask, excepts); \
} while (0)
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y)
-{
- return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
-}
-
void
run_generic_tests(void)
{
diff --git a/tools/regression/lib/msun/test-fma.c b/tools/regression/lib/msun/test-fma.c
index 1237a60..1fcf889 100644
--- a/tools/regression/lib/msun/test-fma.c
+++ b/tools/regression/lib/msun/test-fma.c
@@ -37,8 +37,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
@@ -53,14 +52,17 @@ __FBSDID("$FreeBSD$");
* meaningful error messages.
*/
#define test(func, x, y, z, result, exceptmask, excepts) do { \
+ volatile long double _vx = (x), _vy = (y), _vz = (z); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(fpequal((func)((x), (y), (z)), (result))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(fpequal((func)(_vx, _vy, _vz), (result))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
#define testall(x, y, z, result, exceptmask, excepts) do { \
- test(fma, (x), (y), (z), (double)(result), (exceptmask), (excepts)); \
- test(fmaf, (x), (y), (z), (float)(result), (exceptmask), (excepts)); \
+ test(fma, (double)(x), (double)(y), (double)(z), \
+ (double)(result), (exceptmask), (excepts)); \
+ test(fmaf, (float)(x), (float)(y), (float)(z), \
+ (float)(result), (exceptmask), (excepts)); \
test(fmal, (x), (y), (z), (result), (exceptmask), (excepts)); \
} while (0)
@@ -77,17 +79,10 @@ __FBSDID("$FreeBSD$");
} while (0)
/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
+ * This is needed because clang constant-folds fma in ways that are incorrect
+ * in rounding modes other than FE_TONEAREST.
*/
-int
-fpequal(long double x, long double y)
-{
-
- return ((x == y && !signbit(x) == !signbit(y))
- || (isnan(x) && isnan(y)));
-}
+volatile double one = 1.0;
static void
test_zeroes(void)
@@ -108,9 +103,9 @@ test_zeroes(void)
testall(-0.0, 0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0);
testall(0.0, -0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0);
- testall(-1.0, 1.0, 1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
- testall(1.0, -1.0, 1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
- testall(-1.0, -1.0, -1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
+ testall(-one, one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
+ testall(one, -one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
+ testall(-one, -one, -one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
switch (fegetround()) {
case FE_TONEAREST:
@@ -190,53 +185,53 @@ test_small_z(void)
/* x*y positive, z positive */
if (fegetround() == FE_UPWARD) {
- test(fmaf, 1.0, 1.0, 0x1.0p-100, 1.0 + FLT_EPSILON,
+ test(fmaf, one, one, 0x1.0p-100, 1.0 + FLT_EPSILON,
ALL_STD_EXCEPT, FE_INEXACT);
- test(fma, 1.0, 1.0, 0x1.0p-200, 1.0 + DBL_EPSILON,
+ test(fma, one, one, 0x1.0p-200, 1.0 + DBL_EPSILON,
ALL_STD_EXCEPT, FE_INEXACT);
- test(fmal, 1.0, 1.0, 0x1.0p-200, 1.0 + LDBL_EPSILON,
+ test(fmal, one, one, 0x1.0p-200, 1.0 + LDBL_EPSILON,
ALL_STD_EXCEPT, FE_INEXACT);
} else {
- testall(0x1.0p100, 1.0, 0x1.0p-100, 0x1.0p100,
+ testall(0x1.0p100, one, 0x1.0p-100, 0x1.0p100,
ALL_STD_EXCEPT, FE_INEXACT);
}
/* x*y negative, z negative */
if (fegetround() == FE_DOWNWARD) {
- test(fmaf, -1.0, 1.0, -0x1.0p-100, -(1.0 + FLT_EPSILON),
+ test(fmaf, -one, one, -0x1.0p-100, -(1.0 + FLT_EPSILON),
ALL_STD_EXCEPT, FE_INEXACT);
- test(fma, -1.0, 1.0, -0x1.0p-200, -(1.0 + DBL_EPSILON),
+ test(fma, -one, one, -0x1.0p-200, -(1.0 + DBL_EPSILON),
ALL_STD_EXCEPT, FE_INEXACT);
- test(fmal, -1.0, 1.0, -0x1.0p-200, -(1.0 + LDBL_EPSILON),
+ test(fmal, -one, one, -0x1.0p-200, -(1.0 + LDBL_EPSILON),
ALL_STD_EXCEPT, FE_INEXACT);
} else {
- testall(0x1.0p100, -1.0, -0x1.0p-100, -0x1.0p100,
+ testall(0x1.0p100, -one, -0x1.0p-100, -0x1.0p100,
ALL_STD_EXCEPT, FE_INEXACT);
}
/* x*y positive, z negative */
if (fegetround() == FE_DOWNWARD || fegetround() == FE_TOWARDZERO) {
- test(fmaf, 1.0, 1.0, -0x1.0p-100, 1.0 - FLT_EPSILON / 2,
+ test(fmaf, one, one, -0x1.0p-100, 1.0 - FLT_EPSILON / 2,
ALL_STD_EXCEPT, FE_INEXACT);
- test(fma, 1.0, 1.0, -0x1.0p-200, 1.0 - DBL_EPSILON / 2,
+ test(fma, one, one, -0x1.0p-200, 1.0 - DBL_EPSILON / 2,
ALL_STD_EXCEPT, FE_INEXACT);
- test(fmal, 1.0, 1.0, -0x1.0p-200, 1.0 - LDBL_EPSILON / 2,
+ test(fmal, one, one, -0x1.0p-200, 1.0 - LDBL_EPSILON / 2,
ALL_STD_EXCEPT, FE_INEXACT);
} else {
- testall(0x1.0p100, 1.0, -0x1.0p-100, 0x1.0p100,
+ testall(0x1.0p100, one, -0x1.0p-100, 0x1.0p100,
ALL_STD_EXCEPT, FE_INEXACT);
}
/* x*y negative, z positive */
if (fegetround() == FE_UPWARD || fegetround() == FE_TOWARDZERO) {
- test(fmaf, -1.0, 1.0, 0x1.0p-100, -1.0 + FLT_EPSILON / 2,
+ test(fmaf, -one, one, 0x1.0p-100, -1.0 + FLT_EPSILON / 2,
ALL_STD_EXCEPT, FE_INEXACT);
- test(fma, -1.0, 1.0, 0x1.0p-200, -1.0 + DBL_EPSILON / 2,
+ test(fma, -one, one, 0x1.0p-200, -1.0 + DBL_EPSILON / 2,
ALL_STD_EXCEPT, FE_INEXACT);
- test(fmal, -1.0, 1.0, 0x1.0p-200, -1.0 + LDBL_EPSILON / 2,
+ test(fmal, -one, one, 0x1.0p-200, -1.0 + LDBL_EPSILON / 2,
ALL_STD_EXCEPT, FE_INEXACT);
} else {
- testall(-0x1.0p100, 1.0, 0x1.0p-100, -0x1.0p100,
+ testall(-0x1.0p100, one, 0x1.0p-100, -0x1.0p100,
ALL_STD_EXCEPT, FE_INEXACT);
}
}
diff --git a/tools/regression/lib/msun/test-fmaxmin.c b/tools/regression/lib/msun/test-fmaxmin.c
index fdba529..7ddcc87 100644
--- a/tools/regression/lib/msun/test-fmaxmin.c
+++ b/tools/regression/lib/msun/test-fmaxmin.c
@@ -36,25 +36,11 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
/*
- * Test for equality with two special rules:
- * fpequal(NaN, NaN) is true
- * fpequal(+0.0, -0.0) is false
- */
-static inline int
-fpequal(long double x, long double y)
-{
-
- return ((x == y && !signbit(x) == !signbit(y))
- || (isnan(x) && isnan(y)));
-}
-
-/*
* Test whether func(x, y) has the expected result, and make sure no
* exceptions are raised.
*/
diff --git a/tools/regression/lib/msun/test-invctrig.c b/tools/regression/lib/msun/test-invctrig.c
new file mode 100644
index 0000000..e78c26b
--- /dev/null
+++ b/tools/regression/lib/msun/test-invctrig.c
@@ -0,0 +1,372 @@
+/*-
+ * Copyright (c) 2008-2013 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Tests for casin[h](), cacos[h](), and catan[h]().
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <complex.h>
+#include <fenv.h>
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "test-utils.h"
+
+#pragma STDC FENV_ACCESS ON
+#pragma STDC CX_LIMITED_RANGE OFF
+
+/*
+ * Test that a function returns the correct value and sets the
+ * exception flags correctly. The exceptmask specifies which
+ * exceptions we should check. We need to be lenient for several
+ * reasons, but mainly because on some architectures it's impossible
+ * to raise FE_OVERFLOW without raising FE_INEXACT.
+ *
+ * These are macros instead of functions so that assert provides more
+ * meaningful error messages.
+ *
+ * XXX The volatile here is to avoid gcc's bogus constant folding and work
+ * around the lack of support for the FENV_ACCESS pragma.
+ */
+#define test_p(func, z, result, exceptmask, excepts, checksign) do { \
+ volatile long double complex _d = z; \
+ debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \
+ creall(_d), cimagl(_d), creall(result), cimagl(result)); \
+ assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
+ assert(cfpequal_cs((func)(_d), (result), (checksign))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
+} while (0)
+
+/*
+ * Test within a given tolerance. The tolerance indicates relative error
+ * in ulps.
+ */
+#define test_p_tol(func, z, result, tol) do { \
+ volatile long double complex _d = z; \
+ debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \
+ creall(_d), cimagl(_d), creall(result), cimagl(result)); \
+ assert(cfpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \
+} while (0)
+
+/* These wrappers apply the identities f(conj(z)) = conj(f(z)). */
+#define test(func, z, result, exceptmask, excepts, checksign) do { \
+ test_p(func, z, result, exceptmask, excepts, checksign); \
+ test_p(func, conjl(z), conjl(result), exceptmask, excepts, checksign); \
+} while (0)
+#define test_tol(func, z, result, tol) do { \
+ test_p_tol(func, z, result, tol); \
+ test_p_tol(func, conjl(z), conjl(result), tol); \
+} while (0)
+
+/* Test the given function in all precisions. */
+#define testall(func, x, result, exceptmask, excepts, checksign) do { \
+ test(func, x, result, exceptmask, excepts, checksign); \
+ test(func##f, x, result, exceptmask, excepts, checksign); \
+} while (0)
+#define testall_odd(func, x, result, exceptmask, excepts, checksign) do { \
+ testall(func, x, result, exceptmask, excepts, checksign); \
+ testall(func, -(x), -result, exceptmask, excepts, checksign); \
+} while (0)
+#define testall_even(func, x, result, exceptmask, excepts, checksign) do { \
+ testall(func, x, result, exceptmask, excepts, checksign); \
+ testall(func, -(x), result, exceptmask, excepts, checksign); \
+} while (0)
+
+/*
+ * Test the given function in all precisions, within a given tolerance.
+ * The tolerance is specified in ulps.
+ */
+#define testall_tol(func, x, result, tol) do { \
+ test_tol(func, x, result, (tol) * DBL_ULP()); \
+ test_tol(func##f, x, result, (tol) * FLT_ULP()); \
+} while (0)
+#define testall_odd_tol(func, x, result, tol) do { \
+ testall_tol(func, x, result, tol); \
+ testall_tol(func, -(x), -result, tol); \
+} while (0)
+#define testall_even_tol(func, x, result, tol) do { \
+ testall_tol(func, x, result, tol); \
+ testall_tol(func, -(x), result, tol); \
+} while (0)
+
+static const long double
+pi = 3.14159265358979323846264338327950280L,
+c3pi = 9.42477796076937971538793014983850839L;
+
+
+/* Tests for 0 */
+void
+test_zero(void)
+{
+ long double complex zero = CMPLXL(0.0, 0.0);
+
+ testall_tol(cacosh, zero, CMPLXL(0.0, pi / 2), 1);
+ testall_tol(cacosh, -zero, CMPLXL(0.0, -pi / 2), 1);
+ testall_tol(cacos, zero, CMPLXL(pi / 2, -0.0), 1);
+ testall_tol(cacos, -zero, CMPLXL(pi / 2, 0.0), 1);
+
+ testall_odd(casinh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
+ testall_odd(casin, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
+
+ testall_odd(catanh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
+ testall_odd(catan, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
+}
+
+/*
+ * Tests for NaN inputs.
+ */
+void
+test_nan()
+{
+ long double complex nan_nan = CMPLXL(NAN, NAN);
+ long double complex z;
+
+ /*
+ * IN CACOSH CACOS CASINH CATANH
+ * NaN,NaN NaN,NaN NaN,NaN NaN,NaN NaN,NaN
+ * finite,NaN NaN,NaN* NaN,NaN* NaN,NaN* NaN,NaN*
+ * NaN,finite NaN,NaN* NaN,NaN* NaN,NaN* NaN,NaN*
+ * NaN,Inf Inf,NaN NaN,-Inf ?Inf,NaN ?0,pi/2
+ * +-Inf,NaN Inf,NaN NaN,?Inf +-Inf,NaN +-0,NaN
+ * +-0,NaN NaN,NaN* pi/2,NaN NaN,NaN* +-0,NaN
+ * NaN,0 NaN,NaN* NaN,NaN* NaN,0 NaN,NaN*
+ *
+ * * = raise invalid
+ */
+ z = nan_nan;
+ testall(cacosh, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
+ testall(cacos, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
+ testall(casinh, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
+ testall(casin, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
+ testall(catanh, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
+ testall(catan, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
+
+ z = CMPLXL(0.5, NAN);
+ testall(cacosh, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(cacos, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(casinh, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(casin, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(catanh, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(catan, z, nan_nan, OPT_INVALID, 0, 0);
+
+ z = CMPLXL(NAN, 0.5);
+ testall(cacosh, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(cacos, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(casinh, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(casin, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(catanh, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(catan, z, nan_nan, OPT_INVALID, 0, 0);
+
+ z = CMPLXL(NAN, INFINITY);
+ testall(cacosh, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall(cacosh, -z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall(cacos, z, CMPLXL(NAN, -INFINITY), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall(casinh, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0, 0);
+ testall(casin, z, CMPLXL(NAN, INFINITY), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall_tol(catanh, z, CMPLXL(0.0, pi / 2), 1);
+ testall(catan, z, CMPLXL(NAN, 0.0), ALL_STD_EXCEPT, 0, CS_IMAG);
+
+ z = CMPLXL(INFINITY, NAN);
+ testall_even(cacosh, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0,
+ CS_REAL);
+ testall_even(cacos, z, CMPLXL(NAN, INFINITY), ALL_STD_EXCEPT, 0, 0);
+ testall_odd(casinh, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0,
+ CS_REAL);
+ testall_odd(casin, z, CMPLXL(NAN, INFINITY), ALL_STD_EXCEPT, 0, 0);
+ testall_odd(catanh, z, CMPLXL(0.0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_odd_tol(catan, z, CMPLXL(pi / 2, 0.0), 1);
+
+ z = CMPLXL(0.0, NAN);
+ /* XXX We allow a spurious inexact exception here. */
+ testall_even(cacosh, z, nan_nan, OPT_INVALID & ~FE_INEXACT, 0, 0);
+ testall_even_tol(cacos, z, CMPLXL(pi / 2, NAN), 1);
+ testall_odd(casinh, z, nan_nan, OPT_INVALID, 0, 0);
+ testall_odd(casin, z, CMPLXL(0.0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_odd(catanh, z, CMPLXL(0.0, NAN), OPT_INVALID, 0, CS_REAL);
+ testall_odd(catan, z, nan_nan, OPT_INVALID, 0, 0);
+
+ z = CMPLXL(NAN, 0.0);
+ testall(cacosh, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(cacos, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(casinh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall(casin, z, nan_nan, OPT_INVALID, 0, 0);
+ testall(catanh, z, nan_nan, OPT_INVALID, 0, CS_IMAG);
+ testall(catan, z, CMPLXL(NAN, 0.0), ALL_STD_EXCEPT, 0, 0);
+}
+
+void
+test_inf(void)
+{
+ long double complex z;
+
+ /*
+ * IN CACOSH CACOS CASINH CATANH
+ * Inf,Inf Inf,pi/4 pi/4,-Inf Inf,pi/4 0,pi/2
+ * -Inf,Inf Inf,3pi/4 3pi/4,-Inf --- ---
+ * Inf,finite Inf,0 0,-Inf Inf,0 0,pi/2
+ * -Inf,finite Inf,pi pi,-Inf --- ---
+ * finite,Inf Inf,pi/2 pi/2,-Inf Inf,pi/2 0,pi/2
+ */
+ z = CMPLXL(INFINITY, INFINITY);
+ testall_tol(cacosh, z, CMPLXL(INFINITY, pi / 4), 1);
+ testall_tol(cacosh, -z, CMPLXL(INFINITY, -c3pi / 4), 1);
+ testall_tol(cacos, z, CMPLXL(pi / 4, -INFINITY), 1);
+ testall_tol(cacos, -z, CMPLXL(c3pi / 4, INFINITY), 1);
+ testall_odd_tol(casinh, z, CMPLXL(INFINITY, pi / 4), 1);
+ testall_odd_tol(casin, z, CMPLXL(pi / 4, INFINITY), 1);
+ testall_odd_tol(catanh, z, CMPLXL(0, pi / 2), 1);
+ testall_odd_tol(catan, z, CMPLXL(pi / 2, 0), 1);
+
+ z = CMPLXL(INFINITY, 0.5);
+ /* XXX We allow a spurious inexact exception here. */
+ testall(cacosh, z, CMPLXL(INFINITY, 0), OPT_INEXACT, 0, CS_BOTH);
+ testall_tol(cacosh, -z, CMPLXL(INFINITY, -pi), 1);
+ testall(cacos, z, CMPLXL(0, -INFINITY), OPT_INEXACT, 0, CS_BOTH);
+ testall_tol(cacos, -z, CMPLXL(pi, INFINITY), 1);
+ testall_odd(casinh, z, CMPLXL(INFINITY, 0), OPT_INEXACT, 0, CS_BOTH);
+ testall_odd_tol(casin, z, CMPLXL(pi / 2, INFINITY), 1);
+ testall_odd_tol(catanh, z, CMPLXL(0, pi / 2), 1);
+ testall_odd_tol(catan, z, CMPLXL(pi / 2, 0), 1);
+
+ z = CMPLXL(0.5, INFINITY);
+ testall_tol(cacosh, z, CMPLXL(INFINITY, pi / 2), 1);
+ testall_tol(cacosh, -z, CMPLXL(INFINITY, -pi / 2), 1);
+ testall_tol(cacos, z, CMPLXL(pi / 2, -INFINITY), 1);
+ testall_tol(cacos, -z, CMPLXL(pi / 2, INFINITY), 1);
+ testall_odd_tol(casinh, z, CMPLXL(INFINITY, pi / 2), 1);
+ /* XXX We allow a spurious inexact exception here. */
+ testall_odd(casin, z, CMPLXL(0.0, INFINITY), OPT_INEXACT, 0, CS_BOTH);
+ testall_odd_tol(catanh, z, CMPLXL(0, pi / 2), 1);
+ testall_odd_tol(catan, z, CMPLXL(pi / 2, 0), 1);
+}
+
+/* Tests along the real and imaginary axes. */
+void
+test_axes(void)
+{
+ static const long double nums[] = {
+ -2, -1, -0.5, 0.5, 1, 2
+ };
+ long double complex z;
+ int i;
+
+ for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) {
+ /* Real axis */
+ z = CMPLXL(nums[i], 0.0);
+ if (fabs(nums[i]) <= 1) {
+ testall_tol(cacosh, z, CMPLXL(0.0, acos(nums[i])), 1);
+ testall_tol(cacos, z, CMPLXL(acosl(nums[i]), -0.0), 1);
+ testall_tol(casin, z, CMPLXL(asinl(nums[i]), 0.0), 1);
+ testall_tol(catanh, z, CMPLXL(atanh(nums[i]), 0.0), 1);
+ } else {
+ testall_tol(cacosh, z,
+ CMPLXL(acosh(fabs(nums[i])),
+ (nums[i] < 0) ? pi : 0), 1);
+ testall_tol(cacos, z,
+ CMPLXL((nums[i] < 0) ? pi : 0,
+ -acosh(fabs(nums[i]))), 1);
+ testall_tol(casin, z,
+ CMPLXL(copysign(pi / 2, nums[i]),
+ acosh(fabs(nums[i]))), 1);
+ testall_tol(catanh, z,
+ CMPLXL(atanh(1 / nums[i]), pi / 2), 1);
+ }
+ testall_tol(casinh, z, CMPLXL(asinh(nums[i]), 0.0), 1);
+ testall_tol(catan, z, CMPLXL(atan(nums[i]), 0), 1);
+
+ /* TODO: Test the imaginary axis. */
+ }
+}
+
+void
+test_small(void)
+{
+ /*
+ * z = 0.75 + i 0.25
+ * acos(z) = Pi/4 - i ln(2)/2
+ * asin(z) = Pi/4 + i ln(2)/2
+ * atan(z) = atan(4)/2 + i ln(17/9)/4
+ */
+ static const struct {
+ complex long double z;
+ complex long double acos_z;
+ complex long double asin_z;
+ complex long double atan_z;
+ } tests[] = {
+ { CMPLXL(0.75L, 0.25L),
+ CMPLXL(pi / 4, -0.34657359027997265470861606072908828L),
+ CMPLXL(pi / 4, 0.34657359027997265470861606072908828L),
+ CMPLXL(0.66290883183401623252961960521423782L,
+ 0.15899719167999917436476103600701878L) },
+ };
+ int i;
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ testall_tol(cacos, tests[i].z, tests[i].acos_z, 2);
+ testall_odd_tol(casin, tests[i].z, tests[i].asin_z, 2);
+ testall_odd_tol(catan, tests[i].z, tests[i].atan_z, 2);
+ }
+}
+
+/* Test inputs that might cause overflow in a sloppy implementation. */
+void
+test_large(void)
+{
+
+ /* TODO: Write these tests */
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ printf("1..6\n");
+
+ test_zero();
+ printf("ok 1 - invctrig zero\n");
+
+ test_nan();
+ printf("ok 2 - invctrig nan\n");
+
+ test_inf();
+ printf("ok 3 - invctrig inf\n");
+
+ test_axes();
+ printf("ok 4 - invctrig axes\n");
+
+ test_small();
+ printf("ok 5 - invctrig small\n");
+
+ test_large();
+ printf("ok 6 - invctrig large\n");
+
+ return (0);
+}
diff --git a/tools/regression/lib/msun/test-invtrig.c b/tools/regression/lib/msun/test-invtrig.c
index 05d310f..2523d59 100644
--- a/tools/regression/lib/msun/test-invtrig.c
+++ b/tools/regression/lib/msun/test-invtrig.c
@@ -39,8 +39,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#define LEN(a) (sizeof(a) / sizeof((a)[0]))
@@ -58,8 +57,8 @@ __FBSDID("$FreeBSD$");
#define test_tol(func, x, result, tol, excepts) do { \
volatile long double _in = (x), _out = (result); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(fpequal(func(_in), _out, (tol))); \
- assert((func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
+ assert(fpequal_tol(func(_in), _out, (tol), CS_BOTH)); \
+ assert(((void)func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
} while (0)
#define test(func, x, result, excepts) \
test_tol(func, (x), (result), 0, (excepts))
@@ -78,8 +77,8 @@ __FBSDID("$FreeBSD$");
#define test2_tol(func, y, x, result, tol, excepts) do { \
volatile long double _iny = (y), _inx = (x), _out = (result); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(fpequal(func(_iny, _inx), _out, (tol))); \
- assert((func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
+ assert(fpequal_tol(func(_iny, _inx), _out, (tol), CS_BOTH)); \
+ assert(((void)func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
} while (0)
#define test2(func, y, x, result, excepts) \
test2_tol(func, (y), (x), (result), 0, (excepts))
@@ -104,33 +103,6 @@ c7pi = 2.19911485751285526692385036829565196e+01L,
c5pio3 = 5.23598775598298873077107230546583851e+00L,
sqrt2m1 = 4.14213562373095048801688724209698081e-01L;
-/*
- * Determine whether x and y are equal to within a relative error of tol,
- * with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y, long double tol)
-{
- fenv_t env;
- int ret;
-
- if (isnan(x) && isnan(y))
- return (1);
- if (!signbit(x) != !signbit(y))
- return (0);
- if (x == y)
- return (1);
- if (tol == 0)
- return (0);
-
- /* Hard case: need to check the tolerance. */
- feholdexcept(&env);
- ret = fabsl(x - y) <= fabsl(y * tol);
- fesetenv(&env);
- return (ret);
-}
/*
* Test special case inputs in asin(), acos() and atan(): signed
diff --git a/tools/regression/lib/msun/test-logarithm.c b/tools/regression/lib/msun/test-logarithm.c
index 258c514..18b9ebe 100644
--- a/tools/regression/lib/msun/test-logarithm.c
+++ b/tools/regression/lib/msun/test-logarithm.c
@@ -41,8 +41,7 @@ __FBSDID("$FreeBSD$");
#include <ieeefp.h>
#endif
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
@@ -63,36 +62,42 @@ __FBSDID("$FreeBSD$");
volatile long double _d = x; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
assert(fpequal((func)(_d), (result))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
+} while (0)
+
+#define test(func, x, result, exceptmask, excepts) do { \
+ volatile long double _d = x; \
+ assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
+ assert(fpequal((func)(_d), (result))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
+} while (0)
+
+#define test_tol(func, z, result, tol) do { \
+ volatile long double _d = z; \
+ debug(" testing %6s(%15La) ~= % .36Le\n", #func, _d, result); \
+ assert(fpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \
} while (0)
/* Test all the functions that compute log(x). */
#define testall0(x, result, exceptmask, excepts) do { \
test(log, x, result, exceptmask, excepts); \
test(logf, x, result, exceptmask, excepts); \
+ test(logl, x, result, exceptmask, excepts); \
test(log2, x, result, exceptmask, excepts); \
test(log2f, x, result, exceptmask, excepts); \
+ test(log2l, x, result, exceptmask, excepts); \
test(log10, x, result, exceptmask, excepts); \
test(log10f, x, result, exceptmask, excepts); \
+ test(log10l, x, result, exceptmask, excepts); \
} while (0)
/* Test all the functions that compute log(1+x). */
#define testall1(x, result, exceptmask, excepts) do { \
test(log1p, x, result, exceptmask, excepts); \
test(log1pf, x, result, exceptmask, excepts); \
+ test(log1pl, x, result, exceptmask, excepts); \
} while (0)
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y)
-{
- return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
-}
-
void
run_generic_tests(void)
{
@@ -140,6 +145,13 @@ run_log2_tests(void)
assert(log2(ldexp(1.0, i)) == i);
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
}
+ for (i = LDBL_MIN_EXP - LDBL_MANT_DIG; i < LDBL_MAX_EXP; i++) {
+ assert(log2l(ldexpl(1.0, i)) == i);
+#if 0
+ /* XXX This test does not pass yet. */
+ assert(fetestexcept(ALL_STD_EXCEPT) == 0);
+#endif
+ }
}
void
@@ -151,7 +163,17 @@ run_roundingmode_tests(void)
*/
fesetround(FE_DOWNWARD);
/* These are still positive per IEEE 754R */
+#if 0
testall0(1.0, 0.0, ALL_STD_EXCEPT, 0);
+#else
+ /* logl, log2l, and log10l don't pass yet. */
+ test(log, 1.0, 0.0, ALL_STD_EXCEPT, 0);
+ test(logf, 1.0, 0.0, ALL_STD_EXCEPT, 0);
+ test(log2, 1.0, 0.0, ALL_STD_EXCEPT, 0);
+ test(log2f, 1.0, 0.0, ALL_STD_EXCEPT, 0);
+ test(log10, 1.0, 0.0, ALL_STD_EXCEPT, 0);
+ test(log10f, 1.0, 0.0, ALL_STD_EXCEPT, 0);
+#endif
testall1(0.0, 0.0, ALL_STD_EXCEPT, 0);
fesetround(FE_TOWARDZERO);
testall0(1.0, 0.0, ALL_STD_EXCEPT, 0);
@@ -166,11 +188,84 @@ run_roundingmode_tests(void)
fesetround(FE_TONEAREST);
}
+void
+run_accuracy_tests(void)
+{
+ static const struct {
+ float x;
+ long double log2x;
+ long double logex;
+ long double log10x;
+ } tests[] = {
+ { 0x1p-120 + 0x1p-140,
+ -1.19999998624139449158861798943319717e2L,
+ -8.31776607135195754708796206665656732e1L,
+ -3.61235990655024477716980559136055915e1L,
+ },
+ { 1.0 - 0x1p-20,
+ -1.37586186296463416424364914705656460e-6L,
+ -9.53674771153890007250243736279163253e-7L,
+ -4.14175690642480911859354110516159131e-7L, },
+ { 1.0 + 0x1p-20,
+ 1.37586055084113820105668028340371476e-6L,
+ 9.53673861659188233908415514963336144e-7L,
+ 4.14175295653950611453333571759200697e-7L },
+ { 19.75,
+ 4.30378074817710292442728634194115348e0L,
+ 2.98315349134713087533848129856505779e0L,
+ 1.29556709996247903756734359702926363e0L },
+ { 19.75 * 0x1p100,
+ 1.043037807481771029244272863419411534e2L,
+ 7.229787154734166181706169344438271459e1L,
+ 3.139856666636059855894123306947856631e1L },
+ };
+ int i;
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ test_tol(log2, tests[i].x, tests[i].log2x, DBL_ULP());
+ test_tol(log2f, tests[i].x, tests[i].log2x, FLT_ULP());
+ test_tol(log2l, tests[i].x, tests[i].log2x, LDBL_ULP());
+ test_tol(log, tests[i].x, tests[i].logex, DBL_ULP());
+ test_tol(logf, tests[i].x, tests[i].logex, FLT_ULP());
+ test_tol(logl, tests[i].x, tests[i].logex, LDBL_ULP());
+ test_tol(log10, tests[i].x, tests[i].log10x, DBL_ULP());
+ test_tol(log10f, tests[i].x, tests[i].log10x, FLT_ULP());
+ test_tol(log10l, tests[i].x, tests[i].log10x, LDBL_ULP());
+ if (tests[i].x >= 0.5) {
+ test_tol(log1p, tests[i].x - 1, tests[i].logex,
+ DBL_ULP());
+ test_tol(log1pf, tests[i].x - 1, tests[i].logex,
+ FLT_ULP());
+ test_tol(log1pl, tests[i].x - 1, tests[i].logex,
+ LDBL_ULP());
+ }
+ }
+}
+
+void
+run_log1p_accuracy_tests(void)
+{
+
+ test_tol(log1pf, 0x0.333333p0F,
+ 1.82321546859847114303367992804596800640e-1L, FLT_ULP());
+ test_tol(log1p, 0x0.3333333333333p0,
+ 1.82321556793954589204283870982629267635e-1L, DBL_ULP());
+ test_tol(log1pl, 0x0.33333333333333332p0L,
+ 1.82321556793954626202683007050468762914e-1L, LDBL_ULP());
+
+ test_tol(log1pf, -0x0.333333p0F,
+ -2.23143536413048672940940199918017467652e-1L, FLT_ULP());
+ test_tol(log1p, -0x0.3333333333333p0,
+ -2.23143551314209700255143859052009022937e-1L, DBL_ULP());
+ test_tol(log1pl, -0x0.33333333333333332p0L,
+ -2.23143551314209755752742563153765697950e-1L, LDBL_ULP());
+}
+
int
main(int argc, char *argv[])
{
- printf("1..3\n");
+ printf("1..5\n");
run_generic_tests();
printf("ok 1 - logarithm\n");
@@ -181,5 +276,11 @@ main(int argc, char *argv[])
run_roundingmode_tests();
printf("ok 3 - logarithm\n");
+ run_accuracy_tests();
+ printf("ok 4 - logarithm\n");
+
+ run_log1p_accuracy_tests();
+ printf("ok 5 - logarithm\n");
+
return (0);
}
diff --git a/tools/regression/lib/msun/test-nearbyint.c b/tools/regression/lib/msun/test-nearbyint.c
index 7251acb..602ea2a 100644
--- a/tools/regression/lib/msun/test-nearbyint.c
+++ b/tools/regression/lib/msun/test-nearbyint.c
@@ -40,8 +40,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
static int testnum;
@@ -49,6 +48,14 @@ static const int rmodes[] = {
FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO,
};
+/* Make sure we're testing the library, not some broken compiler built-ins. */
+double (*libnearbyint)(double) = nearbyint;
+float (*libnearbyintf)(float) = nearbyintf;
+long double (*libnearbyintl)(long double) = nearbyintl;
+#define nearbyintf libnearbyintf
+#define nearbyint libnearbyint
+#define nearbyintl libnearbyintl
+
static const struct {
float in;
float out[3]; /* one answer per rounding mode except towardzero */
@@ -64,19 +71,6 @@ static const struct {
static const int ntests = sizeof(tests) / sizeof(tests[0]);
-/*
- * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
- * Fail an assertion if they differ.
- */
-static int
-fpequal(long double d1, long double d2)
-{
-
- if (d1 != d2)
- return (isnan(d1) && isnan(d2));
- return (copysignl(1.0, d1) == copysignl(1.0, d2));
-}
-
/* Get the appropriate result for the current rounding mode. */
static float
get_output(int testindex, int rmodeindex, int negative)
@@ -107,7 +101,7 @@ test_nearby(int testindex)
in = tests[testindex].in;
out = get_output(testindex, i, 0);
- assert(fpequal(out, nearbyintf(in)));
+ assert(fpequal(out, libnearbyintf(in)));
assert(fpequal(out, nearbyint(in)));
assert(fpequal(out, nearbyintl(in)));
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
diff --git a/tools/regression/lib/msun/test-next.c b/tools/regression/lib/msun/test-next.c
index 68e4361..d16fa77 100644
--- a/tools/regression/lib/msun/test-next.c
+++ b/tools/regression/lib/msun/test-next.c
@@ -41,8 +41,8 @@ __FBSDID("$FreeBSD$");
#include <ieeefp.h>
#endif
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID |\
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
+
#define test(exp, ans, ex) do { \
double __ans = (ans); \
feclearexcept(ALL_STD_EXCEPT); \
@@ -235,7 +235,7 @@ _testl(const char *exp, int line, long double actual, long double expected,
int actual_except;
actual_except = fetestexcept(ALL_STD_EXCEPT);
- if (actual != expected && !(isnan(actual) && isnan(expected))) {
+ if (!fpequal(actual, expected)) {
fprintf(stderr, "%d: %s returned %La, expecting %La\n",
line, exp, actual, expected);
abort();
diff --git a/tools/regression/lib/msun/test-rem.c b/tools/regression/lib/msun/test-rem.c
index 840bea3..36e3476 100644
--- a/tools/regression/lib/msun/test-rem.c
+++ b/tools/regression/lib/msun/test-rem.c
@@ -67,8 +67,8 @@ main(int argc, char *argv[])
test(4, 4, 0, 1);
test(0, 3.0, 0, 0);
- testd(0x1p-1074, 1, 0x1p-1074, 0x1p-1074);
- testf(0x1p-149, 1, 0x1p-149, 0x1p-149);
+ testd(0x1p-1074, 1, 0x1p-1074, 0);
+ testf(0x1p-149, 1, 0x1p-149, 0);
test(3.0, 4, -1, 1);
test(3.0, -4, -1, -1);
testd(275 * 1193040, 275, 0, 1193040);
diff --git a/tools/regression/lib/msun/test-trig.c b/tools/regression/lib/msun/test-trig.c
index 1ac7873..80f1aef 100644
--- a/tools/regression/lib/msun/test-trig.c
+++ b/tools/regression/lib/msun/test-trig.c
@@ -42,8 +42,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#define LEN(a) (sizeof(a) / sizeof((a)[0]))
@@ -66,7 +65,7 @@ __FBSDID("$FreeBSD$");
volatile long double _d = x; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
assert(fpequal((func)(_d), (result))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
#define testall(prefix, x, result, exceptmask, excepts) do { \
@@ -80,19 +79,6 @@ __FBSDID("$FreeBSD$");
test(prefix##f, x, (float)result, exceptmask, excepts); \
} while (0)
-
-
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y)
-{
- return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
-}
-
/*
* Test special cases in sin(), cos(), and tan().
*/
diff --git a/tools/regression/lib/msun/test-utils.h b/tools/regression/lib/msun/test-utils.h
new file mode 100644
index 0000000..bf0d6de
--- /dev/null
+++ b/tools/regression/lib/msun/test-utils.h
@@ -0,0 +1,174 @@
+/*-
+ * Copyright (c) 2005-2013 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _TEST_UTILS_H_
+#define _TEST_UTILS_H_
+
+#include <complex.h>
+#include <fenv.h>
+
+/*
+ * Implementations are permitted to define additional exception flags
+ * not specified in the standard, so it is not necessarily true that
+ * FE_ALL_EXCEPT == ALL_STD_EXCEPT.
+ */
+#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
+ FE_OVERFLOW | FE_UNDERFLOW)
+#define OPT_INVALID (ALL_STD_EXCEPT & ~FE_INVALID)
+#define OPT_INEXACT (ALL_STD_EXCEPT & ~FE_INEXACT)
+#define FLT_ULP() ldexpl(1.0, 1 - FLT_MANT_DIG)
+#define DBL_ULP() ldexpl(1.0, 1 - DBL_MANT_DIG)
+#define LDBL_ULP() ldexpl(1.0, 1 - LDBL_MANT_DIG)
+
+/*
+ * Flags that control the behavior of various fpequal* functions.
+ * XXX This is messy due to merging various notions of "close enough"
+ * that are best suited for different functions.
+ *
+ * CS_REAL
+ * CS_IMAG
+ * CS_BOTH
+ * (cfpequal_cs, fpequal_tol, cfpequal_tol) Whether to check the sign of
+ * the real part of the result, the imaginary part, or both.
+ *
+ * FPE_ABS_ZERO
+ * (fpequal_tol, cfpequal_tol) If set, treats the tolerance as an absolute
+ * tolerance when the expected value is 0. This is useful when there is
+ * round-off error in the input, e.g., cos(Pi/2) ~= 0.
+ */
+#define CS_REAL 0x01
+#define CS_IMAG 0x02
+#define CS_BOTH (CS_REAL | CS_IMAG)
+#define FPE_ABS_ZERO 0x04
+
+#ifdef DEBUG
+#define debug(...) printf(__VA_ARGS__)
+#else
+#define debug(...) (void)0
+#endif
+
+/*
+ * XXX The ancient version of gcc in the base system doesn't support CMPLXL,
+ * but we can fake it most of the time.
+ */
+#ifndef CMPLXL
+static inline long double complex
+CMPLXL(long double x, long double y)
+{
+ long double complex z;
+
+ __real__ z = x;
+ __imag__ z = y;
+ return (z);
+}
+#endif
+
+/*
+ * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
+ * Fail an assertion if they differ.
+ */
+static int
+fpequal(long double d1, long double d2)
+{
+
+ if (d1 != d2)
+ return (isnan(d1) && isnan(d2));
+ return (copysignl(1.0, d1) == copysignl(1.0, d2));
+}
+
+/*
+ * Determine whether x and y are equal, with two special rules:
+ * +0.0 != -0.0
+ * NaN == NaN
+ * If checksign is 0, we compare the absolute values instead.
+ */
+static int
+fpequal_cs(long double x, long double y, int checksign)
+{
+ if (isnan(x) && isnan(y))
+ return (1);
+ if (checksign)
+ return (x == y && !signbit(x) == !signbit(y));
+ else
+ return (fabsl(x) == fabsl(y));
+}
+
+static int
+fpequal_tol(long double x, long double y, long double tol, unsigned int flags)
+{
+ fenv_t env;
+ int ret;
+
+ if (isnan(x) && isnan(y))
+ return (1);
+ if (!signbit(x) != !signbit(y) && (flags & CS_BOTH))
+ return (0);
+ if (x == y)
+ return (1);
+ if (tol == 0)
+ return (0);
+
+ /* Hard case: need to check the tolerance. */
+ feholdexcept(&env);
+ /*
+ * For our purposes here, if y=0, we interpret tol as an absolute
+ * tolerance. This is to account for roundoff in the input, e.g.,
+ * cos(Pi/2) ~= 0.
+ */
+ if ((flags & FPE_ABS_ZERO) && y == 0.0)
+ ret = fabsl(x - y) <= fabsl(tol);
+ else
+ ret = fabsl(x - y) <= fabsl(y * tol);
+ fesetenv(&env);
+ return (ret);
+}
+
+static int
+cfpequal(long double complex d1, long double complex d2)
+{
+
+ return (fpequal(creall(d1), creall(d2)) &&
+ fpequal(cimagl(d1), cimagl(d2)));
+}
+
+static int
+cfpequal_cs(long double complex x, long double complex y, int checksign)
+{
+ return (fpequal_cs(creal(x), creal(y), checksign)
+ && fpequal_cs(cimag(x), cimag(y), checksign));
+}
+
+static int
+cfpequal_tol(long double complex x, long double complex y, long double tol,
+ unsigned int flags)
+{
+ return (fpequal_tol(creal(x), creal(y), tol, flags)
+ && fpequal_tol(cimag(x), cimag(y), tol, flags));
+}
+
+#endif /* _TEST_UTILS_H_ */
diff --git a/tools/regression/pjdfstest/pjdfstest.c b/tools/regression/pjdfstest/pjdfstest.c
index fd19084..ceab2dc 100644
--- a/tools/regression/pjdfstest/pjdfstest.c
+++ b/tools/regression/pjdfstest/pjdfstest.c
@@ -581,13 +581,18 @@ call_syscall(struct syscall_desc *scall, char *argv[])
args[i].str = (void *)0xdeadc0de;
else
args[i].str = argv[i];
- } else if ((scall->sd_args[i] & TYPE_MASK) == TYPE_NUMBER) {
+ } else if ((scall->sd_args[i] & TYPE_MASK) ==
+ TYPE_NUMBER) {
args[i].num = strtoll(argv[i], &endp, 0);
- if (*endp != '\0' && !isspace((unsigned char)*endp)) {
- fprintf(stderr, "invalid argument %u, number expected [%s]\n", i, endp);
+ if (*endp != '\0' &&
+ !isspace((unsigned char)*endp)) {
+ fprintf(stderr,
+ "invalid argument %u, number expected [%s]\n",
+ i, endp);
exit(1);
}
- } else if ((scall->sd_args[i] & TYPE_MASK) == TYPE_DESCRIPTOR) {
+ } else if ((scall->sd_args[i] & TYPE_MASK) ==
+ TYPE_DESCRIPTOR) {
if (strcmp(argv[i], "AT_FDCWD") == 0) {
args[i].num = AT_FDCWD;
} else if (strcmp(argv[i], "BADFD") == 0) {
@@ -600,8 +605,11 @@ call_syscall(struct syscall_desc *scall, char *argv[])
int pos;
pos = strtoll(argv[i], &endp, 0);
- if (*endp != '\0' && !isspace((unsigned char)*endp)) {
- fprintf(stderr, "invalid argument %u, number expected [%s]\n", i, endp);
+ if (*endp != '\0' &&
+ !isspace((unsigned char)*endp)) {
+ fprintf(stderr,
+ "invalid argument %u, number expected [%s]\n",
+ i, endp);
exit(1);
}
args[i].num = descriptor_get(pos);
@@ -640,7 +648,8 @@ call_syscall(struct syscall_desc *scall, char *argv[])
fprintf(stderr, "too few arguments\n");
exit(1);
}
- rval = openat(NUM(0), STR(1), (int)flags, (mode_t)NUM(3));
+ rval = openat(NUM(0), STR(1), (int)flags,
+ (mode_t)NUM(3));
} else {
if (i == 4) {
fprintf(stderr, "too many arguments\n");
@@ -716,7 +725,7 @@ call_syscall(struct syscall_desc *scall, char *argv[])
}
dev = makedev(NUM(fa + 3), NUM(fa + 4));
- if (strcmp(STR(fa + 1), "c") == 0) /* character device */
+ if (strcmp(STR(fa + 1), "c") == 0) /* character device */
ntype = S_IFCHR;
else if (strcmp(STR(fa + 1), "b") == 0) /* block device */
ntype = S_IFBLK;
@@ -988,7 +997,8 @@ set_gids(char *gids)
assert(ngroups > 0);
gidset = malloc(sizeof(*gidset) * ngroups);
assert(gidset != NULL);
- for (i = 0, g = strtok(gids, ","); g != NULL; g = strtok(NULL, ","), i++) {
+ for (i = 0, g = strtok(gids, ","); g != NULL;
+ g = strtok(NULL, ","), i++) {
if (i >= ngroups) {
fprintf(stderr, "too many gids\n");
exit(1);
@@ -1005,7 +1015,8 @@ set_gids(char *gids)
exit(1);
}
if (setegid(gidset[0]) < 0) {
- fprintf(stderr, "cannot change effective gid: %s\n", strerror(errno));
+ fprintf(stderr, "cannot change effective gid: %s\n",
+ strerror(errno));
exit(1);
}
free(gidset);
@@ -1075,7 +1086,8 @@ main(int argc, char *argv[])
for (;;) {
scall = find_syscall(argv[0]);
if (scall == NULL) {
- fprintf(stderr, "syscall '%s' not supported\n", argv[0]);
+ fprintf(stderr, "syscall '%s' not supported\n",
+ argv[0]);
exit(1);
}
argc++;
diff --git a/tools/regression/priv/Makefile b/tools/regression/priv/Makefile
index 663d68d..9ed28a7 100644
--- a/tools/regression/priv/Makefile
+++ b/tools/regression/priv/Makefile
@@ -45,7 +45,7 @@ SRCS= main.c \
priv_vm_mlock.c \
priv_vm_munlock.c
-NO_MAN=
+MAN=
WARNS?= 3
DPADD+= ${LIBIPSEC}
diff --git a/tools/regression/pthread/cv_cancel1/cv_cancel1.c b/tools/regression/pthread/cv_cancel1/cv_cancel1.c
index cacad44..2ae94c5 100644
--- a/tools/regression/pthread/cv_cancel1/cv_cancel1.c
+++ b/tools/regression/pthread/cv_cancel1/cv_cancel1.c
@@ -28,6 +28,7 @@
*/
#include <pthread.h>
#include <stdio.h>
+#include <unistd.h>
#define NLOOPS 10
diff --git a/tools/regression/sbin/dhclient/Makefile b/tools/regression/sbin/dhclient/Makefile
index 7de3791..a9c876e 100644
--- a/tools/regression/sbin/dhclient/Makefile
+++ b/tools/regression/sbin/dhclient/Makefile
@@ -11,6 +11,7 @@ LDADD= -lutil
PROG= option-domain-search
+NO_MAN=
WARNS?= 2
.include <bsd.prog.mk>
diff --git a/tools/regression/usr.bin/xargs/regress.0.in b/tools/regression/usr.bin/xargs/regress.0.in
new file mode 100644
index 0000000..448ba53
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.0.in
Binary files differ
diff --git a/tools/regression/usr.bin/xargs/regress.0.out b/tools/regression/usr.bin/xargs/regress.0.out
new file mode 100644
index 0000000..2bc9725
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.0.out
@@ -0,0 +1,8 @@
+quick ' brown
+fox jumped
+over "the lazy
+dog
+quick brown fox
+jumped over the
+lazy dog
+
diff --git a/tools/regression/usr.bin/xargs/regress.0I.out b/tools/regression/usr.bin/xargs/regress.0I.out
new file mode 100644
index 0000000..16009c0
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.0I.out
@@ -0,0 +1,18 @@
+The quick ' brown quick ' brownquick ' brown quick ' brown
+The fox jumped
+over "the lazy fox jumped
+over "the lazyfox jumped
+over "the lazy fox jumped
+over "the lazy
+The
+The dog
+quick brown fox dog
+quick brown foxdog
+quick brown fox dog
+quick brown fox
+The jumped over the jumped over thejumped over the jumped over the
+The lazy dog
+ lazy dog
+lazy dog
+ lazy dog
+
diff --git a/tools/regression/usr.bin/xargs/regress.0J.out b/tools/regression/usr.bin/xargs/regress.0J.out
new file mode 100644
index 0000000..69c87f9
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.0J.out
@@ -0,0 +1,4 @@
+The quick ' brown fox jumped
+over "the lazy dog
+quick brown fox jumped over the lazy dog
+ again.
diff --git a/tools/regression/usr.bin/xargs/regress.0L.out b/tools/regression/usr.bin/xargs/regress.0L.out
new file mode 100644
index 0000000..2d13fcc
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.0L.out
@@ -0,0 +1,6 @@
+quick ' brown fox jumped
+over "the lazy
+dog
+quick brown fox
+jumped over the lazy dog
+
diff --git a/tools/regression/usr.bin/xargs/regress.n1.out b/tools/regression/usr.bin/xargs/regress.n1.out
new file mode 100644
index 0000000..77ef6c5
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.n1.out
@@ -0,0 +1,8 @@
+quick
+brown
+fox
+jumped
+over
+the
+lazy
+dog
diff --git a/tools/regression/usr.bin/xargs/regress.n2.out b/tools/regression/usr.bin/xargs/regress.n2.out
new file mode 100644
index 0000000..4fa3f55
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.n2.out
@@ -0,0 +1,4 @@
+quick brown
+fox jumped
+over the
+lazy dog
diff --git a/tools/regression/usr.bin/xargs/regress.n3.out b/tools/regression/usr.bin/xargs/regress.n3.out
new file mode 100644
index 0000000..21b2c1e
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.n3.out
@@ -0,0 +1,3 @@
+quick brown fox
+jumped over the
+lazy dog
diff --git a/tools/regression/usr.bin/xargs/regress.quotes.in b/tools/regression/usr.bin/xargs/regress.quotes.in
new file mode 100644
index 0000000..11388a0
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.quotes.in
@@ -0,0 +1,4 @@
+a 'b "c' \'d
+e\ f "g ' h"
+i\
+j
diff --git a/tools/regression/usr.bin/xargs/regress.quotes.out b/tools/regression/usr.bin/xargs/regress.quotes.out
new file mode 100644
index 0000000..f79ad41
--- /dev/null
+++ b/tools/regression/usr.bin/xargs/regress.quotes.out
@@ -0,0 +1,7 @@
+a
+b "c
+'d
+e f
+g ' h
+i
+j
diff --git a/tools/regression/usr.bin/xargs/regress.sh b/tools/regression/usr.bin/xargs/regress.sh
index 7c8db1d..4edeae4 100644
--- a/tools/regression/usr.bin/xargs/regress.sh
+++ b/tools/regression/usr.bin/xargs/regress.sh
@@ -1,6 +1,6 @@
# $FreeBSD$
-echo 1..5
+echo 1..13
REGRESSION_START($1)
@@ -9,5 +9,13 @@ REGRESSION_TEST(`I', `xargs -I% echo The % % % %% % % < regress.in')
REGRESSION_TEST(`J', `xargs -J% echo The % again. < regress.in')
REGRESSION_TEST(`L', `xargs -L3 echo < regress.in')
REGRESSION_TEST(`R', `xargs -I% -R1 echo The % % % %% % % < regress.in')
+REGRESSION_TEST(`n1', `xargs -n1 echo < regress.in')
+REGRESSION_TEST(`n2', `xargs -n2 echo < regress.in')
+REGRESSION_TEST(`n3', `xargs -n3 echo < regress.in')
+REGRESSION_TEST(`0', `xargs -0 -n1 echo < regress.0.in')
+REGRESSION_TEST(`0I', `xargs -0 -I% echo The % %% % < regress.0.in')
+REGRESSION_TEST(`0J', `xargs -0 -J% echo The % again. < regress.0.in')
+REGRESSION_TEST(`0L', `xargs -0 -L2 echo < regress.0.in')
+REGRESSION_TEST(`quotes', `xargs -n1 echo < regress.quotes.in')
REGRESSION_END()
diff --git a/tools/regression/usr.bin/yacc/grammar.y b/tools/regression/usr.bin/yacc/grammar.y
index 6755522..a2f1883 100644
--- a/tools/regression/usr.bin/yacc/grammar.y
+++ b/tools/regression/usr.bin/yacc/grammar.y
@@ -1027,7 +1027,7 @@ extern char *yytext;
extern FILE *yyin, *yyout;
static int curly; /* number of curly brace nesting levels */
-static int ly_count; /* number of occurances of %% */
+static int ly_count; /* number of occurrences of %% */
static int inc_depth; /* include nesting level */
static SymbolTable *included_files; /* files already included */
static int yy_start = 0; /* start state number */
diff --git a/tools/regression/usr.bin/yacc/regress.08.out b/tools/regression/usr.bin/yacc/regress.08.out
index 86e93e7..c86f19f 100644
--- a/tools/regression/usr.bin/yacc/regress.08.out
+++ b/tools/regression/usr.bin/yacc/regress.08.out
@@ -847,7 +847,7 @@ extern char *yytext;
extern FILE *yyin, *yyout;
static int curly; /* number of curly brace nesting levels */
-static int ly_count; /* number of occurances of %% */
+static int ly_count; /* number of occurrences of %% */
static int inc_depth; /* include nesting level */
static SymbolTable *included_files; /* files already included */
static int yy_start = 0; /* start state number */
diff --git a/tools/test/dtrace/Makefile b/tools/test/dtrace/Makefile
index 5cafb87..c9e9a20 100644
--- a/tools/test/dtrace/Makefile
+++ b/tools/test/dtrace/Makefile
@@ -159,7 +159,6 @@ NOTWORK+= \
${TESTSRCDIR}/tst/common/sched/tst.enqueue.d \
${TESTSRCDIR}/tst/common/sched/tst.oncpu.d \
${TESTSRCDIR}/tst/common/sched/tst.stackdepth.d \
- ${TESTSRCDIR}/tst/common/sdt/tst.sdtargs.d \
${TESTSRCDIR}/tst/common/usdt/argmap.d \
${TESTSRCDIR}/tst/common/usdt/args.d \
${TESTSRCDIR}/tst/common/usdt/forker.d \
diff --git a/tools/test/hwpmc/pmctest.py b/tools/test/hwpmc/pmctest.py
index fb4a977..9265dde 100755
--- a/tools/test/hwpmc/pmctest.py
+++ b/tools/test/hwpmc/pmctest.py
@@ -51,6 +51,10 @@ import sys
import subprocess
from subprocess import PIPE
+# Use input() for Python version 3
+if sys.version_info[0] == 3:
+ raw_input = input
+
# A list of strings that are not really counters, just
# name tags that are output by pmccontrol -L
notcounter = ["IAF", "IAP", "TSC", "UNC", "UCF", "UCP", "SOFT" ]
@@ -87,7 +91,7 @@ def main():
print(result)
if (options.wait == True):
try:
- value = input("next?")
+ value = raw_input("next?")
except EOFError:
sys.exit()
diff --git a/tools/test/posixshm/shm_test.c b/tools/test/posixshm/shm_test.c
index 3ab4732..0ec890a 100644
--- a/tools/test/posixshm/shm_test.c
+++ b/tools/test/posixshm/shm_test.c
@@ -21,7 +21,7 @@
* Signal handler which does nothing.
*/
static void
-ignoreit(int sig)
+ignoreit(int sig __unused)
{
;
}
@@ -29,13 +29,13 @@ ignoreit(int sig)
int
main(int argc, char **argv)
{
- char buf[1024], *cp;
- int desc, rv;
+ char buf[1024], *cp, c;
+ int error, desc, rv;
long scval;
sigset_t ss;
struct sigaction sa;
void *region;
- size_t psize;
+ size_t i, psize;
#ifndef _POSIX_SHARED_MEMORY_OBJECTS
printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n");
@@ -118,14 +118,29 @@ main(int argc, char **argv)
sigemptyset(&ss);
sigsuspend(&ss);
- for (cp = region; cp < (char *)region + psize; cp++)
+ for (cp = region; cp < (char *)region + psize; cp++) {
if (*cp != '\151')
_exit(1);
+ }
+ if (lseek(desc, 0, SEEK_SET) == -1)
+ _exit(1);
+ for (i = 0; i < psize; i++) {
+ error = read(desc, &c, 1);
+ if (c != '\151')
+ _exit(1);
+ }
_exit(0);
} else {
int status;
- memset(region, '\151', psize);
+ memset(region, '\151', psize - 2);
+ error = pwrite(desc, region, 2, psize - 2);
+ if (error != 2) {
+ if (error >= 0)
+ errx(1, "short write %d", error);
+ else
+ err(1, "shmfd write");
+ }
kill(rv, SIGUSR1);
waitpid(rv, &status, 0);
diff --git a/tools/tools/README b/tools/tools/README
index 1260683..ef05ee0 100644
--- a/tools/tools/README
+++ b/tools/tools/README
@@ -18,6 +18,7 @@ cxgbetool A tool for the cxgbe(4) driver.
cxgbtool A tool for the cxgb(4) driver.
diffburst OBSOLETE: equivalent functionality is available via split -p.
For example: "split -p ^diff < patchfile". See split(1).
+drm Tools specific to the DRM/KMS device drivers.
editing Editor modes and the like to help editing FreeBSD code.
epfe Extract printing filter examples from printing.sgml.
ether_reflect An Ethernet packet reflector for low level testing.
diff --git a/tools/tools/ath/Makefile b/tools/tools/ath/Makefile
index c4c81ba..99dc588 100644
--- a/tools/tools/ath/Makefile
+++ b/tools/tools/ath/Makefile
@@ -2,7 +2,7 @@
SUBDIR= arcode athdebug athdecode athkey athpoke athprom athrd athregs
SUBDIR+= athstats ath_prom_read athradar athaggrstats
-SUBDIR+= ath_ee_v14_print ath_ee_v4k_print ath_ee_9287_print
+SUBDIR+= ath_ee_v14_print ath_ee_v4k_print ath_ee_9287_print ath_ee_9300_print
SUBDIR+= athsurvey athratestats athspectral
.include <bsd.subdir.mk>
diff --git a/tools/tools/ath/Makefile.inc b/tools/tools/ath/Makefile.inc
index 901844e..85953f2 100644
--- a/tools/tools/ath/Makefile.inc
+++ b/tools/tools/ath/Makefile.inc
@@ -11,4 +11,5 @@ CFLAGS+=-I${.CURDIR}/../common
CFLAGS+=-I${.CURDIR}/../../../../sys
CFLAGS+=-I${.CURDIR}/../../../../sys/dev/ath
CFLAGS+=-I${.CURDIR}/../../../../sys/dev/ath/ath_hal
+CFLAGS+=-I${.CURDIR}/../../../../sys/contrib/dev/ath/ath_hal
CFLAGS+=-I${.OBJDIR}
diff --git a/tools/tools/ath/ath_ee_9300_print/Makefile b/tools/tools/ath/ath_ee_9300_print/Makefile
new file mode 100644
index 0000000..8f37eef
--- /dev/null
+++ b/tools/tools/ath/ath_ee_9300_print/Makefile
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal
+
+PROG= ath_ee_9300_print
+NOMAN= yes
+NO_MAN= yes
+SRCS= main.c
+SRCS+= opt_ah.h
+CLEANFILES+= opt_ah.h
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/ath_ee_9300_print/main.c b/tools/tools/ath/ath_ee_9300_print/main.c
new file mode 100644
index 0000000..acf646e
--- /dev/null
+++ b/tools/tools/ath/ath_ee_9300_print/main.c
@@ -0,0 +1,229 @@
+
+/*
+ * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+
+struct ath_hal;
+
+#include "ar9300/ar9300eep.h"
+
+static void
+eeprom_9300_hdr_print(const uint16_t *buf)
+{
+ const ar9300_eeprom_t *ee = (ar9300_eeprom_t *) buf;
+
+ printf("| Version: %d, Template: %d, MAC: %02x:%02x:%02x:%02x:%02x:%02x |\n",
+ ee->eeprom_version,
+ ee->template_version,
+ ee->mac_addr[0],
+ ee->mac_addr[1],
+ ee->mac_addr[2],
+ ee->mac_addr[3],
+ ee->mac_addr[4],
+ ee->mac_addr[5]);
+}
+
+static void
+eeprom_9300_base_print(const uint16_t *buf)
+{
+ const ar9300_eeprom_t *ee = (ar9300_eeprom_t *) buf;
+ const OSPREY_BASE_EEP_HEADER *ee_base = &ee->base_eep_header;
+
+ printf("| RegDomain: 0x%02x 0x%02x TxRxMask: 0x%02x OpFlags: 0x%02x OpMisc: 0x%02x |\n",
+ ee_base->reg_dmn[0],
+ ee_base->reg_dmn[1],
+ ee_base->txrx_mask,
+ ee_base->op_cap_flags.op_flags,
+ ee_base->op_cap_flags.eepMisc);
+
+ printf("| RfSilent: 0x%02x BtOptions: 0x%02x DeviceCap: 0x%02x DeviceType: 0x%02x |\n",
+ ee_base->rf_silent,
+ ee_base->blue_tooth_options,
+ ee_base->device_cap,
+ ee_base->device_type);
+
+ printf("| pwrTableOffset: %d dB, feature_enable: 0x%02x MiscConfig: 0x%02x |\n",
+ ee_base->pwrTableOffset,
+ ee_base->feature_enable,
+ ee_base->misc_configuration);
+
+ printf("| EepromWriteGpio: %d, WlanDisableGpio: %d, WlanLedGpio: %d RxBandSelectGpio: %d |\n",
+ ee_base->eeprom_write_enable_gpio,
+ ee_base->wlan_disable_gpio,
+ ee_base->wlan_led_gpio,
+ ee_base->rx_band_select_gpio);
+
+ printf("| TxRxGain: %d, SwReg: %d |\n",
+ ee_base->txrxgain,
+ ee_base->swreg);
+}
+
+static void
+eeprom_9300_modal_print(const OSPREY_MODAL_EEP_HEADER *m)
+{
+ int i;
+
+ printf("| AntCtrl: 0x%08x AntCtrl2: 0x%08x |\n",
+ m->ant_ctrl_common,
+ m->ant_ctrl_common2);
+
+ for (i = 0; i < OSPREY_MAX_CHAINS; i++) {
+ printf("| Ch %d: AntCtrl: 0x%08x Atten1: %d, atten1_margin: %d, NfThresh: %d |\n",
+ i,
+ m->ant_ctrl_chain[i],
+ m->xatten1_db[i],
+ m->xatten1_margin[i],
+ m->noise_floor_thresh_ch[i]);
+ }
+
+ printf("| Spur: ");
+ for (i = 0; i < OSPREY_EEPROM_MODAL_SPURS; i++) {
+ printf("(%d: %d) ", i, m->spur_chans[i]);
+ }
+ printf("|\n");
+
+ printf("| TempSlope: %d, VoltSlope: %d, QuickDrop: %d, XpaBiasLvl %d |\n",
+ m->temp_slope,
+ m->voltSlope,
+ m->quick_drop,
+ m->xpa_bias_lvl);
+
+ printf("| txFrameToDataStart: %d, TxFrameToPaOn: %d, TxEndToXpaOff: %d, TxEndToRxOn: %d, TxFrameToXpaOn: %d |\n",
+ m->tx_frame_to_data_start,
+ m->tx_frame_to_pa_on,
+ m->tx_end_to_xpa_off,
+ m->txEndToRxOn,
+ m->tx_frame_to_xpa_on);
+
+ printf("| txClip: %d, AntGain: %d, SwitchSettling: %d, adcDesiredSize: %d |\n",
+ m->txClip,
+ m->antenna_gain,
+ m->switchSettling,
+ m->adcDesiredSize);
+
+ printf("| Thresh62: %d, PaprdMaskHt20: 0x%08x, PaPrdMaskHt40: 0x%08x |\n",
+ m->thresh62,
+ m->paprd_rate_mask_ht20,
+ m->paprd_rate_mask_ht40);
+
+ printf("| SwitchComSpdt: %02x, XlnaBiasStrength: %d, RfGainCap: %d, TxGainCap: %x\n",
+ m->switchcomspdt,
+ m->xLNA_bias_strength,
+ m->rf_gain_cap,
+ m->tx_gain_cap);
+
+#if 0
+ u_int8_t reserved[MAX_MODAL_RESERVED];
+ u_int16_t switchcomspdt;
+ u_int8_t xLNA_bias_strength; // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
+ u_int8_t rf_gain_cap;
+ u_int8_t tx_gain_cap; // bit0:4 txgain cap, txgain index for max_txgain + 20 (10dBm higher than max txgain)
+ u_int8_t futureModal[MAX_MODAL_FUTURE];
+ // last 12 bytes stolen and moved to newly created base extension structure
+#endif
+}
+
+static void
+load_eeprom_dump(const char *file, uint16_t *buf)
+{
+ unsigned int r[8];
+ FILE *fp;
+ char b[1024];
+ int i;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ err(1, "fopen");
+
+ while (!feof(fp)) {
+ if (fgets(b, 1024, fp) == NULL)
+ break;
+ if (feof(fp))
+ break;
+ if (strlen(b) > 0)
+ b[strlen(b)-1] = '\0';
+ if (strlen(b) == 0)
+ break;
+ sscanf(b, "%x: %x %x %x %x %x %x %x %x\n",
+ &i, &r[0], &r[1], &r[2], &r[3], &r[4],
+ &r[5], &r[6], &r[7]);
+ buf[i++] = r[0];
+ buf[i++] = r[1];
+ buf[i++] = r[2];
+ buf[i++] = r[3];
+ buf[i++] = r[4];
+ buf[i++] = r[5];
+ buf[i++] = r[6];
+ buf[i++] = r[7];
+ }
+ fclose(fp);
+}
+
+void
+usage(char *argv[])
+{
+ printf("Usage: %s <eeprom dump file>\n", argv[0]);
+ printf("\n");
+ printf(" The eeprom dump file is a text hexdump of an EEPROM.\n");
+ printf(" The lines must be formatted as follows:\n");
+ printf(" 0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n");
+ printf(" where each line must have exactly eight data bytes.\n");
+ exit(127);
+}
+
+int
+main(int argc, char *argv[])
+{
+ uint16_t *eep = NULL;
+ const ar9300_eeprom_t *ee;
+
+ eep = calloc(4096, sizeof(int16_t));
+
+ if (argc < 2)
+ usage(argv);
+
+ load_eeprom_dump(argv[1], eep);
+ ee = (ar9300_eeprom_t *) eep;
+
+ eeprom_9300_hdr_print(eep);
+ eeprom_9300_base_print(eep);
+
+ printf("\n2GHz modal:\n");
+ eeprom_9300_modal_print(&ee->modal_header_2g);
+
+ printf("\n5GHz modal:\n");
+ eeprom_9300_modal_print(&ee->modal_header_5g);
+
+ free(eep);
+ exit(0);
+}
diff --git a/tools/tools/ath/athalq/Makefile b/tools/tools/ath/athalq/Makefile
index 60c9bf8..a7eb394 100644
--- a/tools/tools/ath/athalq/Makefile
+++ b/tools/tools/ath/athalq/Makefile
@@ -3,8 +3,10 @@
PROG= athalq
NOMAN= yes
+CFLAGS+= -I../../../../sys/contrib
+
SRCS= main.c ar5210_ds.c ar5211_ds.c ar5212_ds.c ar5416_ds.c tdma.c
-# SRCS+= ar9300_ds.c
+SRCS+= ar9300_ds.c
.include <../Makefile.inc>
diff --git a/tools/tools/ath/athalq/ar9300_ds.c b/tools/tools/ath/athalq/ar9300_ds.c
index 5ab55ca..04455d3 100644
--- a/tools/tools/ath/athalq/ar9300_ds.c
+++ b/tools/tools/ath/athalq/ar9300_ds.c
@@ -29,7 +29,7 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <dev/ath/if_ath_alq.h>
-#include <dev/ath/ath_hal/ar9003/ar9300desc.h>
+#include <dev/ath/ath_hal/ar9300/ar9300desc.h>
#include "ar9300_ds.h"
diff --git a/tools/tools/ath/athalq/main.c b/tools/tools/ath/athalq/main.c
index 1d5447d..c5ba9ef 100644
--- a/tools/tools/ath/athalq/main.c
+++ b/tools/tools/ath/athalq/main.c
@@ -30,7 +30,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ath/if_ath_alq.h>
-#if 0
+#if 1
#include "ar9300_ds.h"
#endif
#include "ar5210_ds.h"
@@ -75,6 +75,36 @@ ath_alq_print_intr_status(struct if_ath_alq_payload *a)
be32toh(is.intr_status));
}
+static void
+ath_alq_print_beacon_miss(struct if_ath_alq_payload *a)
+{
+
+ printf("[%u.%06u] [%llu] BMISS\n",
+ (unsigned int) be32toh(a->hdr.tstamp_sec),
+ (unsigned int) be32toh(a->hdr.tstamp_usec),
+ (unsigned long long) be64toh(a->hdr.threadid));
+}
+
+static void
+ath_alq_print_beacon_stuck(struct if_ath_alq_payload *a)
+{
+
+ printf("[%u.%06u] [%llu] BSTUCK\n",
+ (unsigned int) be32toh(a->hdr.tstamp_sec),
+ (unsigned int) be32toh(a->hdr.tstamp_usec),
+ (unsigned long long) be64toh(a->hdr.threadid));
+}
+
+static void
+ath_alq_print_beacon_resume(struct if_ath_alq_payload *a)
+{
+
+ printf("[%u.%06u] [%llu] BRESUME\n",
+ (unsigned int) be32toh(a->hdr.tstamp_sec),
+ (unsigned int) be32toh(a->hdr.tstamp_usec),
+ (unsigned long long) be64toh(a->hdr.threadid));
+}
+
int
main(int argc, const char *argv[])
{
@@ -147,6 +177,15 @@ main(int argc, const char *argv[])
case ATH_ALQ_INTR_STATUS:
ath_alq_print_intr_status(a);
break;
+ case ATH_ALQ_MISSED_BEACON:
+ ath_alq_print_beacon_miss(a);
+ break;
+ case ATH_ALQ_STUCK_BEACON:
+ ath_alq_print_beacon_stuck(a);
+ break;
+ case ATH_ALQ_RESUME_BEACON:
+ ath_alq_print_beacon_resume(a);
+ break;
default:
if (be32toh(hdr.sc_hal_magic) == AR5210_MAGIC)
ar5210_alq_payload(a);
@@ -156,7 +195,7 @@ main(int argc, const char *argv[])
ar5212_alq_payload(a);
else if (be32toh(hdr.sc_hal_magic) == AR5416_MAGIC)
ar5416_alq_payload(a);
-#if 0
+#if 1
else if (be32toh(hdr.sc_hal_magic) == AR9300_MAGIC)
ar9300_alq_payload(a);
#endif
diff --git a/tools/tools/ath/athalq/txdiff.pl b/tools/tools/ath/athalq/txdiff.pl
new file mode 100755
index 0000000..dff9405
--- /dev/null
+++ b/tools/tools/ath/athalq/txdiff.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+# $FreeBSD$
+
+# [1360537229.753890] [100494] TXD
+# [1360537229.754292] [100494] TXSTATUS: TxDone=1, TS=0x5ccfa5c7
+
+my ($tv_sec) = 0;
+my ($tv_usec) = 0;
+
+sub tvdiff($$$$) {
+ my ($tv1_sec, $tv1_usec, $tv2_sec, $tv2_usec) = @_;
+
+ if ($tv2_usec < $tv1_usec) {
+ $tv2_usec += 1000000;
+ $tv1_sec = $tv1_sec + 1;
+ }
+
+ return ($tv2_sec - $tv1_sec) * 1000000 + ($tv2_usec - $tv1_usec);
+}
+
+while (<>) {
+ chomp;
+ m/^\[(.*?)\.(.*?)\]/ || next;
+ printf "%d\t| %s\n", tvdiff($tv_sec, $tv_usec, $1, $2), $_;
+# if (tvdiff($tv_sec, $tv_usec, $1, $2) > 500) {
+# printf "%d\t| %s\n", tvdiff($tv_sec, $tv_usec, $1, $2), $_;
+# }
+ $tv_sec = $1;
+ $tv_usec = $2;
+}
+
diff --git a/tools/tools/ath/athspectral/athspectral.c b/tools/tools/ath/athspectral/athspectral.c
index 7bdfa2b..1ec9085 100644
--- a/tools/tools/ath/athspectral/athspectral.c
+++ b/tools/tools/ath/athspectral/athspectral.c
@@ -67,7 +67,7 @@ spectral_opendev(struct spectralhandler *spectral, const char *devid)
spectral->atd.ad_out_data = (caddr_t) &revs;
spectral->atd.ad_out_size = sizeof(revs);
if (ioctl(spectral->s, SIOCGATHDIAG, &spectral->atd) < 0) {
- warn(spectral->atd.ad_name);
+ warn("%s", spectral->atd.ad_name);
return 0;
}
spectral->ah_devid = revs.ah_devid;
@@ -116,7 +116,7 @@ spectralset(struct spectralhandler *spectral, int op, u_int32_t param)
spectral->atd.ad_in_data = (caddr_t) &pe;
spectral->atd.ad_in_size = sizeof(HAL_SPECTRAL_PARAM);
if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0)
- err(1, spectral->atd.ad_name);
+ err(1, "%s", spectral->atd.ad_name);
}
static void
@@ -133,7 +133,7 @@ spectral_get(struct spectralhandler *spectral)
spectral->atd.ad_out_size = sizeof(pe);
if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0)
- err(1, spectral->atd.ad_name);
+ err(1, "%s", spectral->atd.ad_name);
printf("Spectral parameters (raw):\n");
printf(" ss_enabled: %d\n", pe.ss_enabled);
@@ -163,7 +163,7 @@ spectral_start(struct spectralhandler *spectral)
spectral->atd.ad_out_size = sizeof(pe);
if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0)
- err(1, spectral->atd.ad_name);
+ err(1, "%s", spectral->atd.ad_name);
}
static void
@@ -184,7 +184,7 @@ spectral_stop(struct spectralhandler *spectral)
spectral->atd.ad_out_size = sizeof(pe);
if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0)
- err(1, spectral->atd.ad_name);
+ err(1, "%s", spectral->atd.ad_name);
}
static void
@@ -207,7 +207,7 @@ spectral_enable_at_reset(struct spectralhandler *spectral, int val)
printf("%s: val=%d\n", __func__, v);
if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0)
- err(1, spectral->atd.ad_name);
+ err(1, "%s", spectral->atd.ad_name);
}
static int
diff --git a/tools/tools/ath/athstats/athstats.c b/tools/tools/ath/athstats/athstats.c
index 2cffe34..f3f18f4 100644
--- a/tools/tools/ath/athstats/athstats.c
+++ b/tools/tools/ath/athstats/athstats.c
@@ -262,7 +262,9 @@ static const struct fmt athstats[] = {
{ 10, "rxdescbusy", "rxdescbusy", "Decryption engine busy" },
#define S_RX_HI_CHAIN AFTER(S_RX_DECRYPT_BUSY_ERR)
{ 4, "rxhi", "rxhi", "Frames received with RX chain in high power mode" },
-#define S_TX_HTPROTECT AFTER(S_RX_HI_CHAIN)
+#define S_RX_STBC AFTER(S_RX_HI_CHAIN)
+ { 6, "rxstbc", "rxstbc", "Frames received w/ STBC encoding" },
+#define S_TX_HTPROTECT AFTER(S_RX_STBC)
{ 7, "txhtprot", "txhtprot", "Frames transmitted with HT Protection" },
#define S_RX_QEND AFTER(S_TX_HTPROTECT)
{ 7, "rxquend", "rxquend", "Hit end of RX descriptor queue" },
@@ -420,7 +422,6 @@ static const struct fmt athstats[] = {
{ 4, "signal", "sig", "avg recv signal (dBm)" },
#define S_BMISSCOUNT AFTER(S_RX_SIGNAL)
{ 8, "bmisscount", "bmisscnt", "beacon miss count" },
-
};
#define S_PHY_MIN S_RX_PHY_UNDERRUN
#define S_PHY_MAX S_RX_PHY_CCK_RESTART
@@ -773,6 +774,7 @@ ath_get_curstat(struct statfoo *sf, int s, char b[], size_t bs)
case S_RX_POST_CRC_ERR: STAT(rx_post_crc_err);
case S_RX_DECRYPT_BUSY_ERR: STAT(rx_decrypt_busy_err);
case S_RX_HI_CHAIN: STAT(rx_hi_rx_chain);
+ case S_RX_STBC: STAT(rx_stbc);
case S_TX_HTPROTECT: STAT(tx_htprotect);
case S_RX_QEND: STAT(rx_hitqueueend);
case S_TX_TIMEOUT: STAT(tx_timeout);
@@ -1015,6 +1017,7 @@ ath_get_totstat(struct statfoo *sf, int s, char b[], size_t bs)
case S_RX_POST_CRC_ERR: STAT(rx_post_crc_err);
case S_RX_DECRYPT_BUSY_ERR: STAT(rx_decrypt_busy_err);
case S_RX_HI_CHAIN: STAT(rx_hi_rx_chain);
+ case S_RX_STBC: STAT(rx_stbc);
case S_TX_HTPROTECT: STAT(tx_htprotect);
case S_RX_QEND: STAT(rx_hitqueueend);
case S_TX_TIMEOUT: STAT(tx_timeout);
diff --git a/tools/tools/bootparttest/bootparttest.c b/tools/tools/bootparttest/bootparttest.c
index 2b93ee0..f0fb8a9 100644
--- a/tools/tools/bootparttest/bootparttest.c
+++ b/tools/tools/bootparttest/bootparttest.c
@@ -54,7 +54,7 @@ diskread(void *arg, void *buf, size_t blocks, off_t offset)
struct disk *dp;
dp = (struct disk *)arg;
- printf("%s: read %d blocks from the offset %jd [+%jd]\n", dp->name,
+ printf("%s: read %lu blocks from the offset %jd [+%jd]\n", dp->name,
blocks, offset, dp->offset);
if (offset >= dp->mediasize / dp->sectorsize)
return (-1);
diff --git a/tools/tools/bus_autoconf/bus_load_file.c b/tools/tools/bus_autoconf/bus_load_file.c
index 527e5bc..8d82ac3 100644
--- a/tools/tools/bus_autoconf/bus_load_file.c
+++ b/tools/tools/bus_autoconf/bus_load_file.c
@@ -39,7 +39,7 @@ void
load_file(const char *fname, uint8_t **pptr, uint32_t *plen)
{
uint8_t *ptr;
- uint32_t len;
+ ssize_t len;
off_t off;
int f;
diff --git a/tools/tools/crypto/ipsecstats.c b/tools/tools/crypto/ipsecstats.c
index 6ecc1f4..9f98ea8 100644
--- a/tools/tools/crypto/ipsecstats.c
+++ b/tools/tools/crypto/ipsecstats.c
@@ -25,11 +25,12 @@
*
* $FreeBSD$
*/
-#include <stdio.h>
#include <sys/types.h>
#include <netipsec/ipsec.h>
#include <netipsec/ah_var.h>
#include <netipsec/esp_var.h>
+#include <stdint.h>
+#include <stdio.h>
struct alg {
int a;
@@ -82,7 +83,7 @@ algname(int a, const struct alg algs[], int nalgs)
int
main(int argc, char *argv[])
{
-#define STAT(x,fmt) if (x) printf(fmt "\n", x)
+#define STAT(x,fmt) if (x) printf(fmt "\n", (uintmax_t)x)
struct ipsecstat ips;
struct ahstat ahs;
struct espstat esps;
@@ -99,8 +100,7 @@ main(int argc, char *argv[])
if (sysctlbyname("net.inet.esp.stats", &esps, &slen, NULL, NULL) < 0)
err(1, "net.inet.esp.stats");
-#define AHSTAT(x,fmt) if (x) printf("ah " fmt ": %u\n", x)
-#define AHSTAT64(x,fmt) if (x) printf("ah " fmt ": %llu\n", x)
+#define AHSTAT(x,fmt) if (x) printf("ah " fmt ": %ju\n", (uintmax_t)x)
AHSTAT(ahs.ahs_input, "input packets processed");
AHSTAT(ahs.ahs_output, "output packets processed");
AHSTAT(ahs.ahs_hdrops, "headers too short");
@@ -120,17 +120,15 @@ main(int argc, char *argv[])
AHSTAT(ahs.ahs_tunnel, "tunnel sanity check failures");
for (i = 0; i < AH_ALG_MAX; i++)
if (ahs.ahs_hist[i])
- printf("ah packets with %s: %u\n"
+ printf("ah packets with %s: %ju\n"
, algname(i, aalgs, N(aalgs))
- , ahs.ahs_hist[i]
+ , (uintmax_t)ahs.ahs_hist[i]
);
- AHSTAT64(ahs.ahs_ibytes, "bytes received");
- AHSTAT64(ahs.ahs_obytes, "bytes transmitted");
-#undef AHSTAT64
+ AHSTAT(ahs.ahs_ibytes, "bytes received");
+ AHSTAT(ahs.ahs_obytes, "bytes transmitted");
#undef AHSTAT
-#define ESPSTAT(x,fmt) if (x) printf("esp " fmt ": %u\n", x)
-#define ESPSTAT64(x,fmt) if (x) printf("esp " fmt ": %llu\n", x)
+#define ESPSTAT(x,fmt) if (x) printf("esp " fmt ": %ju\n", (uintmax_t)x)
ESPSTAT(esps.esps_input, "input packets processed");
ESPSTAT(esps.esps_output, "output packets processed");
ESPSTAT(esps.esps_hdrops, "headers too short");
@@ -151,29 +149,30 @@ main(int argc, char *argv[])
ESPSTAT(esps.esps_tunnel, "tunnel sanity check failures");
for (i = 0; i < ESP_ALG_MAX; i++)
if (esps.esps_hist[i])
- printf("esp packets with %s: %u\n"
+ printf("esp packets with %s: %ju\n"
, algname(i, espalgs, N(espalgs))
- , esps.esps_hist[i]
+ , (uintmax_t)esps.esps_hist[i]
);
- ESPSTAT64(esps.esps_ibytes, "bytes received");
- ESPSTAT64(esps.esps_obytes, "bytes transmitted");
-#undef ESPSTAT64
+ ESPSTAT(esps.esps_ibytes, "bytes received");
+ ESPSTAT(esps.esps_obytes, "bytes transmitted");
#undef ESPSTAT
printf("\n");
if (ips.ips_in_polvio+ips.ips_out_polvio)
- printf("policy violations: input %u output %u\n",
- ips.ips_in_polvio, ips.ips_out_polvio);
- STAT(ips.ips_out_nosa, "no SA found %u (output)");
- STAT(ips.ips_out_nomem, "no memory available %u (output)");
- STAT(ips.ips_out_noroute, "no route available %u (output)");
- STAT(ips.ips_out_inval, "generic error %u (output)");
- STAT(ips.ips_out_bundlesa, "bundled SA processed %u (output)");
- printf("m_clone processing: %u mbufs + %u clusters coalesced\n",
- ips.ips_mbcoalesced, ips.ips_clcoalesced);
- printf("m_clone processing: %u clusters copied\n", ips.ips_clcopied);
- printf("m_makespace: %u mbufs inserted\n", ips.ips_mbinserted);
- printf("header position [front/middle/end]: %u/%u/%u\n",
- ips.ips_input_front, ips.ips_input_middle, ips.ips_input_end);
+ printf("policy violations: input %ju output %ju\n",
+ (uintmax_t)ips.ips_in_polvio,
+ (uintmax_t)ips.ips_out_polvio);
+ STAT(ips.ips_out_nosa, "no SA found %ju (output)");
+ STAT(ips.ips_out_nomem, "no memory available %ju (output)");
+ STAT(ips.ips_out_noroute, "no route available %ju (output)");
+ STAT(ips.ips_out_inval, "generic error %ju (output)");
+ STAT(ips.ips_out_bundlesa, "bundled SA processed %ju (output)");
+ printf("m_clone processing: %ju mbufs + %ju clusters coalesced\n",
+ (uintmax_t)ips.ips_mbcoalesced, (uintmax_t)ips.ips_clcoalesced);
+ STAT(ips.ips_clcopied, "m_clone processing: %ju clusters copied\n");
+ STAT(ips.ips_mbinserted, "m_makespace: %ju mbufs inserted\n");
+ printf("header position [front/middle/end]: %ju/%ju/%ju\n",
+ (uintmax_t)ips.ips_input_front, (uintmax_t)ips.ips_input_middle,
+ (uintmax_t)ips.ips_input_end);
return 0;
}
diff --git a/tools/tools/cxgbetool/cxgbetool.c b/tools/tools/cxgbetool/cxgbetool.c
index 6b90b12..e5704e7 100644
--- a/tools/tools/cxgbetool/cxgbetool.c
+++ b/tools/tools/cxgbetool/cxgbetool.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#define max(x, y) ((x) > (y) ? (x) : (y))
static const char *progname, *nexus;
+static int chip_id; /* 4 for T4, 5 for T5 */
struct reg_info {
const char *name;
@@ -98,6 +99,9 @@ usage(FILE *fp)
"\tregdump [<module>] ... dump registers\n"
"\tstdio interactive mode\n"
"\ttcb <tid> read TCB\n"
+ "\ttracer <idx> tx<n>|rx<n> set and enable a tracer)\n"
+ "\ttracer <idx> disable|enable disable or enable a tracer\n"
+ "\ttracer list list all tracers\n"
);
}
@@ -122,6 +126,7 @@ real_doit(unsigned long cmd, void *data, const char *cmdstr)
rc = errno;
return (rc);
}
+ chip_id = nexus[1] - '0';
}
rc = ioctl(fd, cmd, data);
@@ -965,6 +970,7 @@ set_filter(uint32_t idx, int argc, const char *argv[])
};
bzero(&t, sizeof (t));
t.idx = idx;
+ t.fs.hitcnts = 1;
for (start_arg = 0; start_arg + 2 <= argc; start_arg += 2) {
const char **args = &argv[start_arg];
@@ -1361,6 +1367,15 @@ show_sge_context(const struct t4_sge_context *p)
FIELD("CngChMap:", 0, 3),
{ NULL }
};
+ static struct field_desc t5_conm[] = {
+ FIELD1("CngMPSEnable:", 21),
+ FIELD("CngTPMode:", 19, 20),
+ FIELD1("CngDBPHdr:", 18),
+ FIELD1("CngDBPData:", 17),
+ FIELD1("CngIMSG:", 16),
+ FIELD("CngChMap:", 0, 15),
+ { NULL }
+ };
if (p->mem_id == SGE_CONTEXT_EGRESS)
show_struct(p->data, 6, (p->data[0] & 2) ? fl : egress);
@@ -1369,7 +1384,7 @@ show_sge_context(const struct t4_sge_context *p)
else if (p->mem_id == SGE_CONTEXT_INGRESS)
show_struct(p->data, 5, ingress);
else if (p->mem_id == SGE_CONTEXT_CNM)
- show_struct(p->data, 1, conm);
+ show_struct(p->data, 1, chip_id == 5 ? t5_conm : conm);
}
#undef FIELD
@@ -1657,6 +1672,203 @@ clearstats(int argc, const char *argv[])
}
static int
+show_tracers(void)
+{
+ struct t4_tracer t;
+ char *s;
+ int rc, port_idx, i;
+ long long val;
+
+ /* Magic values: MPS_TRC_CFG = 0x9800. MPS_TRC_CFG[1:1] = TrcEn */
+ rc = read_reg(0x9800, 4, &val);
+ if (rc != 0)
+ return (rc);
+ printf("tracing is %s\n", val & 2 ? "ENABLED" : "DISABLED");
+
+ t.idx = 0;
+ for (t.idx = 0; ; t.idx++) {
+ rc = doit(CHELSIO_T4_GET_TRACER, &t);
+ if (rc != 0 || t.idx == 0xff)
+ break;
+
+ if (t.tp.port < 4) {
+ s = "Rx";
+ port_idx = t.tp.port;
+ } else if (t.tp.port < 8) {
+ s = "Tx";
+ port_idx = t.tp.port - 4;
+ } else if (t.tp.port < 12) {
+ s = "loopback";
+ port_idx = t.tp.port - 8;
+ } else if (t.tp.port < 16) {
+ s = "MPS Rx";
+ port_idx = t.tp.port - 12;
+ } else if (t.tp.port < 20) {
+ s = "MPS Tx";
+ port_idx = t.tp.port - 16;
+ } else {
+ s = "unknown";
+ port_idx = t.tp.port;
+ }
+
+ printf("\ntracer %u (currently %s) captures ", t.idx,
+ t.enabled ? "ENABLED" : "DISABLED");
+ if (t.tp.port < 8)
+ printf("port %u %s, ", port_idx, s);
+ else
+ printf("%s %u, ", s, port_idx);
+ printf("snap length: %u, min length: %u\n", t.tp.snap_len,
+ t.tp.min_len);
+ printf("packets captured %smatch filter\n",
+ t.tp.invert ? "do not " : "");
+ if (t.tp.skip_ofst) {
+ printf("filter pattern: ");
+ for (i = 0; i < t.tp.skip_ofst * 2; i += 2)
+ printf("%08x%08x", t.tp.data[i],
+ t.tp.data[i + 1]);
+ printf("/");
+ for (i = 0; i < t.tp.skip_ofst * 2; i += 2)
+ printf("%08x%08x", t.tp.mask[i],
+ t.tp.mask[i + 1]);
+ printf("@0\n");
+ }
+ printf("filter pattern: ");
+ for (i = t.tp.skip_ofst * 2; i < T4_TRACE_LEN / 4; i += 2)
+ printf("%08x%08x", t.tp.data[i], t.tp.data[i + 1]);
+ printf("/");
+ for (i = t.tp.skip_ofst * 2; i < T4_TRACE_LEN / 4; i += 2)
+ printf("%08x%08x", t.tp.mask[i], t.tp.mask[i + 1]);
+ printf("@%u\n", (t.tp.skip_ofst + t.tp.skip_len) * 8);
+ }
+
+ return (rc);
+}
+
+static int
+tracer_onoff(uint8_t idx, int enabled)
+{
+ struct t4_tracer t;
+
+ t.idx = idx;
+ t.enabled = enabled;
+ t.valid = 0;
+
+ return doit(CHELSIO_T4_SET_TRACER, &t);
+}
+
+static void
+create_tracing_ifnet()
+{
+ char *cmd[] = {
+ "/sbin/ifconfig", __DECONST(char *, nexus), "create", NULL
+ };
+ char *env[] = {NULL};
+
+ if (vfork() == 0) {
+ close(STDERR_FILENO);
+ execve(cmd[0], cmd, env);
+ _exit(0);
+ }
+}
+
+/*
+ * XXX: Allow user to specify snaplen, minlen, and pattern (including inverted
+ * matching). Right now this is a quick-n-dirty implementation that traces the
+ * first 128B of all tx or rx on a port
+ */
+static int
+set_tracer(uint8_t idx, int argc, const char *argv[])
+{
+ struct t4_tracer t;
+ int len, port;
+
+ bzero(&t, sizeof (t));
+ t.idx = idx;
+ t.enabled = 1;
+ t.valid = 1;
+
+ if (argc != 1) {
+ warnx("must specify tx<n> or rx<n>.");
+ return (EINVAL);
+ }
+
+ len = strlen(argv[0]);
+ if (len != 3) {
+ warnx("argument must be 3 characters (tx<n> or rx<n>)");
+ return (EINVAL);
+ }
+
+ if (strncmp(argv[0], "tx", 2) == 0) {
+ port = argv[0][2] - '0';
+ if (port < 0 || port > 3) {
+ warnx("'%c' in %s is invalid", argv[0][2], argv[0]);
+ return (EINVAL);
+ }
+ port += 4;
+ } else if (strncmp(argv[0], "rx", 2) == 0) {
+ port = argv[0][2] - '0';
+ if (port < 0 || port > 3) {
+ warnx("'%c' in %s is invalid", argv[0][2], argv[0]);
+ return (EINVAL);
+ }
+ } else {
+ warnx("argument '%s' isn't tx<n> or rx<n>", argv[0]);
+ return (EINVAL);
+ }
+
+ t.tp.snap_len = 128;
+ t.tp.min_len = 0;
+ t.tp.skip_ofst = 0;
+ t.tp.skip_len = 0;
+ t.tp.invert = 0;
+ t.tp.port = port;
+
+ create_tracing_ifnet();
+ return doit(CHELSIO_T4_SET_TRACER, &t);
+}
+
+static int
+tracer_cmd(int argc, const char *argv[])
+{
+ long long val;
+ uint8_t idx;
+ char *s;
+
+ if (argc == 0) {
+ warnx("tracer: no arguments.");
+ return (EINVAL);
+ };
+
+ /* list */
+ if (strcmp(argv[0], "list") == 0) {
+ if (argc != 1)
+ warnx("trailing arguments after \"list\" ignored.");
+
+ return show_tracers();
+ }
+
+ /* <idx> ... */
+ s = str_to_number(argv[0], NULL, &val);
+ if (*s || val > 0xff) {
+ warnx("\"%s\" is neither an index nor a tracer subcommand.",
+ argv[0]);
+ return (EINVAL);
+ }
+ idx = (int8_t)val;
+
+ /* <idx> disable */
+ if (argc == 2 && strcmp(argv[1], "disable") == 0)
+ return tracer_onoff(idx, 0);
+
+ /* <idx> enable */
+ if (argc == 2 && strcmp(argv[1], "enable") == 0)
+ return tracer_onoff(idx, 1);
+
+ /* <idx> ... */
+ return set_tracer(idx, argc - 1, argv + 1);
+}
+
+static int
run_cmd(int argc, const char *argv[])
{
int rc = -1;
@@ -1686,6 +1898,8 @@ run_cmd(int argc, const char *argv[])
rc = read_i2c(argc, argv);
else if (!strcmp(cmd, "clearstats"))
rc = clearstats(argc, argv);
+ else if (!strcmp(cmd, "tracer"))
+ rc = tracer_cmd(argc, argv);
else {
rc = EINVAL;
warnx("invalid command \"%s\"", cmd);
diff --git a/tools/tools/drm/README b/tools/tools/drm/README
new file mode 100644
index 0000000..35660ed
--- /dev/null
+++ b/tools/tools/drm/README
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+gen-drm_pciids Generate drm_pciids.h based on Linux' drm_pciids.h, FreeBSD's
+ drm_pciids.h and misc/pciids database.
+radeon Tools specific to the Radeon device driver.
diff --git a/tools/tools/drm/gen-drm_pciids b/tools/tools/drm/gen-drm_pciids
new file mode 100755
index 0000000..02ed562
--- /dev/null
+++ b/tools/tools/drm/gen-drm_pciids
@@ -0,0 +1,183 @@
+#!/usr/bin/perl
+# $FreeBSD$
+
+use strict;
+use warnings;
+use utf8;
+
+use File::Basename;
+
+my $progname = basename($0);
+
+sub parse_linux_header ($)
+{
+ my ($header) = @_;
+
+ open(my $fh, '<', $header) or die "Can't open Linux header: $!\n";
+
+ my $in_list = 0;
+
+ my %pciids = ();
+
+ my $current_vendor_define;
+
+ while (my $line = <$fh>) {
+ if ($line =~ /^#define +([^ ]+) +/) {
+ $current_vendor_define = $1;
+ $pciids{$current_vendor_define} = {};
+ } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}),[^,]+,[^,]+,[^,]+,[^,]+, *([^}]+)\}/) {
+ my $vendor_id = uc($1);
+ my $device_id = uc($2);
+ my $flags = $3;
+
+ $pciids{$current_vendor_define}{$device_id} = {
+ 'vendor_id' => $vendor_id,
+ 'flags' => $flags
+ };
+ }
+ }
+
+ close($fh);
+
+ return %pciids;
+}
+
+sub parse_freebsd_header ($) {
+ my ($header) = @_;
+
+ open(my $fh, '<', $header) or die "Can't open FreeBSD header: $!\n";
+
+ my $in_list = 0;
+
+ my %pciids = ();
+
+ my $current_vendor_define;
+
+ while (my $line = <$fh>) {
+ if ($line =~ /^#define +([^ ]+) +/) {
+ $current_vendor_define = $1;
+ $pciids{$current_vendor_define} = {};
+ } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}), *([^,]+), *"([^"]+)"\}/) {
+ my $vendor_id = uc($1);
+ my $device_id = uc($2);
+ my $flags = $3;
+ my $name = $4;
+
+ $pciids{$current_vendor_define}{$device_id} = {
+ 'vendor_id' => $vendor_id,
+ 'flags' => $flags,
+ 'name' => $name
+ };
+ }
+ }
+
+ close($fh);
+
+ return %pciids;
+}
+
+sub parse_pciids_db ($) {
+ my ($header) = @_;
+
+ open(my $fh, '<', $header) or die "Can't open PCI IDs database: $!\n";
+
+ my %pciids = ();
+
+ my $current_vendor_id;
+
+ while (my $line = <$fh>) {
+ if (!$line || $line =~ /^#/) {
+ next;
+ }
+ if ($line =~ /^([0-9a-fA-F]{4}) (.+)/) {
+ # Vendor ID & name.
+ my $vendor_id = uc($1);
+ my $vendor_name = $2;
+ $pciids{$vendor_id} = {
+ 'name' => $vendor_name,
+ 'devices' => {}
+ };
+
+ $current_vendor_id = $vendor_id;
+ } elsif ($line =~ /^\t([0-9a-fA-F]{4}) (.+)/) {
+ # Device ID & name.
+ my $device_id = uc($1);
+ my $device_name = $2;
+ $pciids{$current_vendor_id}{'devices'}{$device_id} = $device_name;
+ }
+ }
+
+ close($fh);
+
+ return %pciids;
+}
+
+if (scalar(@ARGV) != 3) {
+ print STDERR "Syntax: $progname <linux_header> <freebsd_header> <pciids_db> [<vendor_define>]\n";
+ exit 1;
+}
+
+my $linux_header = $ARGV[0];
+my $freebsd_header = $ARGV[1];
+my $pciids_db = $ARGV[2];
+my $only_vendor = $ARGV[3];
+
+my %linux_pciids = parse_linux_header($linux_header);
+my %freebsd_pciids = parse_freebsd_header($freebsd_header);
+my %pciids_db = parse_pciids_db($pciids_db);
+
+print STDERR "Update FreeBSD's PCI IDs:\n";
+foreach my $vendor_define (sort keys(%linux_pciids)) {
+ if ($only_vendor && $vendor_define ne $only_vendor) {
+ print STDERR "(skip unwanted define: $vendor_define)\n";
+ next;
+ } elsif (!$only_vendor && !exists($freebsd_pciids{$vendor_define})) {
+ print STDERR "(skip unsupport define: $vendor_define)\n";
+ next;
+ }
+
+ foreach my $device_id (sort keys(%{$linux_pciids{$vendor_define}})) {
+ my $vendor_id = $linux_pciids{$vendor_define}{$device_id}{'vendor_id'};
+
+ if (exists($freebsd_pciids{$vendor_define}{$device_id})) {
+ print STDERR " $vendor_define: $vendor_id:$device_id already in header\n";
+ next;
+ }
+
+ my $flags = $linux_pciids{$vendor_define}{$device_id}{'flags'};
+ my $name = $pciids_db{$vendor_id}{'devices'}{$device_id} || "Unknown device name";
+ print STDERR " $vendor_define: $vendor_id:$device_id is missing ($name)\n";
+ $freebsd_pciids{$vendor_define}{$device_id} = {
+ 'vendor_id' => $vendor_id,
+ 'flags' => $flags,
+ 'name' => $name
+ };
+ }
+}
+
+print STDERR "\nWrite FreeBSD header to stdout...\n";
+print <<"EOF";
+/*
+ * \$FreeBSD\$
+ */
+
+/*
+ * Generated by $progname from:
+ * o previous FreeBSD's drm_pciids.h
+ * o Linux' drm_pciids.h
+ * o the PCI ID repository (http://pciids.sourceforge.net/)
+ *
+ * See tools/tools/drm/$progname.
+ */
+EOF
+foreach my $vendor_define (sort keys(%freebsd_pciids)) {
+ print "\n#define $vendor_define \\\n";
+ foreach my $device_id (sort keys(%{$freebsd_pciids{$vendor_define}})) {
+ my $vendor_id = $freebsd_pciids{$vendor_define}{$device_id}{'vendor_id'};
+ my $flags = $freebsd_pciids{$vendor_define}{$device_id}{'flags'};
+ my $name = $freebsd_pciids{$vendor_define}{$device_id}{'name'};
+
+ print "\t{0x$vendor_id, 0x$device_id, $flags, \"$name\"}, \\\n";
+ }
+ print "\t{0, 0, 0, NULL}\n";
+}
diff --git a/tools/tools/drm/radeon/README b/tools/tools/drm/radeon/README
new file mode 100644
index 0000000..a05878e
--- /dev/null
+++ b/tools/tools/drm/radeon/README
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+firmwares Tools to handle Radeon firmwares imported into the tree.
+mkregtable Generate headers used to build the Radeon driver.
diff --git a/tools/tools/drm/radeon/firmwares/README b/tools/tools/drm/radeon/firmwares/README
new file mode 100644
index 0000000..1a28c83
--- /dev/null
+++ b/tools/tools/drm/radeon/firmwares/README
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+To update firmwares:
+
+ 1. Clone the following Git repository:
+ git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
+
+ 2. Run this script as:
+ ./encode-firmwares /path/to/linux-firmwares/radeon
diff --git a/tools/tools/drm/radeon/firmwares/encode-firmwares b/tools/tools/drm/radeon/firmwares/encode-firmwares
new file mode 100755
index 0000000..e95c0d2
--- /dev/null
+++ b/tools/tools/drm/radeon/firmwares/encode-firmwares
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD$
+
+set -e
+
+scriptdir=$(cd $(dirname $0) && pwd)
+fwdir="$scriptdir/../../../../../sys/contrib/dev/drm2/radeonkmsfw"
+srcdir=$1
+
+if [ -z "$srcdir" -o ! -d "$srcdir" ]; then
+ echo "Syntax: $(basename $0) <path to original firmwares>" 1>&2
+ exit
+fi
+
+for file in "$srcdir"/*.bin; do
+ uuencode -o "$fwdir"/$(basename $file).uu $file $(basename $file)
+done
diff --git a/tools/tools/drm/radeon/mkregtable/Makefile b/tools/tools/drm/radeon/mkregtable/Makefile
new file mode 100644
index 0000000..b83cf5c
--- /dev/null
+++ b/tools/tools/drm/radeon/mkregtable/Makefile
@@ -0,0 +1,58 @@
+# $FreeBSD$
+
+all: regtables
+
+PROG= mkregtable
+
+SRCS= mkregtable.c
+
+NO_MAN=
+
+MKREGTABLE= ${PROG}
+KERNSRCDIR= ${.CURDIR}/../../../../../sys
+REG_SRCS_DIR= ${KERNSRCDIR}/dev/drm2/radeon/reg_srcs
+REG_DEST_DIR= ${KERNSRCDIR}/dev/drm2/radeon
+
+regtables: \
+ ${REG_DEST_DIR}/rn50_reg_safe.h \
+ ${REG_DEST_DIR}/r100_reg_safe.h \
+ ${REG_DEST_DIR}/r200_reg_safe.h \
+ ${REG_DEST_DIR}/rv515_reg_safe.h \
+ ${REG_DEST_DIR}/r300_reg_safe.h \
+ ${REG_DEST_DIR}/r420_reg_safe.h \
+ ${REG_DEST_DIR}/rs600_reg_safe.h \
+ ${REG_DEST_DIR}/r600_reg_safe.h \
+ ${REG_DEST_DIR}/evergreen_reg_safe.h \
+ ${REG_DEST_DIR}/cayman_reg_safe.h
+
+${REG_DEST_DIR}/rn50_reg_safe.h: ${REG_SRCS_DIR}/rn50 ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/rn50 > $@
+
+${REG_DEST_DIR}/r100_reg_safe.h: ${REG_SRCS_DIR}/r100 ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/r100 > $@
+
+${REG_DEST_DIR}/r200_reg_safe.h: ${REG_SRCS_DIR}/r200 ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/r200 > $@
+
+${REG_DEST_DIR}/rv515_reg_safe.h: ${REG_SRCS_DIR}/rv515 ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/rv515 > $@
+
+${REG_DEST_DIR}/r300_reg_safe.h: ${REG_SRCS_DIR}/r300 ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/r300 > $@
+
+${REG_DEST_DIR}/r420_reg_safe.h: ${REG_SRCS_DIR}/r420 ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/r420 > $@
+
+${REG_DEST_DIR}/rs600_reg_safe.h: ${REG_SRCS_DIR}/rs600 ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/rs600 > $@
+
+${REG_DEST_DIR}/r600_reg_safe.h: ${REG_SRCS_DIR}/r600 ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/r600 > $@
+
+${REG_DEST_DIR}/evergreen_reg_safe.h: ${REG_SRCS_DIR}/evergreen ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/evergreen > $@
+
+${REG_DEST_DIR}/cayman_reg_safe.h: ${REG_SRCS_DIR}/cayman ${MKREGTABLE}
+ ./${MKREGTABLE} ${REG_SRCS_DIR}/cayman > $@
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/drm/radeon/mkregtable/README b/tools/tools/drm/radeon/mkregtable/README
new file mode 100644
index 0000000..12b8699
--- /dev/null
+++ b/tools/tools/drm/radeon/mkregtable/README
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+"mkregtable" is a tool used to generate headers for the radeonkms
+driver. Headers are regenerated by running "make" in this directory.
+
+Header source files are in sys/dev/drm2/radeon/reg_srcs.
+Generated headers are placed in sys/dev/drm2/radeon.
diff --git a/tools/tools/drm/radeon/mkregtable/mkregtable.c b/tools/tools/drm/radeon/mkregtable/mkregtable.c
new file mode 100644
index 0000000..51b8f90
--- /dev/null
+++ b/tools/tools/drm/radeon/mkregtable/mkregtable.c
@@ -0,0 +1,733 @@
+/* utility to create the register check tables
+ * this includes inlined list.h safe for userspace.
+ *
+ * Copyright 2009 Jerome Glisse
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Dave Airlie
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <regex.h>
+#include <libgen.h>
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type *)0)->member)*__mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev, struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+#else
+extern void __list_add(struct list_head *new,
+ struct list_head *prev, struct list_head *next);
+#endif
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head *prev, struct list_head *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = (void *)0xDEADBEEF;
+ entry->prev = (void *)0xBEEFDEAD;
+}
+#else
+extern void list_del(struct list_head *entry);
+#endif
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old, struct list_head *new)
+{
+ new->next = old->next;
+ new->next->prev = new;
+ new->prev = old->prev;
+ new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+ struct list_head *new)
+{
+ list_replace(old, new);
+ INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+ const struct list_head *head)
+{
+ return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+ struct list_head *next = head->next;
+ return (next == head) && (next == head->prev);
+}
+
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static inline int list_is_singular(const struct list_head *head)
+{
+ return !list_empty(head) && (head->next == head->prev);
+}
+
+static inline void __list_cut_position(struct list_head *list,
+ struct list_head *head,
+ struct list_head *entry)
+{
+ struct list_head *new_first = entry->next;
+ list->next = head->next;
+ list->next->prev = list;
+ list->prev = entry;
+ entry->next = list;
+ head->next = new_first;
+ new_first->prev = head;
+}
+
+/**
+ * list_cut_position - cut a list into two
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ * and if so we won't cut the list
+ *
+ * This helper moves the initial part of @head, up to and
+ * including @entry, from @head to @list. You should
+ * pass on @entry an element you know is on @head. @list
+ * should be an empty list or a list you do not care about
+ * losing its data.
+ *
+ */
+static inline void list_cut_position(struct list_head *list,
+ struct list_head *head,
+ struct list_head *entry)
+{
+ if (list_empty(head))
+ return;
+ if (list_is_singular(head) && (head->next != entry && head != entry))
+ return;
+ if (entry == head)
+ INIT_LIST_HEAD(list);
+ else
+ __list_cut_position(list, head, entry);
+}
+
+static inline void __list_splice(const struct list_head *list,
+ struct list_head *prev, struct list_head *next)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+
+ first->prev = prev;
+ prev->next = first;
+
+ last->next = next;
+ next->prev = last;
+}
+
+/**
+ * list_splice - join two lists, this is designed for stacks
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(const struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head, head->next);
+}
+
+/**
+ * list_splice_tail - join two lists, each list being a queue
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice_tail(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head->prev, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head, head->next);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_splice_tail_init - join two lists and reinitialise the emptied list
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * Each of the lists is a queue.
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_tail_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head->prev, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; prefetch(pos->next), pos != (head); \
+ pos = pos->next)
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+ pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+ for (pos = (head)->prev, n = pos->prev; \
+ prefetch(pos->prev), pos != (head); \
+ pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ prefetch(pos->member.prev), &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos: the type * to use as a start point
+ * @head: the head of the list
+ * @member: the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+ ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member); \
+ prefetch(pos->member.next), &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member) \
+ for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
+ prefetch(pos->member.prev), &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member) \
+ for (; prefetch(pos->member.next), &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) \
+ for (n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+struct offset {
+ struct list_head list;
+ unsigned offset;
+};
+
+struct table {
+ struct list_head offsets;
+ unsigned offset_max;
+ unsigned nentry;
+ unsigned *table;
+ char *gpu_prefix;
+};
+
+static struct offset *offset_new(unsigned o)
+{
+ struct offset *offset;
+
+ offset = (struct offset *)malloc(sizeof(struct offset));
+ if (offset) {
+ INIT_LIST_HEAD(&offset->list);
+ offset->offset = o;
+ }
+ return offset;
+}
+
+static void table_offset_add(struct table *t, struct offset *offset)
+{
+ list_add_tail(&offset->list, &t->offsets);
+}
+
+static void table_init(struct table *t)
+{
+ INIT_LIST_HEAD(&t->offsets);
+ t->offset_max = 0;
+ t->nentry = 0;
+ t->table = NULL;
+}
+
+static void table_print(struct table *t)
+{
+ unsigned nlloop, i, j, n, c, id;
+
+ nlloop = (t->nentry + 3) / 4;
+ c = t->nentry;
+ printf(
+ "#include <sys/cdefs.h>\n"
+ "__FBSDID(\"$" "FreeBSD" "$\");\n"
+ "\n"
+ );
+ printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
+ t->nentry);
+ for (i = 0, id = 0; i < nlloop; i++) {
+ n = 4;
+ if (n > c)
+ n = c;
+ c -= n;
+ for (j = 0; j < n; j++) {
+ if (j == 0)
+ printf("\t");
+ else
+ printf(" ");
+ printf("0x%08X,", t->table[id++]);
+ }
+ printf("\n");
+ }
+ printf("};\n");
+}
+
+static int table_build(struct table *t)
+{
+ struct offset *offset;
+ unsigned i, m;
+
+ t->nentry = ((t->offset_max >> 2) + 31) / 32;
+ t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
+ if (t->table == NULL)
+ return -1;
+ memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
+ list_for_each_entry(offset, &t->offsets, list) {
+ i = (offset->offset >> 2) / 32;
+ m = (offset->offset >> 2) & 31;
+ m = 1 << m;
+ t->table[i] ^= m;
+ }
+ return 0;
+}
+
+static char gpu_name[10];
+static int parser_auth(struct table *t, const char *filename)
+{
+ FILE *file;
+ regex_t mask_rex;
+ regmatch_t match[4];
+ char buf[1024];
+ size_t end;
+ int len;
+ int done = 0;
+ int r;
+ unsigned o;
+ struct offset *offset;
+ char last_reg_s[10];
+ int last_reg;
+
+ if (regcomp
+ (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
+ fprintf(stderr, "Failed to compile regular expression\n");
+ return -1;
+ }
+ file = fopen(filename, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Failed to open: %s\n", filename);
+ return -1;
+ }
+ fseek(file, 0, SEEK_END);
+ end = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /* get header */
+ if (fgets(buf, 1024, file) == NULL) {
+ fclose(file);
+ return -1;
+ }
+
+ /* first line will contain the last register
+ * and gpu name */
+ sscanf(buf, "%s %s", gpu_name, last_reg_s);
+ t->gpu_prefix = gpu_name;
+ last_reg = strtol(last_reg_s, NULL, 16);
+
+ do {
+ if (fgets(buf, 1024, file) == NULL) {
+ fclose(file);
+ return -1;
+ }
+ len = strlen(buf);
+ if (ftell(file) == end)
+ done = 1;
+ if (len) {
+ r = regexec(&mask_rex, buf, 4, match, 0);
+ if (r == REG_NOMATCH) {
+ } else if (r) {
+ fprintf(stderr,
+ "Error matching regular expression %d in %s\n",
+ r, filename);
+ fclose(file);
+ return -1;
+ } else {
+ buf[match[0].rm_eo] = 0;
+ buf[match[1].rm_eo] = 0;
+ buf[match[2].rm_eo] = 0;
+ o = strtol(&buf[match[1].rm_so], NULL, 16);
+ offset = offset_new(o);
+ table_offset_add(t, offset);
+ if (o > t->offset_max)
+ t->offset_max = o;
+ }
+ }
+ } while (!done);
+ fclose(file);
+ if (t->offset_max < last_reg)
+ t->offset_max = last_reg;
+ return table_build(t);
+}
+
+int main(int argc, char *argv[])
+{
+ struct table t;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
+ exit(1);
+ }
+ table_init(&t);
+ if (parser_auth(&t, argv[1])) {
+ fprintf(stderr, "Failed to parse file %s\n", argv[1]);
+ return -1;
+ }
+ table_print(&t);
+ return 0;
+}
diff --git a/tools/tools/ifinfo/ifinfo.c b/tools/tools/ifinfo/ifinfo.c
index f5987f7..bfc3863 100644
--- a/tools/tools/ifinfo/ifinfo.c
+++ b/tools/tools/ifinfo/ifinfo.c
@@ -169,8 +169,11 @@ printit(const struct ifmibdata *ifmd, const char *dname)
ifmd->ifmd_data.ifi_physical));
printf("\taddress length: %d\n", ifmd->ifmd_data.ifi_addrlen);
printf("\theader length: %d\n", ifmd->ifmd_data.ifi_hdrlen);
- printf("\treceive spare char1: %u\n", ifmd->ifmd_data.ifi_spare_char1);
- printf("\ttransmit spare char2: %u\n", ifmd->ifmd_data.ifi_spare_char2);
+ printf("\tlink state: %u\n", ifmd->ifmd_data.ifi_link_state);
+ printf("\tvhid: %u\n", ifmd->ifmd_data.ifi_vhid);
+ printf("\tbaudrate power factor: %u\n",
+ ifmd->ifmd_data.ifi_baudrate_pf);
+ printf("\tdatalen: %u\n", ifmd->ifmd_data.ifi_datalen);
printf("\tmtu: %lu\n", ifmd->ifmd_data.ifi_mtu);
printf("\tmetric: %lu\n", ifmd->ifmd_data.ifi_metric);
printf("\tline rate: %lu bit/s\n", ifmd->ifmd_data.ifi_baudrate);
@@ -186,6 +189,10 @@ printit(const struct ifmibdata *ifmd, const char *dname)
printf("\tinput queue drops: %lu\n", ifmd->ifmd_data.ifi_iqdrops);
printf("\tpackets for unknown protocol: %lu\n",
ifmd->ifmd_data.ifi_noproto);
+ printf("\tHW offload capabilities: 0x%lx\n",
+ ifmd->ifmd_data.ifi_hwassist);
+ printf("\tuptime at attach or stat reset: %lu\n",
+ ifmd->ifmd_data.ifi_epoch);
#ifdef notdef
printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming);
printf("\ttransmit timing: %lu usec\n",
diff --git a/tools/tools/makeroot/Makefile b/tools/tools/makeroot/Makefile
new file mode 100644
index 0000000..ebf81ae
--- /dev/null
+++ b/tools/tools/makeroot/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+SCRIPTS= makeroot.sh
+MAN= makeroot.8
+
+BINDIR?= /usr/sbin
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/makeroot/makeroot.8 b/tools/tools/makeroot/makeroot.8
new file mode 100644
index 0000000..379187c
--- /dev/null
+++ b/tools/tools/makeroot/makeroot.8
@@ -0,0 +1,131 @@
+.\"-
+.\" Copyright (c) 2013 SRI International
+.\" All rights reserved.
+.\"
+.\" This software was developed by SRI International and the University of
+.\" Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+.\" ("CTSRD"), as part of the DARPA CRASH research programme.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.Dd May 20, 2013
+.Dt MAKEROOT 8
+.Os
+.Sh NAME
+.Nm makeroot
+.Nd Tool to create root filesystem images given a tree containing a manifest
+.Sh SYNOPSIS
+.Nm
+.Op Fl d
+.Op Fl B Ar byte-order
+.Op Fl e Ar extras-manifest
+.Op Fl f Ar filelist
+.Op Fl k Ar keydir Op Fl K Ar user
+.Op Fl p Ar master.passwd Op Fl g Ar group
+.Op Fl s Ar size
+.Ar image-file
+.Ar rootdir
+.Sh DESCRIPTION
+The
+.Nm
+script creates a UFS filesystem image into
+.Ar imagefile .
+By default,
+all filesystem objects listed in the
+.Pa METALOG
+file contained in the
+.Ar rootdir
+directory will be placed in the root of the UFS image
+.Ar image-file .
+.Pp
+Images can be customized with a number of different flags:
+.Bl -tag -width indent
+.It Fl B Ar byte-order
+Set the byte order of the image to
+.Ar byte-order .
+This argument is passed directly to
+.Xr makefs 8 .
+.It Fl d
+Enable debugging output.
+.It Fl e Ar manifest
+Extra files listed in the
+.Xr nmtree 8
+format
+.Ar manifest
+file are added to the filesystem image.
+If no contents= tag is specified or a contents= tag is relative then
+files are found relative to the basename of the full path of the
+manifest.
+If a contents= tag is provided and it is an absolute path then the file
+will be from that path.
+.It Fl f Ar filelist
+Constrain set of filesystem objects included from
+.Ar rootdir
+to those listed (one per line) in the
+.Ar filelist
+plus any required directories.
+.It Fl k Ar keydir Op Fl K Ar user
+Create a .ssh/authorized_keys file from a collection of public key files
+stored in
+.Ar keydir
+and install it in the home directory of
+.Ar user .
+If no
+.Fl K
+argument is supplied then the files will be installed in the root user's
+directory.
+.It Fl p Ar master.passwd Op Fl g Ar group
+Install an alternate
+.Ar master.passwd
+file and optionally an alternative
+.Ar group
+file.
+.It Fl s Ar size
+Set the size of the image to
+.Ar size .
+The
+.Fl s
+argument is passed directly to
+.Xr makefs 8 .
+.El
+.Sh FILES
+.Bl -tag -width METALOG -compact
+.It Pa METALOG
+.Xr mtree 5
+2.0 format manifest of permissions and ownership for files in the root
+directory.
+This file is generated by installworld, distribution, and installkernel.
+.El
+.Sh EXAMPLES
+.Dl $ makeroot.sh -k keys -K ctsrd -p extras/etc/master.passwd -g extras/etc/group -e extras/mdroot.mtree -e demo/demo.mtree -e extras/ctsrd.mtree -s 26112k -f demo.files cheribsd-demo.img /path/to/dist
+.Sh SEE ALSO
+.Xr mtree 5 ,
+.Xr makefs 8 ,
+.Xr nmtree 8
+.Sh AUTHORS
+This software and this manual page were developed by SRI International
+and the University of Cambridge Computer Laboratory under DARPA/AFRL
+contract
+.Pq FA8750-10-C-0237
+.Pq Do CTSRD Dc ,
+as part of the DARPA CRASH research programme.
diff --git a/tools/tools/makeroot/makeroot.sh b/tools/tools/makeroot/makeroot.sh
new file mode 100755
index 0000000..3db4e7f
--- /dev/null
+++ b/tools/tools/makeroot/makeroot.sh
@@ -0,0 +1,236 @@
+#!/bin/sh -e
+#-
+# Copyright (c) 2012-2013 SRI International
+# Copyright (c) 2012 Robert N. M. Watson
+# All rights reserved.
+#
+# This software was developed by SRI International and the University of
+# Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+# ("CTSRD"), as part of the DARPA CRASH research programme.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+usage()
+{
+ cat <<EOF 1>&2
+usage: makeroot.sh [-B byte-order] [-d] [-e <extras manifest>] [-f <filelist>]
+ [-k <keydir> [-K <user>]]
+ [-p <master.passwd> [-g <groupfile>]] [-s <size>]
+ <image> <bsdroot>
+EOF
+ exit 1
+}
+
+warn()
+{
+ echo `basename $0` "$@" 1>&2
+}
+
+err()
+{
+ ret=$1
+ shift
+ warn "$@"
+ exit $ret
+}
+
+atexit()
+{
+ if [ -z "${DEBUG}" ]; then
+ rm -rf ${tmpdir}
+ else
+ warn "temp directory left at ${tmpdir}"
+ fi
+}
+
+DEBUG=
+# Allow duplice manifest entries when not file list is given because the
+# FreeBSD METALOG still includes it.
+DUPFLAG=-D
+EXTRAS=
+FILELIST=
+GROUP=
+KEYDIR=
+KEYUSERS=
+PASSWD=
+
+while getopts "Bde:f:g:K:k:p:s:" opt; do
+ case "$opt" in
+ B) BFLAG="-B ${OPTARG}" ;;
+ d) DEBUG=1 ;;
+ e) EXTRAS="${EXTRAS} ${OPTARG}" ;;
+ f) FILELIST="${OPTARG}"; DUPFLAG= ;;
+ g) GROUP="${OPTARG}" ;;
+ K) KEYUSERS="${KEYUSERS} ${OPTARG}" ;;
+ k) KEYDIR="${OPTARG}" ;;
+ p) PASSWD="${OPTARG}" ;;
+ s) SIZE="${OPTARG}" ;;
+ *) usage ;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+if [ $# -ne 2 ]; then
+ usage;
+fi
+
+IMGFILE=$(realpath $(dirname $1))/$(basename $1)
+BSDROOT=$2
+
+DBDIR=${BSDROOT}/etc
+
+if [ ! -r ${BSDROOT}/METALOG ]; then
+ err 1 "${BSDROOT} does not contain a METALOG"
+fi
+
+if [ -n "${GROUP}" -a -z "${PASSWD}" ]; then
+ warn "-g requires -p"
+ usage
+fi
+
+if [ -n "${KEYUSERS}" -a -z "${KEYDIR}" ]; then
+ warn "-K requires -k"
+ usage
+fi
+if [ -n "${KEYDIR}" -a -z "${KEYUSERS}" ]; then
+ KEYUSERS=root
+fi
+
+tmpdir=`mktemp -d /tmp/makeroot.XXXXX`
+if [ -z "${tmpdir}" -o ! -d "${tmpdir}" ]; then
+ err 1 "failed to create tmpdir"
+fi
+trap atexit EXIT
+
+manifest=${tmpdir}/manifest
+
+echo "#mtree 2.0" > ${manifest}
+
+if [ -n "${PASSWD}" ]; then
+ cp ${PASSWD} ${tmpdir}/master.passwd
+ pwd_mkdb -d ${tmpdir} -p ${tmpdir}/master.passwd
+ if [ -z "${GROUP}" ]; then
+ cp ${DBDIR}/group ${tmpdir}
+ else
+ cp ${GROUP} ${tmpdir}
+ fi
+
+ cat <<EOF >> ${tmpdir}/passwd.mtree
+./etc/group type=file uname=root gname=wheel mode=0644 contents=${tmpdir}/group
+./etc/master.passwd type=file uname=root gname=wheel mode=0600 contents=${tmpdir}/master.passwd
+./etc/passwd type=file mode=0644 uname=root gname=wheel contents=${tmpdir}/passwd
+./etc/pwd.db type=file mode=0644 uname=root gname=wheel contents=${tmpdir}/pwd.db
+./etc/spwd.db type=file mode=0600 uname=root gname=wheel contents=${tmpdir}/spwd.db
+EOF
+ EXTRAS="${EXTRAS} ${tmpdir}/passwd.mtree"
+
+ DBDIR=${tmpdir}
+fi
+
+if [ -n "${FILELIST}" ]; then
+ # build manifest from root manifest and FILELIST
+ (echo .; grep -v ^# ${FILELIST} | while read path; do
+ # Print each included path and all its sub-paths with a ./
+ # prepended. The "sort -u" will then discard all the
+ # duplicate directory entries. This ensures that we
+ # extract the permissions for each unlisted directory
+ # from the METALOG.
+ path="/${path}"
+ while [ -n "${path}" ]; do
+ echo ".${path}"
+ path="${path%/*}"
+ done
+ done) | sort -u ${BSDROOT}/METALOG - | \
+ awk '
+ !/ type=/ { file = $1 }
+ / type=/ { if ($1 == file) {print} }' >> ${manifest}
+else
+ # Start with all the files in BSDROOT/METALOG except those in
+ # one of the EXTRAS manifests.
+ grep -h type=file ${EXTRAS} | cut -d' ' -f1 | \
+ sort -u ${BSDROOT}/METALOG - | awk '
+ !/ type=/ { file = $1 }
+ / type=/ { if ($1 != file) {print} }' >> ${manifest}
+fi
+
+# For each extras file, add contents kyes relative to the directory the
+# manifest lives in for each file line that does not have one. Adjust
+# contents keys relative to ./ to be relative to the same directory.
+for eman in ${EXTRAS}; do
+ if [ ! -f ${eman} ]; then
+ err 1 "${eman} is not a regular file"
+ fi
+ extradir=`realpath ${eman}`; extradir=`dirname ${extradir}`
+
+ awk '{
+ if ($0 !~ /type=file/) {
+ print
+ } else {
+ if ($0 !~ /contents=/) {
+ printf ("%s contents=%s\n", $0, $1)
+ } else {
+ print
+ }
+ }
+ }' ${eman} | \
+ sed -e "s|contents=\./|contents=${extradir}/|" >> ${manifest}
+done
+
+# /etc/rcorder.start allows the startup order to be stable even if
+# not all startup scripts are installed. In theory it should be
+# unnecessicary, but dependencies in rc.d appear to be under recorded.
+# This is a hack local to beri/cheribsd.
+#
+echo /etc/rc.d/FIRST > ${tmpdir}/rcorder.start
+rcorder -s nostart ${BSDROOT}/etc/rc.d/* | sed -e "s:^${BSDROOT}::" | \
+ grep -v LAST | grep -v FIRST >> \
+ ${tmpdir}/rcorder.start
+echo /etc/rc.d/LAST >> ${tmpdir}/rcorder.start
+echo "./etc/rcorder.start type=file mode=644 uname=root gname=wheel" \
+ "contents=${tmpdir}/rcorder.start" >> ${manifest}
+
+# Add all public keys in KEYDIR to roots' authorized_keys file.
+if [ -n "${KEYDIR}" ]; then
+ cat ${KEYDIR}/*.pub > ${tmpdir}/authorized_keys
+ if [ ! -s ${tmpdir}/authorized_keys ]; then
+ err 1 "no keys found in ${KEYDIR}"
+ fi
+ for user in ${KEYUSERS}; do
+ userdir=`awk -F: "{if (\\\$1 == \"${user}\") {print \\\$9; exit} }" ${DBDIR}/master.passwd`
+ gid=`awk -F: "{if (\\\$1 == \"${user}\") {print \\\$4; exit} }" ${DBDIR}/master.passwd`
+ group=`awk -F: "{if (\\\$3 == \"${gid}\") {print \\\$1; exit} }" ${DBDIR}/group`
+ if [ -z "${userdir}" ]; then
+ err 1 "${user}: not found in ${DBDIR}/master.passwd"
+ fi
+ echo ".${userdir}/.ssh type=dir mode=700 uname=${user} gname=${group}" >> ${manifest}
+ echo ".${userdir}/.ssh/authorized_keys type=file mode=600 uname=${user} gname=${group} contents=${tmpdir}/authorized_keys" >> ${manifest}
+ done
+fi
+
+if [ -n "${SIZE}" ]; then
+SIZEFLAG="-s ${SIZE}"
+fi
+
+cd ${BSDROOT}; makefs ${DUPFLAG} -N ${DBDIR} ${SIZEFLAG} ${BFLAG} \
+ -t ffs -f 256 ${IMGFILE} ${manifest}
diff --git a/tools/tools/nanobsd/gateworks/common b/tools/tools/nanobsd/gateworks/common
index c23a2bf..182bfbd 100644
--- a/tools/tools/nanobsd/gateworks/common
+++ b/tools/tools/nanobsd/gateworks/common
@@ -113,7 +113,6 @@ WITHOUT_BSNMP=true
WITHOUT_CALENDAR=true
WITHOUT_CDDL=true
WITHOUT_CTM=true
-WITHOUT_CVS=true
WITHOUT_DICT=true
WITHOUT_EXAMPLES=true
WITHOUT_FLOPPY=true
diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh
index c3e96b3..216c900 100644
--- a/tools/tools/nanobsd/nanobsd.sh
+++ b/tools/tools/nanobsd/nanobsd.sh
@@ -359,8 +359,7 @@ setup_nanobsd ( ) (
echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount
# Put /tmp on the /var ramdisk (could be symlink already)
- rmdir tmp || true
- rm tmp || true
+ test -d tmp && rmdir tmp || rm -f tmp
ln -s var/tmp tmp
) > ${NANO_OBJ}/_.dl 2>&1
@@ -413,12 +412,13 @@ populate_slice ( ) (
dir=$2
mnt=$3
lbl=$4
- test -z $2 && dir=${NANO_WORLDDIR}/var/empty
- test -d $dir || dir=${NANO_WORLDDIR}/var/empty
- echo "Creating ${dev} with ${dir} (mounting on ${mnt})"
- newfs_part $dev $mnt $lbl
- cd ${dir}
- find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${mnt}
+ echo "Creating ${dev} (mounting on ${mnt})"
+ newfs_part ${dev} ${mnt} ${lbl}
+ if [ -n "${dir}" -a -d "${dir}" ]; then
+ echo "Populating ${lbl} from ${dir}"
+ cd ${dir}
+ find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${mnt}
+ fi
df -i ${mnt}
umount ${mnt}
)
@@ -540,7 +540,7 @@ create_i386_diskimage ( ) (
if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then
# Duplicate to second image (if present)
echo "Duplicating to second image..."
- dd if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k
+ dd conv=sparse if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k
mount /dev/${MD}s2a ${MNT}
for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab
do
@@ -564,12 +564,12 @@ create_i386_diskimage ( ) (
if [ "${NANO_MD_BACKING}" = "swap" ] ; then
echo "Writing out ${NANO_IMGNAME}..."
- dd if=/dev/${MD} of=${IMG} bs=64k
+ dd conv=sparse if=/dev/${MD} of=${IMG} bs=64k
fi
if ${do_copyout_partition} ; then
echo "Writing out _.disk.image..."
- dd if=/dev/${MD}s1 of=${NANO_DISKIMGDIR}/_.disk.image bs=64k
+ dd conv=sparse if=/dev/${MD}s1 of=${NANO_DISKIMGDIR}/_.disk.image bs=64k
fi
mdconfig -d -u $MD
@@ -588,6 +588,7 @@ last_orders () (
# after the build completed, for instance to copy the finished
# image to a more convenient place:
# cp ${NANO_DISKIMGDIR}/_.disk.image /home/ftp/pub/nanobsd.disk
+ true
)
#######################################################################
diff --git a/tools/tools/netmap/Makefile b/tools/tools/netmap/Makefile
index 2593a27..d737bac 100644
--- a/tools/tools/netmap/Makefile
+++ b/tools/tools/netmap/Makefile
@@ -3,7 +3,7 @@
#
# For multiple programs using a single source file each,
# we can just define 'progs' and create custom targets.
-PROGS = pkt-gen bridge testpcap libnetmap.so
+PROGS = pkt-gen bridge vale-ctl testpcap libnetmap.so
CLEANFILES = $(PROGS) pcap.o nm_util.o
NO_MAN=
diff --git a/tools/tools/netmap/README b/tools/tools/netmap/README
index 3520790..2bde6f2 100644
--- a/tools/tools/netmap/README
+++ b/tools/tools/netmap/README
@@ -21,3 +21,4 @@ BSD netmap
0.77 3.82 ports/trafshow (version 5)
0.94 7.7 net-mgmt/ipcad (ip accounting daemon)
0.9 5.0 net-mgmt/darkstat (ip accounting + graphing)
+ 0.83 2.45 net-mgmt/iftop (curses traffic display)
diff --git a/tools/tools/netmap/bridge.c b/tools/tools/netmap/bridge.c
index 473ee0c..0aca44d 100644
--- a/tools/tools/netmap/bridge.c
+++ b/tools/tools/netmap/bridge.c
@@ -14,7 +14,7 @@
int verbose = 0;
-char *version = "$Id: bridge.c 12016 2013-01-23 17:24:22Z luigi $";
+char *version = "$Id$";
static int do_abort = 0;
@@ -50,7 +50,12 @@ process_rings(struct netmap_ring *rxring, struct netmap_ring *txring,
while (limit-- > 0) {
struct netmap_slot *rs = &rxring->slot[j];
struct netmap_slot *ts = &txring->slot[k];
+#ifdef NO_SWAP
+ char *rxbuf = NETMAP_BUF(rxring, rs->buf_idx);
+ char *txbuf = NETMAP_BUF(txring, ts->buf_idx);
+#else
uint32_t pkt;
+#endif
/* swap packets */
if (ts->buf_idx < 2 || rs->buf_idx < 2) {
@@ -58,20 +63,24 @@ process_rings(struct netmap_ring *rxring, struct netmap_ring *txring,
j, rs->buf_idx, k, ts->buf_idx);
sleep(2);
}
+#ifndef NO_SWAP
pkt = ts->buf_idx;
ts->buf_idx = rs->buf_idx;
rs->buf_idx = pkt;
-
+#endif
/* copy the packet length. */
if (rs->len < 14 || rs->len > 2048)
D("wrong len %d rx[%d] -> tx[%d]", rs->len, j, k);
else if (verbose > 1)
D("%s send len %d rx[%d] -> tx[%d]", msg, rs->len, j, k);
ts->len = rs->len;
-
+#ifdef NO_SWAP
+ pkt_copy(rxbuf, txbuf, ts->len);
+#else
/* report the buffer change. */
ts->flags |= NS_BUF_CHANGED;
rs->flags |= NS_BUF_CHANGED;
+#endif /* NO_SWAP */
j = NETMAP_RING_NEXT(rxring, j);
k = NETMAP_RING_NEXT(txring, k);
}
diff --git a/tools/tools/netmap/nm_util.c b/tools/tools/netmap/nm_util.c
index 2b2c0ca..6153603 100644
--- a/tools/tools/netmap/nm_util.c
+++ b/tools/tools/netmap/nm_util.c
@@ -221,7 +221,6 @@ netmap_close(struct my_ring *me)
D("");
if (me->mem)
munmap(me->mem, me->memsize);
- ioctl(me->fd, NIOCUNREGIF, NULL);
close(me->fd);
return (0);
}
diff --git a/tools/tools/netmap/pcap.c b/tools/tools/netmap/pcap.c
index c2acd1a..f30f57b 100644
--- a/tools/tools/netmap/pcap.c
+++ b/tools/tools/netmap/pcap.c
@@ -13,7 +13,7 @@
#define MY_PCAP
#include "nm_util.h"
-char *version = "$Id: pcap.c 11463 2012-07-30 15:26:02Z luigi $";
+char *version = "$Id$";
int verbose = 0;
/*
@@ -445,7 +445,6 @@ pcap_close(pcap_t *p)
if (me->mem)
munmap(me->mem, me->memsize);
/* restore original flags ? */
- ioctl(me->fd, NIOCUNREGIF, NULL);
close(me->fd);
bzero(me, sizeof(*me));
free(me);
diff --git a/tools/tools/netmap/pkt-gen.c b/tools/tools/netmap/pkt-gen.c
index 7c2ad98..901175e 100644
--- a/tools/tools/netmap/pkt-gen.c
+++ b/tools/tools/netmap/pkt-gen.c
@@ -25,7 +25,7 @@
/*
* $FreeBSD$
- * $Id: pkt-gen.c 12024 2013-01-25 05:41:51Z luigi $
+ * $Id$
*
* Example program to show how to build a multithreaded packet
* source/sink using the netmap device.
@@ -38,6 +38,8 @@
#include "nm_util.h"
+#include <ctype.h> // isprint()
+
const char *default_payload="netmap pkt-gen payload\n"
"http://info.iet.unipi.it/~luigi/netmap/ ";
@@ -86,9 +88,14 @@ struct glob_arg {
#define OPT_COPY 4
#define OPT_MEMCPY 8
#define OPT_TS 16 /* add a timestamp */
+#define OPT_INDIRECT 32 /* use indirect buffers, tx only */
+#define OPT_DUMP 64 /* dump rx/tx traffic */
int dev_type;
pcap_t *p;
+ int tx_rate;
+ struct timespec tx_period;
+
int affinity;
int main_fd;
int report_interval;
@@ -114,7 +121,7 @@ struct targ {
struct netmap_if *nifp;
uint16_t qfirst, qlast; /* range of queues to scan */
volatile uint64_t count;
- struct timeval tic, toc;
+ struct timespec tic, toc;
int me;
pthread_t thread;
int affinity;
@@ -343,6 +350,33 @@ wrapsum(u_int32_t sum)
return (htons(sum));
}
+/* Check the payload of the packet for errors (use it for debug).
+ * Look for consecutive ascii representations of the size of the packet.
+ */
+static void
+dump_payload(char *p, int len, struct netmap_ring *ring, int cur)
+{
+ char buf[128];
+ int i, j, i0;
+
+ /* get the length in ASCII of the length of the packet. */
+
+ printf("ring %p cur %5d len %5d buf %p\n", ring, cur, len, p);
+ /* hexdump routine */
+ for (i = 0; i < len; ) {
+ memset(buf, sizeof(buf), ' ');
+ sprintf(buf, "%5d: ", i);
+ i0 = i;
+ for (j=0; j < 16 && i < len; i++, j++)
+ sprintf(buf+7+j*3, "%02x ", (uint8_t)(p[i]));
+ i = i0;
+ for (j=0; j < 16 && i < len; i++, j++)
+ sprintf(buf+7+j + 48, "%c",
+ isprint(p[i]) ? p[i] : '.');
+ printf("%s\n", buf);
+ }
+}
+
/*
* Fill a packet with some payload.
* We create a UDP packet so the payload starts at
@@ -354,6 +388,7 @@ wrapsum(u_int32_t sum)
#define uh_ulen len
#define uh_sum check
#endif /* linux */
+
static void
initialize_packet(struct targ *targ)
{
@@ -362,11 +397,13 @@ initialize_packet(struct targ *targ)
struct ip *ip;
struct udphdr *udp;
uint16_t paylen = targ->g->pkt_size - sizeof(*eh) - sizeof(struct ip);
- int i, l, l0 = strlen(default_payload);
+ const char *payload = targ->g->options & OPT_INDIRECT ?
+ "XXXXXXXXXXXXXXXXXXXXXX" : default_payload;
+ int i, l, l0 = strlen(payload);
for (i = 0; i < paylen;) {
l = min(l0, paylen - i);
- bcopy(default_payload, pkt->body + i, l);
+ bcopy(payload, pkt->body + i, l);
i += l;
}
pkt->body[i-1] = '\0';
@@ -412,34 +449,9 @@ initialize_packet(struct targ *targ)
bcopy(&targ->g->src_mac.start, eh->ether_shost, 6);
bcopy(&targ->g->dst_mac.start, eh->ether_dhost, 6);
eh->ether_type = htons(ETHERTYPE_IP);
+ // dump_payload((void *)pkt, targ->g->pkt_size, NULL, 0);
}
-/* Check the payload of the packet for errors (use it for debug).
- * Look for consecutive ascii representations of the size of the packet.
- */
-static void
-check_payload(char *p, int psize)
-{
- char temp[64];
- int n_read, size, sizelen;
-
- /* get the length in ASCII of the length of the packet. */
- sizelen = sprintf(temp, "%d", psize) + 1; // include a whitespace
-
- /* dummy payload. */
- p += 14; /* skip packet header. */
- n_read = 14;
- while (psize - n_read >= sizelen) {
- sscanf(p, "%d", &size);
- if (size != psize) {
- D("Read %d instead of %d", size, psize);
- break;
- }
-
- p += sizelen;
- n_read += sizelen;
- }
-}
/*
@@ -472,7 +484,13 @@ send_packets(struct netmap_ring *ring, struct pkt *pkt,
struct netmap_slot *slot = &ring->slot[cur];
char *p = NETMAP_BUF(ring, slot->buf_idx);
- if (options & OPT_COPY)
+ slot->flags = 0;
+ if (options & OPT_DUMP)
+ dump_payload(p, size, ring, cur);
+ if (options & OPT_INDIRECT) {
+ slot->flags |= NS_INDIRECT;
+ *((struct pkt **)(void *)p) = pkt;
+ } else if (options & OPT_COPY)
pkt_copy(pkt, p, size);
else if (options & OPT_MEMCPY)
memcpy(p, pkt, size);
@@ -669,6 +687,76 @@ ponger_body(void *data)
return NULL;
}
+static __inline int
+timespec_ge(const struct timespec *a, const struct timespec *b)
+{
+
+ if (a->tv_sec > b->tv_sec)
+ return (1);
+ if (a->tv_sec < b->tv_sec)
+ return (0);
+ if (a->tv_nsec >= b->tv_nsec)
+ return (1);
+ return (0);
+}
+
+static __inline struct timespec
+timeval2spec(const struct timeval *a)
+{
+ struct timespec ts = {
+ .tv_sec = a->tv_sec,
+ .tv_nsec = a->tv_usec * 1000
+ };
+ return ts;
+}
+
+static __inline struct timeval
+timespec2val(const struct timespec *a)
+{
+ struct timeval tv = {
+ .tv_sec = a->tv_sec,
+ .tv_usec = a->tv_nsec / 1000
+ };
+ return tv;
+}
+
+
+static int
+wait_time(struct timespec ts, struct timespec *wakeup_ts, long long *waited)
+{
+ struct timespec curtime;
+
+ curtime.tv_sec = 0;
+ curtime.tv_nsec = 0;
+
+ if (clock_gettime(CLOCK_REALTIME_PRECISE, &curtime) == -1) {
+ D("clock_gettime: %s", strerror(errno));
+ return (-1);
+ }
+ while (timespec_ge(&ts, &curtime)) {
+ if (waited != NULL)
+ (*waited)++;
+ if (clock_gettime(CLOCK_REALTIME_PRECISE, &curtime) == -1) {
+ D("clock_gettime");
+ return (-1);
+ }
+ }
+ if (wakeup_ts != NULL)
+ *wakeup_ts = curtime;
+ return (0);
+}
+
+static __inline void
+timespec_add(struct timespec *tsa, struct timespec *tsb)
+{
+ tsa->tv_sec += tsb->tv_sec;
+ tsa->tv_nsec += tsb->tv_nsec;
+ if (tsa->tv_nsec >= 1000000000) {
+ tsa->tv_sec++;
+ tsa->tv_nsec -= 1000000000;
+ }
+}
+
static void *
sender_body(void *data)
@@ -680,7 +768,11 @@ sender_body(void *data)
struct netmap_ring *txring;
int i, n = targ->g->npackets / targ->g->nthreads, sent = 0;
int options = targ->g->options | OPT_COPY;
-D("start");
+ struct timespec tmptime, nexttime = { 0, 0}; // XXX silence compiler
+ int rate_limit = targ->g->tx_rate;
+ long long waited = 0;
+
+ D("start");
if (setaffinity(targ->thread, targ->affinity))
goto quit;
/* setup poll(2) mechanism. */
@@ -689,8 +781,18 @@ D("start");
fds[0].events = (POLLOUT);
/* main loop.*/
- gettimeofday(&targ->tic, NULL);
-
+ clock_gettime(CLOCK_REALTIME_PRECISE, &targ->tic);
+ if (rate_limit) {
+ tmptime.tv_sec = 2;
+ tmptime.tv_nsec = 0;
+ timespec_add(&targ->tic, &tmptime);
+ targ->tic.tv_nsec = 0;
+ if (wait_time(targ->tic, NULL, NULL) == -1) {
+ D("wait_time: %s", strerror(errno));
+ goto quit;
+ }
+ nexttime = targ->tic;
+ }
if (targ->g->dev_type == DEV_PCAP) {
int size = targ->g->pkt_size;
void *pkt = &targ->pkt;
@@ -718,8 +820,18 @@ D("start");
}
}
} else {
+ int tosend = 0;
while (!targ->cancel && (n == 0 || sent < n)) {
+ if (rate_limit && tosend <= 0) {
+ tosend = targ->g->burst;
+ timespec_add(&nexttime, &targ->g->tx_period);
+ if (wait_time(nexttime, &tmptime, &waited) == -1) {
+ D("wait_time");
+ goto quit;
+ }
+ }
+
/*
* wait for available room in the send queue(s)
*/
@@ -737,7 +849,7 @@ D("start");
options &= ~OPT_COPY;
}
for (i = targ->qfirst; i < targ->qlast; i++) {
- int m, limit = targ->g->burst;
+ int m, limit = rate_limit ? tosend : targ->g->burst;
if (n > 0 && n - sent < limit)
limit = n - sent;
txring = NETMAP_TXRING(nifp, i);
@@ -746,6 +858,7 @@ D("start");
m = send_packets(txring, &targ->pkt, targ->g->pkt_size,
limit, options);
sent += m;
+ tosend -= m;
targ->count = sent;
}
}
@@ -762,7 +875,7 @@ D("start");
}
}
- gettimeofday(&targ->toc, NULL);
+ clock_gettime(CLOCK_REALTIME_PRECISE, &targ->toc);
targ->completed = 1;
targ->count = sent;
@@ -785,7 +898,7 @@ receive_pcap(u_char *user, const struct pcap_pkthdr * h,
}
static int
-receive_packets(struct netmap_ring *ring, u_int limit, int skip_payload)
+receive_packets(struct netmap_ring *ring, u_int limit, int dump)
{
u_int cur, rx;
@@ -796,8 +909,9 @@ receive_packets(struct netmap_ring *ring, u_int limit, int skip_payload)
struct netmap_slot *slot = &ring->slot[cur];
char *p = NETMAP_BUF(ring, slot->buf_idx);
- if (!skip_payload)
- check_payload(p, slot->len);
+ slot->flags = OPT_INDIRECT; // XXX
+ if (dump)
+ dump_payload(p, slot->len, ring, cur);
cur = NETMAP_RING_NEXT(ring, cur);
}
@@ -834,7 +948,7 @@ receiver_body(void *data)
}
/* main loop, exit after 1s silence */
- gettimeofday(&targ->tic, NULL);
+ clock_gettime(CLOCK_REALTIME_PRECISE, &targ->tic);
if (targ->g->dev_type == DEV_PCAP) {
while (!targ->cancel) {
/* XXX should we poll ? */
@@ -849,11 +963,12 @@ receiver_body(void *data)
targ->count++;
}
} else {
+ int dump = targ->g->options & OPT_DUMP;
while (!targ->cancel) {
/* Once we started to receive packets, wait at most 1 seconds
before quitting. */
- if (poll(fds, 1, 1 * 1000) <= 0 && targ->g->forever == 0) {
- gettimeofday(&targ->toc, NULL);
+ if (poll(fds, 1, 1 * 1000) <= 0 && !targ->g->forever) {
+ clock_gettime(CLOCK_REALTIME_PRECISE, &targ->toc);
targ->toc.tv_sec -= 1; /* Subtract timeout time. */
break;
}
@@ -865,8 +980,7 @@ receiver_body(void *data)
if (rxring->avail == 0)
continue;
- m = receive_packets(rxring, targ->g->burst,
- SKIP_PAYLOAD);
+ m = receive_packets(rxring, targ->g->burst, dump);
received += m;
}
targ->count = received;
@@ -1085,11 +1199,13 @@ main_thread(struct glob_arg *g)
timerclear(&tic);
timerclear(&toc);
for (i = 0; i < g->nthreads; i++) {
+ struct timespec t_tic, t_toc;
/*
* Join active threads, unregister interfaces and close
* file descriptors.
*/
- pthread_join(targs[i].thread, NULL);
+ if (targs[i].used)
+ pthread_join(targs[i].thread, NULL);
close(targs[i].fd);
if (targs[i].completed == 0)
@@ -1100,10 +1216,12 @@ main_thread(struct glob_arg *g)
* how long it took to send all the packets.
*/
count += targs[i].count;
- if (!timerisset(&tic) || timercmp(&targs[i].tic, &tic, <))
- tic = targs[i].tic;
- if (!timerisset(&toc) || timercmp(&targs[i].toc, &toc, >))
- toc = targs[i].toc;
+ t_tic = timeval2spec(&tic);
+ t_toc = timeval2spec(&toc);
+ if (!timerisset(&tic) || timespec_ge(&targs[i].tic, &t_tic))
+ tic = timespec2val(&targs[i].tic);
+ if (!timerisset(&toc) || timespec_ge(&targs[i].toc, &t_toc))
+ toc = timespec2val(&targs[i].toc);
}
/* print output. */
@@ -1115,7 +1233,6 @@ main_thread(struct glob_arg *g)
rx_output(count, delta_t);
if (g->dev_type == DEV_NETMAP) {
- ioctl(g->main_fd, NIOCUNREGIF, NULL); // XXX deprecated
munmap(g->mmap_addr, g->mmap_size);
close(g->main_fd);
}
@@ -1224,9 +1341,11 @@ main(int arc, char **argv)
g.burst = 512; // default
g.nthreads = 1;
g.cpus = 1;
+ g.forever = 1;
+ g.tx_rate = 0;
while ( (ch = getopt(arc, argv,
- "a:f:n:i:t:r:l:d:s:D:S:b:c:o:p:PT:w:Wv")) != -1) {
+ "a:f:n:i:It:r:l:d:s:D:S:b:c:o:p:PT:w:WvR:X")) != -1) {
struct sf *fn;
switch(ch) {
@@ -1266,6 +1385,10 @@ main(int arc, char **argv)
g.dev_type = DEV_NETMAP;
break;
+ case 'I':
+ g.options |= OPT_INDIRECT; /* XXX use indirect buffer */
+ break;
+
case 't': /* send, deprecated */
D("-t deprecated, please use -f tx -n %s", optarg);
g.td_body = sender_body;
@@ -1298,8 +1421,8 @@ main(int arc, char **argv)
wait_link = atoi(optarg);
break;
- case 'W':
- g.forever = 1; /* do not exit rx even with no traffic */
+ case 'W': /* XXX changed default */
+ g.forever = 0; /* do not exit rx even with no traffic */
break;
case 'b': /* burst */
@@ -1325,6 +1448,12 @@ main(int arc, char **argv)
break;
case 'v':
verbose++;
+ break;
+ case 'R':
+ g.tx_rate = atoi(optarg);
+ break;
+ case 'X':
+ g.options |= OPT_DUMP;
}
}
@@ -1467,12 +1596,30 @@ main(int arc, char **argv)
}
if (g.options) {
- D("special options:%s%s%s%s\n",
+ D("--- SPECIAL OPTIONS:%s%s%s%s%s\n",
g.options & OPT_PREFETCH ? " prefetch" : "",
g.options & OPT_ACCESS ? " access" : "",
g.options & OPT_MEMCPY ? " memcpy" : "",
+ g.options & OPT_INDIRECT ? " indirect" : "",
g.options & OPT_COPY ? " copy" : "");
}
+
+ if (g.tx_rate == 0) {
+ g.tx_period.tv_sec = 0;
+ g.tx_period.tv_nsec = 0;
+ } else if (g.tx_rate == 1) {
+ g.tx_period.tv_sec = 1;
+ g.tx_period.tv_nsec = 0;
+ } else {
+ g.tx_period.tv_sec = 0;
+ g.tx_period.tv_nsec = (1e9 / g.tx_rate) * g.burst;
+ if (g.tx_period.tv_nsec > 1000000000) {
+ g.tx_period.tv_sec = g.tx_period.tv_nsec / 1000000000;
+ g.tx_period.tv_nsec = g.tx_period.tv_nsec % 1000000000;
+ }
+ }
+ D("Sending %d packets every %d.%09d ns",
+ g.burst, (int)g.tx_period.tv_sec, (int)g.tx_period.tv_nsec);
/* Wait for PHY reset. */
D("Wait %d secs for phy reset", wait_link);
sleep(wait_link);
diff --git a/tools/tools/netmap/vale-ctl.c b/tools/tools/netmap/vale-ctl.c
new file mode 100644
index 0000000..0a478ba
--- /dev/null
+++ b/tools/tools/netmap/vale-ctl.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013 Michio Honda. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $FreeBSD$ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <inttypes.h> /* PRI* macros */
+#include <string.h> /* strcmp */
+#include <fcntl.h> /* open */
+#include <unistd.h> /* close */
+#include <sys/ioctl.h> /* ioctl */
+#include <sys/param.h>
+#include <net/if.h> /* ifreq */
+#include <net/netmap.h>
+#include <net/netmap_user.h>
+#include <libgen.h> /* basename */
+
+/* debug support */
+#define ND(format, ...) do {} while(0)
+#define D(format, ...) \
+ fprintf(stderr, "%s [%d] " format "\n", \
+ __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+static int
+bdg_ctl(const char *name, int nr_cmd, int nr_arg)
+{
+ struct nmreq nmr;
+ int error = 0;
+ int fd = open("/dev/netmap", O_RDWR);
+
+ if (fd == -1) {
+ D("Unable to open /dev/netmap");
+ return -1;
+ }
+
+ bzero(&nmr, sizeof(nmr));
+ nmr.nr_version = NETMAP_API;
+ if (name != NULL) /* might be NULL */
+ strncpy(nmr.nr_name, name, sizeof(nmr.nr_name));
+ nmr.nr_cmd = nr_cmd;
+
+ switch (nr_cmd) {
+ case NETMAP_BDG_ATTACH:
+ case NETMAP_BDG_DETACH:
+ if (nr_arg && nr_arg != NETMAP_BDG_HOST)
+ nr_arg = 0;
+ nmr.nr_arg1 = nr_arg;
+ error = ioctl(fd, NIOCREGIF, &nmr);
+ if (error == -1)
+ D("Unable to %s %s to the bridge", nr_cmd ==
+ NETMAP_BDG_DETACH?"detach":"attach", name);
+ else
+ D("Success to %s %s to the bridge\n", nr_cmd ==
+ NETMAP_BDG_DETACH?"detach":"attach", name);
+ break;
+
+ case NETMAP_BDG_LIST:
+ if (strlen(nmr.nr_name)) { /* name to bridge/port info */
+ error = ioctl(fd, NIOCGINFO, &nmr);
+ if (error)
+ D("Unable to obtain info for %s", name);
+ else
+ D("%s at bridge:%d port:%d", name, nmr.nr_arg1,
+ nmr.nr_arg2);
+ break;
+ }
+
+ /* scan all the bridges and ports */
+ nmr.nr_arg1 = nmr.nr_arg2 = 0;
+ for (; !ioctl(fd, NIOCGINFO, &nmr); nmr.nr_arg2++) {
+ D("bridge:%d port:%d %s", nmr.nr_arg1, nmr.nr_arg2,
+ nmr.nr_name);
+ nmr.nr_name[0] = '\0';
+ }
+
+ break;
+
+ default: /* GINFO */
+ nmr.nr_cmd = nmr.nr_arg1 = nmr.nr_arg2 = 0;
+ error = ioctl(fd, NIOCGINFO, &nmr);
+ if (error)
+ D("Unable to get if info for %s", name);
+ else
+ D("%s: %d queues.", name, nmr.nr_rx_rings);
+ break;
+ }
+ close(fd);
+ return error;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ch, nr_cmd = 0, nr_arg = 0;
+ const char *command = basename(argv[0]);
+ char *name = NULL;
+
+ if (argc != 3 && argc != 1 /* list all */ ) {
+usage:
+ fprintf(stderr,
+ "Usage:\n"
+ "%s arguments\n"
+ "\t-g interface interface name to get info\n"
+ "\t-d interface interface name to be detached\n"
+ "\t-a interface interface name to be attached\n"
+ "\t-h interface interface name to be attached with the host stack\n"
+ "\t-l list all or specified bridge's interfaces\n"
+ "", command);
+ return 0;
+ }
+
+ while ((ch = getopt(argc, argv, "d:a:h:g:l:")) != -1) {
+ switch (ch) {
+ default:
+ fprintf(stderr, "bad option %c %s", ch, optarg);
+ goto usage;
+ case 'd':
+ nr_cmd = NETMAP_BDG_DETACH;
+ break;
+ case 'a':
+ nr_cmd = NETMAP_BDG_ATTACH;
+ break;
+ case 'h':
+ nr_cmd = NETMAP_BDG_ATTACH;
+ nr_arg = NETMAP_BDG_HOST;
+ break;
+ case 'g':
+ nr_cmd = 0;
+ break;
+ case 'l':
+ nr_cmd = NETMAP_BDG_LIST;
+ break;
+ }
+ name = optarg;
+ }
+ if (argc == 1)
+ nr_cmd = NETMAP_BDG_LIST;
+ bdg_ctl(name, nr_cmd, nr_arg);
+ return 0;
+}
diff --git a/tools/tools/notescheck/notescheck.py b/tools/tools/notescheck/notescheck.py
index 35915b9..8e23387 100644
--- a/tools/tools/notescheck/notescheck.py
+++ b/tools/tools/notescheck/notescheck.py
@@ -93,7 +93,7 @@ class Option:
return
if global_platform in self.defines:
- # If the device is defined globally ans is never tested, whine.
+ # If the device is defined globally and is never tested, whine.
if len(self.tests) == 0:
print('WARN: %s is defined globally but never tested' % \
(self.title()))
diff --git a/tools/tools/pciroms/pciroms.c b/tools/tools/pciroms/pciroms.c
index 460c7ef..9919c20 100644
--- a/tools/tools/pciroms/pciroms.c
+++ b/tools/tools/pciroms/pciroms.c
@@ -10,25 +10,18 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bruce M. Simpson.
- * 4. Neither the name of Bruce M. Simpson nor the names of
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY BRUCE M. SIMPSON AND AFFILIATES
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
*
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#include <sys/cdefs.h>
diff --git a/tools/tools/sysbuild/sysbuild.sh b/tools/tools/sysbuild/sysbuild.sh
index 2f91e86..0b39fe2 100644
--- a/tools/tools/sysbuild/sysbuild.sh
+++ b/tools/tools/sysbuild/sysbuild.sh
@@ -91,7 +91,7 @@ SERCONS=false
PORTS_WE_WANT='
'
-PORTS_OPTS="BATCH=YES MAKE_IDEA=YES A4=yes"
+PORTS_OPTS="BATCH=YES A4=yes"
CONFIGFILES='
'
diff --git a/tools/tools/sysdoc/sysdoc.sh b/tools/tools/sysdoc/sysdoc.sh
index c428174..b07c53d 100644
--- a/tools/tools/sysdoc/sysdoc.sh
+++ b/tools/tools/sysdoc/sysdoc.sh
@@ -88,7 +88,7 @@ EOF
# tunables in our tunables.mdoc file and generate
# the final 'inner circle' of our manual page.
markup_create() {
- sort < _names | \
+ sort -u < _names | \
xargs -n 1 /bin/sh ./sysctl.sh \
> markup.file \
2> tunables.TODO
@@ -238,9 +238,13 @@ if [ -z "$LOCATION" ] ;
&& for x in `find $LOCATION -name '*.kld'` \
$LOCATION/kernel; \
do nm $x | \
- grep ' sysctl___' | uniq | \
- sed 's/sysctl___//g' | sed 's/_/./g' | \
- awk {'print $3'} > _names;
+ sed -n '/sysctl___/ {
+ 's/[\.a-z_]*sysctl___//g'
+ 's/_/./g'
+ p
+ }' | \
+ awk {'print $3'} | \
+ sort -u > _names;
done;
markup_create
page_create
diff --git a/tools/tools/sysdoc/tunables.mdoc b/tools/tools/sysdoc/tunables.mdoc
index 35ef9c0..505c4a7 100644
--- a/tools/tools/sysdoc/tunables.mdoc
+++ b/tools/tools/sysdoc/tunables.mdoc
@@ -1093,6 +1093,13 @@ line programs.
kern.quantum
---
+kern.random.adaptors
+str
+
+Displays registered PRNG adaptors.
+This is a read-only variable.
+
+---
kern.random.sys.burst
---
@@ -2259,9 +2266,6 @@ Displays the number of swap devices available
to the system. This is a read-only variable.
---
-vm.pageout_algorithm
-
----
vm.pageout_full_stats_interval
---
diff --git a/tools/tools/umastat/umastat.c b/tools/tools/umastat/umastat.c
index 3a43c37..758195e 100644
--- a/tools/tools/umastat/umastat.c
+++ b/tools/tools/umastat/umastat.c
@@ -79,7 +79,7 @@ kread(kvm_t *kvm, void *kvm_pointer, void *address, size_t size,
}
static int
-kread_string(kvm_t *kvm, void *kvm_pointer, char *buffer, int buflen)
+kread_string(kvm_t *kvm, const void *kvm_pointer, char *buffer, int buflen)
{
ssize_t ret;
int i;
@@ -151,7 +151,7 @@ uma_print_keg_flags(struct uma_keg *ukp, const char *spaces)
if (ukp->uk_flags & flaginfo[i].fi_flag) {
if (count++ > 0)
printf(" | ");
- printf(flaginfo[i].fi_name);
+ printf("%s", flaginfo[i].fi_name);
}
}
diff --git a/tools/tools/usbtest/Makefile b/tools/tools/usbtest/Makefile
new file mode 100644
index 0000000..1cc0c83
--- /dev/null
+++ b/tools/tools/usbtest/Makefile
@@ -0,0 +1,40 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+PROG= usbtest
+MAN=
+SRCS+= usbtest.c
+SRCS+= usb_msc_test.c
+SRCS+= usb_modem_test.c
+SRCS+= usb_control_ep_test.c
+
+LDADD+= -lusb
+
+WARNS= 3
+
+CFLAGS+= -I ${.CURDIR}/../../../sys/dev/usb/gadget
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/usbtest/usb_control_ep_test.c b/tools/tools/usbtest/usb_control_ep_test.c
new file mode 100644
index 0000000..87c5fc1
--- /dev/null
+++ b/tools/tools/usbtest/usb_control_ep_test.c
@@ -0,0 +1,673 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2007-2010 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <err.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <libusb20.h>
+#include <libusb20_desc.h>
+
+#include <dev/usb/usb_endian.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usb_cdc.h>
+
+#include "usbtest.h"
+
+static void
+set_ctrl_ep_fail(int bus, int dev, int ds_fail, int ss_fail)
+{
+ int error;
+
+ error = sysctlbyname("hw.usb.ctrl_bus_fail", NULL, NULL,
+ &bus, sizeof(bus));
+ if (error != 0)
+ goto emissing;
+
+ error = sysctlbyname("hw.usb.ctrl_dev_fail", NULL, NULL,
+ &dev, sizeof(dev));
+ if (error != 0)
+ goto emissing;
+
+ error = sysctlbyname("hw.usb.ctrl_ds_fail", NULL, NULL,
+ &ds_fail, sizeof(ds_fail));
+ if (error != 0)
+ goto emissing;
+
+ error = sysctlbyname("hw.usb.ctrl_ss_fail", NULL, NULL,
+ &ss_fail, sizeof(ss_fail));
+ if (error != 0)
+ goto emissing;
+ return;
+
+emissing:
+ printf("Cannot set USB sysctl, missing USB_REQ_DEBUG option?\n");
+}
+
+void
+usb_control_ep_error_test(uint16_t vid, uint16_t pid)
+{
+ struct LIBUSB20_CONTROL_SETUP_DECODED req;
+ struct libusb20_device *pdev;
+ uint8_t buffer[256];
+ int error;
+ int fail = 0;
+ int bus;
+ int dev;
+ int cfg;
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ error = libusb20_dev_open(pdev, 0);
+ if (error) {
+ printf("Could not open USB device\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+
+ bus = libusb20_dev_get_bus_number(pdev);
+ dev = libusb20_dev_get_address(pdev);
+
+ for (cfg = 0; cfg != 255; cfg++) {
+
+ LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);
+ req.bmRequestType = 0x80; /* read */
+ req.bRequest = 0x06; /* descriptor */
+ req.wValue = 0x0200 | cfg; /* config descriptor */
+ req.wIndex = 0;
+ req.wLength = 255;
+
+ printf("Test #%d.1/3 ...\n", cfg);
+
+ set_ctrl_ep_fail(-1,-1,0,0);
+
+ error = libusb20_dev_request_sync(pdev, &req, buffer,
+ NULL, 1000, 0);
+ if (error != 0) {
+ printf("Last configuration index is: %d\n", cfg - 1);
+ break;
+ }
+
+ printf("Test #%d.2/3 ...\n", cfg);
+
+ set_ctrl_ep_fail(bus,dev,1,1);
+
+ error = libusb20_dev_request_sync(pdev, &req, buffer,
+ NULL, 1000, 0);
+
+ set_ctrl_ep_fail(-1,-1,0,0);
+
+ error = libusb20_dev_request_sync(pdev, &req, buffer,
+ NULL, 1000, 0);
+ if (error != 0) {
+ printf("Cannot fetch descriptor (unexpected)\n");
+ fail++;
+ }
+
+ printf("Test #%d.3/3 ...\n", cfg);
+
+ set_ctrl_ep_fail(bus,dev,0,1);
+
+ error = libusb20_dev_request_sync(pdev, &req, buffer,
+ NULL, 1000, 0);
+
+ set_ctrl_ep_fail(-1,-1,0,0);
+
+ error = libusb20_dev_request_sync(pdev, &req, buffer,
+ NULL, 1000, 0);
+ if (error != 0) {
+ printf("Cannot fetch descriptor (unexpected)\n");
+ fail++;
+ }
+ }
+
+ libusb20_dev_close(pdev);
+ libusb20_dev_free(pdev);
+
+ printf("Test completed detecting %d failures\nDone\n\n", fail);
+}
+
+void
+usb_get_string_desc_test(uint16_t vid, uint16_t pid)
+{
+ struct libusb20_device *pdev;
+ uint32_t x;
+ uint32_t y;
+ uint32_t valid;
+ uint8_t *buf;
+ int error;
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ error = libusb20_dev_open(pdev, 0);
+ if (error) {
+ printf("Could not open USB device\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ buf = malloc(256);
+ if (buf == NULL) {
+ printf("Cannot allocate memory\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ valid = 0;
+
+ printf("Starting string descriptor test for "
+ "VID=0x%04x PID=0x%04x\n", vid, pid);
+
+ for (x = 0; x != 256; x++) {
+
+ if (libusb20_dev_check_connected(pdev) != 0) {
+ printf("Device disconnected\n");
+ break;
+ }
+ printf("%d .. ", (int)x);
+
+ fflush(stdout);
+
+ error = libusb20_dev_req_string_simple_sync(pdev, x, buf, 255);
+
+ if (error == 0) {
+ printf("\nINDEX=%d, STRING='%s' (Default language)\n", (int)x, buf);
+ fflush(stdout);
+ } else {
+ continue;
+ }
+
+ valid = 0;
+
+ for (y = 0; y != 65536; y++) {
+
+ if (libusb20_dev_check_connected(pdev) != 0) {
+ printf("Device disconnected\n");
+ break;
+ }
+ error = libusb20_dev_req_string_sync(pdev, x, y, buf, 256);
+ if (error == 0)
+ valid++;
+ }
+
+ printf("String at INDEX=%d responds to %d "
+ "languages\n", (int)x, (int)valid);
+ }
+
+ printf("\nDone\n");
+
+ free(buf);
+
+ libusb20_dev_free(pdev);
+}
+
+void
+usb_port_reset_test(uint16_t vid, uint16_t pid, uint32_t duration)
+{
+ struct timeval sub_tv;
+ struct timeval ref_tv;
+ struct timeval res_tv;
+
+ struct libusb20_device *pdev;
+
+ int error;
+ int iter;
+ int errcnt;
+
+ time_t last_sec;
+
+ /* sysctl() - no set config */
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ error = libusb20_dev_open(pdev, 0);
+ if (error) {
+ libusb20_dev_free(pdev);
+ printf("Could not open USB device\n");
+ return;
+ }
+ iter = 0;
+
+ errcnt = 0;
+
+ gettimeofday(&ref_tv, 0);
+
+ last_sec = ref_tv.tv_sec;
+
+ while (1) {
+
+ gettimeofday(&sub_tv, 0);
+
+ if (last_sec != sub_tv.tv_sec) {
+
+ printf("STATUS: ID=%u, ERR=%u\n",
+ (int)iter, (int)errcnt);
+
+ fflush(stdout);
+
+ last_sec = sub_tv.tv_sec;
+ }
+ timersub(&sub_tv, &ref_tv, &res_tv);
+
+ if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration))
+ break;
+
+ if (libusb20_dev_reset(pdev)) {
+ errcnt++;
+ usleep(50000);
+ }
+ if (libusb20_dev_check_connected(pdev) != 0) {
+ printf("Device disconnected\n");
+ break;
+ }
+ iter++;
+ }
+
+ libusb20_dev_reset(pdev);
+
+ libusb20_dev_free(pdev);
+}
+
+void
+usb_set_config_test(uint16_t vid, uint16_t pid, uint32_t duration)
+{
+ struct libusb20_device *pdev;
+ struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+ int x;
+ int error;
+ int failed;
+ int exp;
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ error = libusb20_dev_open(pdev, 0);
+ if (error) {
+ printf("Could not open USB device\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ failed = 0;
+
+ printf("Starting set config test for "
+ "VID=0x%04x PID=0x%04x\n", vid, pid);
+
+ for (x = 255; x > -1; x--) {
+
+ error = libusb20_dev_set_config_index(pdev, x);
+ if (error == 0) {
+ if (x == 255) {
+ printf("Unconfiguring USB device "
+ "was successful\n");
+ } else {
+ printf("Setting configuration %d "
+ "was successful\n", x);
+ }
+ } else {
+ failed++;
+ }
+ }
+
+ ddesc = libusb20_dev_get_device_desc(pdev);
+ if (ddesc != NULL)
+ exp = ddesc->bNumConfigurations + 1;
+ else
+ exp = 1;
+
+ printf("\n\n"
+ "Set configuration summary\n"
+ "Valid count: %d/%d %s\n"
+ "Failed count: %d\n",
+ 256 - failed, exp,
+ (exp == (256 - failed)) ? "(expected)" : "(unexpected)",
+ failed);
+
+ libusb20_dev_free(pdev);
+}
+
+void
+usb_get_descriptor_test(uint16_t vid, uint16_t pid, uint32_t duration)
+{
+ struct libusb20_device *pdev;
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ libusb20_dev_free(pdev);
+}
+
+void
+usb_suspend_resume_test(uint16_t vid, uint16_t pid, uint32_t duration)
+{
+ struct timeval sub_tv;
+ struct timeval ref_tv;
+ struct timeval res_tv;
+
+ struct libusb20_device *pdev;
+
+ time_t last_sec;
+
+ int iter;
+ int error;
+ int ptimo;
+ int errcnt;
+ int power_old;
+
+ ptimo = 1; /* second(s) */
+
+ error = sysctlbyname("hw.usb.power_timeout", NULL, NULL,
+ &ptimo, sizeof(ptimo));
+
+ if (error != 0) {
+ printf("WARNING: Could not set power "
+ "timeout to 1 (error=%d) \n", errno);
+ }
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ error = libusb20_dev_open(pdev, 0);
+ if (error) {
+ printf("Could not open USB device\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ power_old = libusb20_dev_get_power_mode(pdev);
+
+ printf("Starting suspend and resume "
+ "test for VID=0x%04x PID=0x%04x\n", vid, pid);
+
+ iter = 0;
+ errcnt = 0;
+
+ gettimeofday(&ref_tv, 0);
+
+ last_sec = ref_tv.tv_sec;
+
+ while (1) {
+
+ if (libusb20_dev_check_connected(pdev) != 0) {
+ printf("Device disconnected\n");
+ break;
+ }
+ gettimeofday(&sub_tv, 0);
+
+ if (last_sec != sub_tv.tv_sec) {
+
+ printf("STATUS: ID=%u, ERR=%u\n",
+ (int)iter, (int)errcnt);
+
+ fflush(stdout);
+
+ last_sec = sub_tv.tv_sec;
+ }
+ timersub(&sub_tv, &ref_tv, &res_tv);
+
+ if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration))
+ break;
+
+ error = libusb20_dev_set_power_mode(pdev, (iter & 1) ?
+ LIBUSB20_POWER_ON : LIBUSB20_POWER_SAVE);
+
+ if (error)
+ errcnt++;
+
+ /* wait before switching power mode */
+ usleep(4100000 +
+ (((uint32_t)usb_ts_rand_noise()) % 2000000U));
+
+ iter++;
+ }
+
+ /* restore default power mode */
+ libusb20_dev_set_power_mode(pdev, power_old);
+
+ libusb20_dev_free(pdev);
+}
+
+void
+usb_set_and_clear_stall_test(uint16_t vid, uint16_t pid)
+{
+ struct libusb20_device *pdev;
+ struct libusb20_transfer *pxfer;
+
+ int iter;
+ int error;
+ int errcnt;
+ int ep;
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ error = libusb20_dev_open(pdev, 1);
+ if (error) {
+ printf("Could not open USB device\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ printf("Starting set and clear stall test "
+ "for VID=0x%04x PID=0x%04x\n", vid, pid);
+
+ iter = 0;
+ errcnt = 0;
+
+ for (ep = 2; ep != 32; ep++) {
+
+ struct LIBUSB20_CONTROL_SETUP_DECODED setup_set_stall;
+ struct LIBUSB20_CONTROL_SETUP_DECODED setup_get_status;
+
+ uint8_t epno = ((ep / 2) | ((ep & 1) << 7));
+ uint8_t buf[1];
+
+ LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup_set_stall);
+ setup_set_stall.bmRequestType = 0x02; /* write endpoint */
+ setup_set_stall.bRequest = 0x03; /* set feature */
+ setup_set_stall.wValue = 0x00; /* UF_ENDPOINT_HALT */
+ setup_set_stall.wIndex = epno;
+ setup_set_stall.wLength = 0;
+
+ LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup_get_status);
+ setup_get_status.bmRequestType = 0x82; /* read endpoint */
+ setup_get_status.bRequest = 0x00; /* get status */
+ setup_get_status.wValue = 0x00;
+ setup_get_status.wIndex = epno;
+ setup_get_status.wLength = 1;
+
+ if (libusb20_dev_check_connected(pdev) != 0) {
+ printf("Device disconnected\n");
+ break;
+ }
+ pxfer = libusb20_tr_get_pointer(pdev, 0);
+
+ error = libusb20_tr_open(pxfer, 1, 1, epno);
+
+ if (error != 0) {
+ printf("Endpoint 0x%02x does not exist "
+ "in current setting. (%s, ignored)\n",
+ epno, libusb20_strerror(error));
+ continue;
+ }
+ printf("Stalling endpoint 0x%02x\n", epno);
+
+ /* set stall */
+ error = libusb20_dev_request_sync(pdev,
+ &setup_set_stall, NULL, NULL, 250, 0);
+
+ if (error != 0) {
+ printf("Endpoint 0x%02x does not allow "
+ "setting of stall. (%s)\n",
+ epno, libusb20_strerror(error));
+ errcnt++;
+ }
+ /* get EP status */
+ buf[0] = 0;
+ error = libusb20_dev_request_sync(pdev,
+ &setup_get_status, buf, NULL, 250, 0);
+
+ if (error != 0) {
+ printf("Endpoint 0x%02x does not allow "
+ "reading status. (%s)\n",
+ epno, libusb20_strerror(error));
+ errcnt++;
+ } else {
+ if (!(buf[0] & 1)) {
+ printf("Endpoint 0x%02x status is "
+ "not set to stalled\n", epno);
+ errcnt++;
+ }
+ }
+
+ buf[0] = 0;
+ error = libusb20_tr_bulk_intr_sync(pxfer, buf, 1, NULL, 250);
+ if (error != LIBUSB20_TRANSFER_STALL) {
+ printf("Endpoint 0x%02x does not appear to "
+ "have stalled. Missing stall PID!\n", epno);
+ errcnt++;
+ }
+ printf("Unstalling endpoint 0x%02x\n", epno);
+
+ libusb20_tr_clear_stall_sync(pxfer);
+
+ /* get EP status */
+ buf[0] = 0;
+ error = libusb20_dev_request_sync(pdev,
+ &setup_get_status, buf, NULL, 250, 0);
+
+ if (error != 0) {
+ printf("Endpoint 0x%02x does not allow "
+ "reading status. (%s)\n",
+ epno, libusb20_strerror(error));
+ errcnt++;
+ } else {
+ if (buf[0] & 1) {
+ printf("Endpoint 0x%02x status is "
+ "still stalled\n", epno);
+ errcnt++;
+ }
+ }
+
+ libusb20_tr_close(pxfer);
+ iter++;
+ }
+
+ libusb20_dev_free(pdev);
+
+ printf("\n"
+ "Test summary\n"
+ "============\n"
+ "Endpoints tested: %d\n"
+ "Errors: %d\n", iter, errcnt);
+}
+
+void
+usb_set_alt_interface_test(uint16_t vid, uint16_t pid)
+{
+ struct libusb20_device *pdev;
+ struct libusb20_config *config;
+
+ int iter;
+ int error;
+ int errcnt;
+ int n;
+ int m;
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ printf("Starting set alternate setting test "
+ "for VID=0x%04x PID=0x%04x\n", vid, pid);
+
+ config = libusb20_dev_alloc_config(pdev,
+ libusb20_dev_get_config_index(pdev));
+ if (config == NULL) {
+ printf("Could not get configuration descriptor\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ iter = 0;
+ errcnt = 0;
+
+ for (n = 0; n != config->num_interface; n++) {
+ /* detach kernel driver */
+ libusb20_dev_detach_kernel_driver(pdev, n);
+
+ error = libusb20_dev_open(pdev, 0);
+ if (error)
+ printf("ERROR could not open device\n");
+
+ /* Try the alternate settings */
+ for (m = 0; m != config->interface[n].num_altsetting; m++) {
+
+ iter++;
+
+ if (libusb20_dev_set_alt_index(pdev, n, m + 1)) {
+ printf("ERROR on interface %d alt %d\n", n, m + 1);
+ errcnt++;
+ }
+ }
+
+ /* Restore to default */
+
+ iter++;
+
+ if (libusb20_dev_set_alt_index(pdev, n, 0)) {
+ printf("ERROR on interface %d alt %d\n", n, 0);
+ errcnt++;
+ }
+ libusb20_dev_close(pdev);
+ }
+
+ libusb20_dev_free(pdev);
+
+ printf("\n"
+ "Test summary\n"
+ "============\n"
+ "Interfaces tested: %d\n"
+ "Errors: %d\n", iter, errcnt);
+}
diff --git a/tools/tools/usbtest/usb_modem_test.c b/tools/tools/usbtest/usb_modem_test.c
new file mode 100644
index 0000000..74406fc
--- /dev/null
+++ b/tools/tools/usbtest/usb_modem_test.c
@@ -0,0 +1,585 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2007-2010 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <err.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <libusb20.h>
+#include <libusb20_desc.h>
+
+#include <dev/usb/usb_endian.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usb_cdc.h>
+
+#include "usbtest.h"
+
+static struct modem {
+ struct libusb20_transfer *xfer_in;
+ struct libusb20_transfer *xfer_out;
+ struct libusb20_device *usb_dev;
+
+ struct bps rx_bytes;
+ struct bps tx_bytes;
+ uint32_t c0;
+ uint32_t c1;
+ uint32_t out_state;
+ uint32_t in_last;
+ uint32_t in_synced;
+ uint32_t duration;
+ uint32_t errors;
+
+ uint8_t use_vendor_specific;
+ uint8_t loop_data;
+ uint8_t modem_at_mode;
+ uint8_t data_stress_test;
+ uint8_t control_ep_test;
+ uint8_t usb_iface;
+ uint8_t random_tx_length;
+ uint8_t random_tx_delay;
+
+} modem;
+
+static void
+set_defaults(struct modem *p)
+{
+ memset(p, 0, sizeof(*p));
+
+ p->data_stress_test = 1;
+ p->control_ep_test = 1;
+ p->duration = 60; /* seconds */
+}
+
+void
+do_bps(const char *desc, struct bps *bps, uint32_t len)
+{
+ bps->bytes += len;
+}
+
+static void
+modem_out_state(uint8_t *buf)
+{
+ if (modem.modem_at_mode) {
+ switch (modem.out_state & 3) {
+ case 0:
+ *buf = 'A';
+ break;
+ case 1:
+ *buf = 'T';
+ break;
+ case 2:
+ *buf = '\r';
+ break;
+ default:
+ *buf = '\n';
+ modem.c0++;
+ break;
+ }
+ modem.out_state++;
+ } else {
+ *buf = modem.out_state;
+ modem.out_state++;
+ modem.out_state %= 255;
+ }
+}
+
+static void
+modem_in_state(uint8_t buf, uint32_t counter)
+{
+ if ((modem.in_last == 'O') && (buf == 'K')) {
+ modem.c1++;
+ modem.in_last = buf;
+ } else if (buf == modem.in_last) {
+ modem.c1++;
+ modem.in_last++;
+ modem.in_last %= 255;
+ if (modem.in_synced == 0) {
+ if (modem.errors < 64) {
+ printf("Got sync\n");
+ }
+ modem.in_synced = 1;
+ }
+ } else {
+ if (modem.in_synced) {
+ if (modem.errors < 64) {
+ printf("Lost sync @ %d, 0x%02x != 0x%02x\n",
+ counter % 512, buf, modem.in_last);
+ }
+ modem.in_synced = 0;
+ modem.errors++;
+ }
+ modem.in_last = buf;
+ modem.in_last++;
+ modem.in_last %= 255;
+ }
+}
+
+static void
+modem_write(uint8_t *buf, uint32_t len)
+{
+ uint32_t n;
+
+ for (n = 0; n != len; n++) {
+ modem_out_state(buf + n);
+ }
+
+ do_bps("transmitted", &modem.tx_bytes, len);
+}
+
+static void
+modem_read(uint8_t *buf, uint32_t len)
+{
+ uint32_t n;
+
+ for (n = 0; n != len; n++) {
+ modem_in_state(buf[n], n);
+ }
+
+ do_bps("received", &modem.rx_bytes, len);
+}
+
+static void
+usb_modem_control_ep_test(struct modem *p, uint32_t duration, uint8_t flag)
+{
+ struct timeval sub_tv;
+ struct timeval ref_tv;
+ struct timeval res_tv;
+ struct LIBUSB20_CONTROL_SETUP_DECODED setup;
+ struct usb_cdc_abstract_state ast;
+ struct usb_cdc_line_state ls;
+ uint16_t feature = UCDC_ABSTRACT_STATE;
+ uint16_t state = UCDC_DATA_MULTIPLEXED;
+ uint8_t iface_no;
+ uint8_t buf[4];
+ int id = 0;
+ int iter = 0;
+
+ time_t last_sec;
+
+ iface_no = p->usb_iface - 1;
+
+ gettimeofday(&ref_tv, 0);
+
+ last_sec = ref_tv.tv_sec;
+
+ printf("\nTest=%d\n", (int)flag);
+
+ while (1) {
+
+ gettimeofday(&sub_tv, 0);
+
+ if (last_sec != sub_tv.tv_sec) {
+
+ printf("STATUS: ID=%u, COUNT=%u tests/sec ERR=%u\n",
+ (int)id,
+ (int)iter,
+ (int)p->errors);
+
+ fflush(stdout);
+
+ last_sec = sub_tv.tv_sec;
+
+ id++;
+
+ iter = 0;
+ }
+ timersub(&sub_tv, &ref_tv, &res_tv);
+
+ if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration))
+ break;
+
+ LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup);
+
+ if (flag & 1) {
+ setup.bmRequestType = UT_READ_CLASS_INTERFACE;
+ setup.bRequest = 0x03;
+ setup.wValue = 0x0001;
+ setup.wIndex = iface_no;
+ setup.wLength = 0x0002;
+
+ if (libusb20_dev_request_sync(p->usb_dev, &setup, buf, NULL, 250, 0)) {
+ p->errors++;
+ }
+ }
+ if (flag & 2) {
+ setup.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ setup.bRequest = UCDC_SET_COMM_FEATURE;
+ setup.wValue = feature;
+ setup.wIndex = iface_no;
+ setup.wLength = UCDC_ABSTRACT_STATE_LENGTH;
+ USETW(ast.wState, state);
+
+ if (libusb20_dev_request_sync(p->usb_dev, &setup, &ast, NULL, 250, 0)) {
+ p->errors++;
+ }
+ }
+ if (flag & 4) {
+ USETDW(ls.dwDTERate, 115200);
+ ls.bCharFormat = UCDC_STOP_BIT_1;
+ ls.bParityType = UCDC_PARITY_NONE;
+ ls.bDataBits = 8;
+
+ setup.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ setup.bRequest = UCDC_SET_LINE_CODING;
+ setup.wValue = 0;
+ setup.wIndex = iface_no;
+ setup.wLength = sizeof(ls);
+
+ if (libusb20_dev_request_sync(p->usb_dev, &setup, &ls, NULL, 250, 0)) {
+ p->errors++;
+ }
+ }
+ iter++;
+ }
+
+ printf("\nModem control endpoint test done!\n");
+}
+
+static void
+usb_modem_data_stress_test(struct modem *p, uint32_t duration)
+{
+ struct timeval sub_tv;
+ struct timeval ref_tv;
+ struct timeval res_tv;
+
+ time_t last_sec;
+
+ uint8_t in_pending = 0;
+ uint8_t in_ready = 0;
+ uint8_t out_pending = 0;
+
+ uint32_t id = 0;
+
+ uint32_t in_max;
+ uint32_t out_max;
+ uint32_t io_max;
+
+ uint8_t *in_buffer = 0;
+ uint8_t *out_buffer = 0;
+
+ gettimeofday(&ref_tv, 0);
+
+ last_sec = ref_tv.tv_sec;
+
+ printf("\n");
+
+ in_max = libusb20_tr_get_max_total_length(p->xfer_in);
+ out_max = libusb20_tr_get_max_total_length(p->xfer_out);
+
+ /* get the smallest buffer size and use that */
+ io_max = (in_max < out_max) ? in_max : out_max;
+
+ if (in_max != out_max)
+ printf("WARNING: Buffer sizes are un-equal: %u vs %u\n", in_max, out_max);
+
+ in_buffer = malloc(io_max);
+ if (in_buffer == NULL)
+ goto fail;
+
+ out_buffer = malloc(io_max);
+ if (out_buffer == NULL)
+ goto fail;
+
+ while (1) {
+
+ gettimeofday(&sub_tv, 0);
+
+ if (last_sec != sub_tv.tv_sec) {
+
+ printf("STATUS: ID=%u, RX=%u bytes/sec, TX=%u bytes/sec, ERR=%d\n",
+ (int)id,
+ (int)p->rx_bytes.bytes,
+ (int)p->tx_bytes.bytes,
+ (int)p->errors);
+
+ p->rx_bytes.bytes = 0;
+ p->tx_bytes.bytes = 0;
+
+ fflush(stdout);
+
+ last_sec = sub_tv.tv_sec;
+
+ id++;
+ }
+ timersub(&sub_tv, &ref_tv, &res_tv);
+
+ if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration))
+ break;
+
+ libusb20_dev_process(p->usb_dev);
+
+ if (!libusb20_tr_pending(p->xfer_in)) {
+ if (in_pending) {
+ if (libusb20_tr_get_status(p->xfer_in) == 0) {
+ modem_read(in_buffer, libusb20_tr_get_length(p->xfer_in, 0));
+ } else {
+ p->errors++;
+ usleep(10000);
+ }
+ in_pending = 0;
+ in_ready = 1;
+ }
+ if (p->loop_data == 0) {
+ libusb20_tr_setup_bulk(p->xfer_in, in_buffer, io_max, 0);
+ libusb20_tr_start(p->xfer_in);
+ in_pending = 1;
+ in_ready = 0;
+ }
+ }
+ if (!libusb20_tr_pending(p->xfer_out)) {
+
+ uint32_t len;
+ uint32_t dly;
+
+ if (out_pending) {
+ if (libusb20_tr_get_status(p->xfer_out) != 0) {
+ p->errors++;
+ usleep(10000);
+ }
+ }
+ if (p->random_tx_length) {
+ len = ((uint32_t)usb_ts_rand_noise()) % ((uint32_t)io_max);
+ } else {
+ len = io_max;
+ }
+
+ if (p->random_tx_delay) {
+ dly = ((uint32_t)usb_ts_rand_noise()) % 16000U;
+ } else {
+ dly = 0;
+ }
+
+ if (p->loop_data != 0) {
+ if (in_ready != 0) {
+ len = libusb20_tr_get_length(p->xfer_in, 0);
+ memcpy(out_buffer, in_buffer, len);
+ in_ready = 0;
+ } else {
+ len = io_max + 1;
+ }
+ if (!libusb20_tr_pending(p->xfer_in)) {
+ libusb20_tr_setup_bulk(p->xfer_in, in_buffer, io_max, 0);
+ libusb20_tr_start(p->xfer_in);
+ in_pending = 1;
+ }
+ } else {
+ modem_write(out_buffer, len);
+ }
+
+ if (len <= io_max) {
+ libusb20_tr_setup_bulk(p->xfer_out, out_buffer, len, 0);
+
+ if (dly != 0)
+ usleep(dly);
+
+ libusb20_tr_start(p->xfer_out);
+
+ out_pending = 1;
+ }
+ }
+ libusb20_dev_wait_process(p->usb_dev, 500);
+
+ if (libusb20_dev_check_connected(p->usb_dev) != 0) {
+ printf("Device disconnected\n");
+ break;
+ }
+ }
+
+ libusb20_tr_stop(p->xfer_in);
+ libusb20_tr_stop(p->xfer_out);
+
+ printf("\nData stress test done!\n");
+
+fail:
+ if (in_buffer)
+ free(in_buffer);
+ if (out_buffer)
+ free(out_buffer);
+}
+
+static void
+exec_host_modem_test(struct modem *p, uint16_t vid, uint16_t pid)
+{
+ struct libusb20_device *pdev;
+
+ uint8_t ntest = 0;
+ uint8_t x;
+ uint8_t in_ep;
+ uint8_t out_ep;
+ uint8_t iface;
+
+ int error;
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+
+ if (p->use_vendor_specific)
+ find_usb_endpoints(pdev, 255, 255, 255, 0, &iface, &in_ep, &out_ep, 0);
+ else
+ find_usb_endpoints(pdev, 2, 2, 1, 0, &iface, &in_ep, &out_ep, 1);
+
+ if ((in_ep == 0) || (out_ep == 0)) {
+ printf("Could not find USB endpoints\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ printf("Attaching to: %s @ iface %d\n",
+ libusb20_dev_get_desc(pdev), iface);
+
+ if (libusb20_dev_open(pdev, 2)) {
+ printf("Could not open USB device\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ if (libusb20_dev_detach_kernel_driver(pdev, iface)) {
+ printf("WARNING: Could not detach kernel driver\n");
+ }
+ p->xfer_in = libusb20_tr_get_pointer(pdev, 0);
+ error = libusb20_tr_open(p->xfer_in, 65536 / 4, 1, in_ep);
+ if (error) {
+ printf("Could not open USB endpoint %d\n", in_ep);
+ libusb20_dev_free(pdev);
+ return;
+ }
+ p->xfer_out = libusb20_tr_get_pointer(pdev, 1);
+ error = libusb20_tr_open(p->xfer_out, 65536 / 4, 1, out_ep);
+ if (error) {
+ printf("Could not open USB endpoint %d\n", out_ep);
+ libusb20_dev_free(pdev);
+ return;
+ }
+ p->usb_dev = pdev;
+ p->usb_iface = iface;
+ p->errors = 0;
+
+ if (p->control_ep_test)
+ ntest += 7;
+
+ if (p->data_stress_test)
+ ntest += 1;
+
+ if (ntest == 0) {
+ printf("No tests selected\n");
+ } else {
+
+ if (p->control_ep_test) {
+ for (x = 1; x != 8; x++) {
+ usb_modem_control_ep_test(p,
+ (p->duration + ntest - 1) / ntest, x);
+ }
+ }
+ if (p->data_stress_test) {
+ usb_modem_data_stress_test(p,
+ (p->duration + ntest - 1) / ntest);
+ }
+ }
+
+ printf("\nDone\n");
+
+ libusb20_dev_free(pdev);
+}
+
+void
+show_host_modem_test(uint8_t level, uint16_t vid, uint16_t pid, uint32_t duration)
+{
+ uint8_t retval;
+
+ set_defaults(&modem);
+
+ modem.duration = duration;
+
+ while (1) {
+
+ retval = usb_ts_show_menu(level, "Modem Test Parameters",
+ " 1) Execute Data Stress Test: <%s>\n"
+ " 2) Execute Modem Control Endpoint Test: <%s>\n"
+ " 3) Use random transmit length: <%s>\n"
+ " 4) Use random transmit delay: <%s> ms\n"
+ " 5) Use vendor specific interface: <%s>\n"
+ "10) Loop data: <%s>\n"
+ "13) Set test duration: <%d> seconds\n"
+ "20) Reset parameters\n"
+ "30) Start test (VID=0x%04x, PID=0x%04x)\n"
+ "40) Select another device\n"
+ " x) Return to previous menu \n",
+ (modem.data_stress_test ? "YES" : "NO"),
+ (modem.control_ep_test ? "YES" : "NO"),
+ (modem.random_tx_length ? "YES" : "NO"),
+ (modem.random_tx_delay ? "16" : "0"),
+ (modem.use_vendor_specific ? "YES" : "NO"),
+ (modem.loop_data ? "YES" : "NO"),
+ (int)(modem.duration),
+ (int)vid, (int)pid);
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ modem.data_stress_test ^= 1;
+ break;
+ case 2:
+ modem.control_ep_test ^= 1;
+ break;
+ case 3:
+ modem.random_tx_length ^= 1;
+ break;
+ case 4:
+ modem.random_tx_delay ^= 1;
+ break;
+ case 5:
+ modem.use_vendor_specific ^= 1;
+ modem.control_ep_test = 0;
+ break;
+ case 10:
+ modem.loop_data ^= 1;
+ break;
+ case 13:
+ modem.duration = get_integer();
+ break;
+ case 20:
+ set_defaults(&modem);
+ break;
+ case 30:
+ exec_host_modem_test(&modem, vid, pid);
+ break;
+ case 40:
+ show_host_device_selection(level + 1, &vid, &pid);
+ break;
+ default:
+ return;
+ }
+ }
+}
diff --git a/tools/tools/usbtest/usb_msc_test.c b/tools/tools/usbtest/usb_msc_test.c
new file mode 100644
index 0000000..f98b549
--- /dev/null
+++ b/tools/tools/usbtest/usb_msc_test.c
@@ -0,0 +1,1290 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2007-2012 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <err.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <libusb20.h>
+#include <libusb20_desc.h>
+
+#include <dev/usb/usb_endian.h>
+
+#include "usbtest.h"
+
+#include "usb_msc_test.h"
+
+/* Command Block Wrapper */
+typedef struct {
+ uDWord dCBWSignature;
+#define CBWSIGNATURE 0x43425355
+ uDWord dCBWTag;
+ uDWord dCBWDataTransferLength;
+ uByte bCBWFlags;
+#define CBWFLAGS_OUT 0x00
+#define CBWFLAGS_IN 0x80
+ uByte bCBWLUN;
+ uByte bCDBLength;
+#define CBWCDBLENGTH 16
+ uByte CBWCDB[CBWCDBLENGTH];
+} umass_bbb_cbw_t;
+
+#define UMASS_BBB_CBW_SIZE 31
+
+/* Command Status Wrapper */
+typedef struct {
+ uDWord dCSWSignature;
+#define CSWSIGNATURE 0x53425355
+#define CSWSIGNATURE_IMAGINATION_DBX1 0x43425355
+#define CSWSIGNATURE_OLYMPUS_C1 0x55425355
+ uDWord dCSWTag;
+ uDWord dCSWDataResidue;
+ uByte bCSWStatus;
+#define CSWSTATUS_GOOD 0x0
+#define CSWSTATUS_FAILED 0x1
+#define CSWSTATUS_PHASE 0x2
+} umass_bbb_csw_t;
+
+#define UMASS_BBB_CSW_SIZE 13
+
+#define SC_READ_6 0x08
+#define SC_READ_10 0x28
+#define SC_READ_12 0xa8
+#define SC_WRITE_6 0x0a
+#define SC_WRITE_10 0x2a
+#define SC_WRITE_12 0xaa
+
+static struct stats {
+ uint64_t xfer_error;
+ uint64_t xfer_success;
+ uint64_t xfer_reset;
+ uint64_t xfer_rx_bytes;
+ uint64_t xfer_tx_bytes;
+ uint64_t data_error;
+} stats;
+
+static uint32_t xfer_current_id;
+static uint32_t xfer_wrapper_sig;
+static uint32_t block_size = 512;
+
+static struct libusb20_transfer *xfer_in;
+static struct libusb20_transfer *xfer_out;
+static struct libusb20_device *usb_pdev;
+static uint8_t usb_iface;
+static int sense_recurse;
+
+/*
+ * SCSI commands sniffed off the wire - LUN maybe needs to be
+ * adjusted! Refer to "dev/usb/storage/ustorage_fs.c" for more
+ * information.
+ */
+static uint8_t mode_sense_6[0x6] = {0x1a, 0, 0x3f, 0, 0x0c};
+static uint8_t read_capacity[0xA] = {0x25,};
+static uint8_t request_sense[0xC] = {0x03, 0, 0, 0, 0x12};
+static uint8_t test_unit_ready[0x6] = {0};
+static uint8_t mode_page_inquiry[0x6] = {0x12, 1, 0x80, 0, 0xff, 0};
+static uint8_t request_invalid[0xC] = {0xEA, 0, 0, 0, 0};
+static uint8_t prevent_removal[0x6] = {0x1E, 0, 0, 0, 1};
+static uint8_t read_toc[0xA] = {0x43, 0x02, 0, 0, 0, 0xAA, 0, 0x0C};
+
+#define TIMEOUT_FILTER(x) (x)
+
+static void usb_request_sense(uint8_t lun);
+
+static void
+do_msc_reset(uint8_t lun)
+{
+ struct LIBUSB20_CONTROL_SETUP_DECODED setup;
+
+ LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup);
+
+ setup.bmRequestType = LIBUSB20_REQUEST_TYPE_CLASS |
+ LIBUSB20_RECIPIENT_INTERFACE;
+ setup.bRequest = 0xFF; /* BBB reset */
+ setup.wValue = 0;
+ setup.wIndex = usb_iface;
+ setup.wLength = 0;
+
+ if (libusb20_dev_request_sync(usb_pdev, &setup, NULL, NULL, 5000, 0)) {
+ printf("ERROR: %s\n", __FUNCTION__);
+ stats.xfer_error++;
+ }
+ libusb20_tr_clear_stall_sync(xfer_in);
+ libusb20_tr_clear_stall_sync(xfer_out);
+
+ stats.xfer_reset++;
+
+ usb_request_sense(lun);
+}
+
+static uint8_t
+do_msc_cmd(uint8_t *pcmd, uint8_t cmdlen, void *pdata, uint32_t datalen,
+ uint8_t isread, uint8_t isshort, uint8_t lun, uint8_t flags)
+{
+ umass_bbb_cbw_t cbw;
+ umass_bbb_csw_t csw;
+ struct libusb20_transfer *xfer_io;
+ uint32_t actlen;
+ uint32_t timeout;
+ int error;
+
+ memset(&cbw, 0, sizeof(cbw));
+
+ USETDW(cbw.dCBWSignature, xfer_wrapper_sig);
+ USETDW(cbw.dCBWTag, xfer_current_id);
+ xfer_current_id++;
+ USETDW(cbw.dCBWDataTransferLength, datalen);
+ cbw.bCBWFlags = (isread ? CBWFLAGS_IN : CBWFLAGS_OUT);
+ cbw.bCBWLUN = lun;
+ cbw.bCDBLength = cmdlen;
+ bcopy(pcmd, cbw.CBWCDB, cmdlen);
+
+ actlen = 0;
+
+ timeout = ((datalen + 299999) / 300000) * 1000;
+ timeout += 5000;
+
+ if ((error = libusb20_tr_bulk_intr_sync(xfer_out,
+ &cbw, sizeof(cbw), &actlen, TIMEOUT_FILTER(1000)))) {
+ printf("ERROR: CBW reception: %d\n", error);
+ do_msc_reset(lun);
+ return (1);
+ }
+ if (actlen != sizeof(cbw)) {
+ printf("ERROR: CBW length: %d != %d\n",
+ actlen, (int)sizeof(cbw));
+ do_msc_reset(lun);
+ return (1);
+ }
+ if (flags & 1)
+ datalen /= 2;
+
+ if (datalen != 0) {
+ xfer_io = isread ? xfer_in : xfer_out;
+
+ if ((error = libusb20_tr_bulk_intr_sync(xfer_io,
+ pdata, datalen, &actlen, TIMEOUT_FILTER(timeout)))) {
+ printf("ERROR: Data transfer: %d\n", error);
+ do_msc_reset(lun);
+ return (1);
+ }
+ if ((actlen != datalen) && (!isshort)) {
+ printf("ERROR: Short data: %d of %d bytes\n",
+ actlen, datalen);
+ do_msc_reset(lun);
+ return (1);
+ }
+ }
+ actlen = 0;
+ timeout = 8;
+
+ do {
+ error = libusb20_tr_bulk_intr_sync(xfer_in, &csw,
+ sizeof(csw), &actlen, TIMEOUT_FILTER(1000));
+ if (error) {
+ if (error == LIBUSB20_TRANSFER_TIMED_OUT) {
+ printf("TIMEOUT: Trying to get CSW again. "
+ "%d tries left.\n", timeout);
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ } while (--timeout);
+
+ if (error) {
+ libusb20_tr_clear_stall_sync(xfer_in);
+ error = libusb20_tr_bulk_intr_sync(xfer_in, &csw,
+ sizeof(csw), &actlen, TIMEOUT_FILTER(1000));
+ if (error) {
+ libusb20_tr_clear_stall_sync(xfer_in);
+ printf("ERROR: Could not read CSW: Stalled or "
+ "timeout (%d).\n", error);
+ do_msc_reset(lun);
+ return (1);
+ }
+ }
+ if (UGETDW(csw.dCSWSignature) != CSWSIGNATURE) {
+ printf("ERROR: Wrong CSW signature\n");
+ do_msc_reset(lun);
+ return (1);
+ }
+ if (actlen != sizeof(csw)) {
+ printf("ERROR: Wrong CSW length: %d != %d\n",
+ actlen, (int)sizeof(csw));
+ do_msc_reset(lun);
+ return (1);
+ }
+ if (csw.bCSWStatus != 0) {
+ printf("ERROR: CSW status: %d\n", (int)csw.bCSWStatus);
+ return (1);
+ } else {
+ stats.xfer_success++;
+ return (0);
+ }
+}
+
+static uint8_t
+do_read_10(uint32_t lba, uint32_t len, void *buf, uint8_t lun)
+{
+ static uint8_t cmd[10];
+ uint8_t retval;
+
+ cmd[0] = SC_READ_10;
+
+ len /= block_size;
+
+ cmd[2] = lba >> 24;
+ cmd[3] = lba >> 16;
+ cmd[4] = lba >> 8;
+ cmd[5] = lba >> 0;
+
+ cmd[7] = len >> 8;
+ cmd[8] = len;
+
+ retval = do_msc_cmd(cmd, 10, buf, len * block_size, 1, 0, lun, 0);
+
+ if (retval) {
+ printf("ERROR: %s\n", __FUNCTION__);
+ stats.xfer_error++;
+ }
+ return (retval);
+}
+
+static uint8_t
+do_write_10(uint32_t lba, uint32_t len, void *buf, uint8_t lun)
+{
+ static uint8_t cmd[10];
+ uint8_t retval;
+ uint8_t abort;
+
+ cmd[0] = SC_WRITE_10;
+
+ abort = len & 1;
+
+ len /= block_size;
+
+ cmd[2] = lba >> 24;
+ cmd[3] = lba >> 16;
+ cmd[4] = lba >> 8;
+ cmd[5] = lba >> 0;
+
+ cmd[7] = len >> 8;
+ cmd[8] = len;
+
+ retval = do_msc_cmd(cmd, 10, buf, (len * block_size), 0, 0, lun, abort);
+
+ if (retval) {
+ printf("ERROR: %s\n", __FUNCTION__);
+ stats.xfer_error++;
+ }
+ return (retval);
+}
+
+static void
+do_io_test(struct usb_msc_params *p, uint8_t lun, uint32_t lba_max,
+ uint8_t *buffer, uint8_t *reference)
+{
+ uint32_t io_offset;
+ uint32_t io_size;
+ uint32_t temp;
+ uint8_t do_read;
+ uint8_t retval;
+
+ switch (p->io_mode) {
+ case USB_MSC_IO_MODE_WRITE_ONLY:
+ do_read = 0;
+ break;
+ case USB_MSC_IO_MODE_READ_WRITE:
+ do_read = (usb_ts_rand_noise() & 1);
+ break;
+ default:
+ do_read = 1;
+ break;
+ }
+
+ switch (p->io_offset) {
+ case USB_MSC_IO_OFF_RANDOM:
+ io_offset = usb_ts_rand_noise();
+ break;
+ default:
+ io_offset = 0;
+ break;
+ }
+
+ switch (p->io_delay) {
+ case USB_MSC_IO_DELAY_RANDOM_10MS:
+ usleep(((uint32_t)usb_ts_rand_noise()) % 10000U);
+ break;
+ case USB_MSC_IO_DELAY_RANDOM_100MS:
+ usleep(((uint32_t)usb_ts_rand_noise()) % 100000U);
+ break;
+ case USB_MSC_IO_DELAY_FIXED_10MS:
+ usleep(10000);
+ break;
+ case USB_MSC_IO_DELAY_FIXED_100MS:
+ usleep(100000);
+ break;
+ default:
+ break;
+ }
+
+ switch (p->io_size) {
+ case USB_MSC_IO_SIZE_RANDOM:
+ io_size = ((uint32_t)usb_ts_rand_noise()) & 65535U;
+ break;
+ case USB_MSC_IO_SIZE_INCREASING:
+ io_size = (xfer_current_id & 65535U);
+ break;
+ case USB_MSC_IO_SIZE_FIXED_1BLK:
+ io_size = 1;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_2BLK:
+ io_size = 2;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_4BLK:
+ io_size = 4;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_8BLK:
+ io_size = 8;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_16BLK:
+ io_size = 16;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_32BLK:
+ io_size = 32;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_64BLK:
+ io_size = 64;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_128BLK:
+ io_size = 128;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_256BLK:
+ io_size = 256;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_512BLK:
+ io_size = 512;
+ break;
+ case USB_MSC_IO_SIZE_FIXED_1024BLK:
+ io_size = 1024;
+ break;
+ default:
+ io_size = 1;
+ break;
+ }
+
+ if (io_size == 0)
+ io_size = 1;
+
+ io_offset %= lba_max;
+
+ temp = (lba_max - io_offset);
+
+ if (io_size > temp)
+ io_size = temp;
+
+ if (do_read) {
+ retval = do_read_10(io_offset, io_size * block_size,
+ buffer + (io_offset * block_size), lun);
+
+ if (retval == 0) {
+ if (bcmp(buffer + (io_offset * block_size),
+ reference + (io_offset * block_size),
+ io_size * block_size)) {
+ printf("ERROR: Data comparison failure\n");
+ stats.data_error++;
+ retval = 1;
+ }
+ }
+ stats.xfer_rx_bytes += (io_size * block_size);
+
+ } else {
+
+ retval = do_write_10(io_offset, io_size * block_size,
+ reference + (io_offset * block_size), lun);
+
+ stats.xfer_tx_bytes += (io_size * block_size);
+ }
+
+ if ((stats.xfer_error + stats.data_error +
+ stats.xfer_reset) >= p->max_errors) {
+ printf("Maximum number of errors exceeded\n");
+ p->done = 1;
+ }
+}
+
+static void
+usb_request_sense(uint8_t lun)
+{
+ uint8_t dummy_buf[255];
+
+ if (sense_recurse)
+ return;
+
+ sense_recurse++;
+
+ do_msc_cmd(request_sense, sizeof(request_sense),
+ dummy_buf, 255, 1, 1, lun, 0);
+
+ sense_recurse--;
+}
+
+static void
+usb_msc_test(struct usb_msc_params *p)
+{
+ struct stats last_stat;
+ struct timeval sub_tv;
+ struct timeval ref_tv;
+ struct timeval res_tv;
+ uint8_t *buffer = NULL;
+ uint8_t *reference = NULL;
+ uint32_t dummy_buf[65536 / 4];
+ uint32_t lba_max;
+ uint32_t x;
+ uint32_t y;
+ uint32_t capacity_lba;
+ uint32_t capacity_bs;
+ time_t last_sec;
+ uint8_t lun;
+ int tries;
+
+ memset(&last_stat, 0, sizeof(last_stat));
+
+ switch (p->io_lun) {
+ case USB_MSC_IO_LUN_0:
+ lun = 0;
+ break;
+ case USB_MSC_IO_LUN_1:
+ lun = 1;
+ break;
+ case USB_MSC_IO_LUN_2:
+ lun = 2;
+ break;
+ case USB_MSC_IO_LUN_3:
+ lun = 3;
+ break;
+ default:
+ lun = 0;
+ break;
+ }
+
+ p->done = 0;
+
+ sense_recurse = p->try_sense_on_error ? 0 : 1;
+
+ printf("Resetting device ...\n");
+
+ do_msc_reset(lun);
+
+ printf("Testing SCSI commands ...\n");
+
+ if (p->try_all_lun) {
+ printf("Requesting sense from LUN 0..255 ... ");
+ for (x = y = 0; x != 256; x++) {
+ if (do_msc_cmd(mode_sense_6, sizeof(mode_sense_6),
+ dummy_buf, 255, 1, 1, x, 0))
+ y++;
+
+ if (libusb20_dev_check_connected(usb_pdev) != 0) {
+ printf(" disconnect ");
+ break;
+ }
+ }
+ printf("Passed=%d, Failed=%d\n", 256 - y, y);
+ }
+ do_msc_cmd(mode_sense_6, sizeof(mode_sense_6),
+ dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(request_sense, sizeof(request_sense),
+ dummy_buf, 255, 1, 1, lun, 0);
+
+ for (tries = 0; tries != 4; tries++) {
+
+ memset(dummy_buf, 0, sizeof(dummy_buf));
+
+ if (do_msc_cmd(read_capacity, sizeof(read_capacity),
+ dummy_buf, 255, 1, 1, lun, 0) != 0) {
+ printf("Cannot read disk capacity (%u / 4)\n", tries);
+ if (tries == 3)
+ return;
+ usleep(50000);
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ capacity_lba = be32toh(dummy_buf[0]);
+ capacity_bs = be32toh(dummy_buf[1]);
+
+ printf("Disk reports a capacity of LBA=%u and BS=%u\n",
+ capacity_lba, capacity_bs);
+
+ block_size = capacity_bs;
+
+ if (capacity_bs > 65535) {
+ printf("Blocksize is too big\n");
+ return;
+ }
+ if (capacity_bs < 1) {
+ printf("Blocksize is too small\n");
+ return;
+ }
+ if (capacity_bs != 512)
+ printf("INFO: Blocksize is not 512 bytes\n");
+
+ if (p->try_invalid_scsi_command) {
+ int status;
+
+ for (tries = 0; tries != 4; tries++) {
+
+ printf("Trying invalid SCSI command: ");
+
+ status = do_msc_cmd(request_invalid,
+ sizeof(request_invalid), dummy_buf,
+ 255, 1, 1, lun, 0);
+
+ printf("Result%s as expected\n", status ? "" : " NOT");
+
+ usleep(50000);
+ }
+ }
+ if (p->try_invalid_wrapper_block) {
+ int status;
+
+ for (tries = 0; tries != 4; tries++) {
+
+ printf("Trying invalid USB wrapper block signature: ");
+
+ xfer_wrapper_sig = 0x55663322;
+
+ status = do_msc_cmd(read_capacity,
+ sizeof(read_capacity), dummy_buf,
+ 255, 1, 1, lun, 0);
+
+ printf("Result%s as expected\n", status ? "" : " NOT");
+
+ xfer_wrapper_sig = CBWSIGNATURE;
+
+ usleep(50000);
+ }
+ }
+ do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(read_capacity, sizeof(read_capacity), dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0);
+ do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0);
+ do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0);
+ do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0);
+ do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0);
+ do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0);
+ do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0);
+ do_msc_cmd(read_capacity, sizeof(read_capacity), dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(mode_page_inquiry, sizeof(mode_page_inquiry), dummy_buf, 255, 1, 1, lun, 0);
+ do_msc_cmd(mode_page_inquiry, sizeof(mode_page_inquiry), dummy_buf, 255, 1, 1, lun, 0);
+
+ if (do_msc_cmd(prevent_removal, sizeof(prevent_removal),
+ 0, 0, 1, 1, lun, 0)) {
+ printf("INFO: Prevent medium removal failed\n");
+ }
+ if (do_msc_cmd(read_toc, sizeof(read_toc),
+ dummy_buf, 255, 1, 1, lun, 0)) {
+ printf("INFO: Read Table Of Content failed\n");
+ }
+ if (p->try_last_lba) {
+
+ for (y = 0, x = (1UL << 31); x; x >>= 1) {
+ if (do_read_10(x | y, block_size, dummy_buf, lun) == 0)
+ y |= x;
+ }
+
+ printf("Highest readable LBA: %u (%s), "
+ "Capacity is %u MBytes\n", y,
+ (capacity_lba != y) ? "WRONG" : "OK",
+ (int)((((uint64_t)(y) * (uint64_t)block_size) +
+ (uint64_t)block_size) / 1000000ULL));
+ } else {
+
+ y = capacity_lba;
+
+ printf("Highest readable LBA: %u (not "
+ "verified), Capacity is %u MBytes\n", y,
+ (int)((((uint64_t)(y) * (uint64_t)block_size) +
+ (uint64_t)block_size) / 1000000ULL));
+ }
+
+ if (y != 0xFFFFFFFFU)
+ y++;
+
+ lba_max = y;
+
+ switch (p->io_area) {
+ case USB_MSC_IO_AREA_1MB:
+ lba_max = 1024;
+ break;
+ case USB_MSC_IO_AREA_16MB:
+ lba_max = 1024 * 16;
+ break;
+ case USB_MSC_IO_AREA_256MB:
+ lba_max = 1024 * 256;
+ break;
+ case USB_MSC_IO_AREA_COMPLETE:
+ default:
+ break;
+ }
+
+ if (lba_max > 65535)
+ lba_max = 65535;
+
+ printf("Highest testable LBA: %u\n", (int)lba_max);
+
+ buffer = malloc(block_size * lba_max);
+ if (buffer == NULL) {
+ printf("ERROR: Could not allocate memory\n");
+ goto fail;
+ }
+ reference = malloc(block_size * lba_max);
+ if (reference == NULL) {
+ printf("ERROR: Could not allocate memory\n");
+ goto fail;
+ }
+retry_read_init:
+
+ printf("Setting up initial data pattern, "
+ "LBA limit = %u ... ", lba_max);
+
+ switch (p->io_mode) {
+ case USB_MSC_IO_MODE_WRITE_ONCE_READ_ONLY:
+ case USB_MSC_IO_MODE_WRITE_ONLY:
+ case USB_MSC_IO_MODE_READ_WRITE:
+
+ switch (p->io_pattern) {
+ case USB_MSC_IO_PATTERN_FIXED:
+ for (x = 0; x != (block_size * lba_max); x += 8) {
+ reference[x + 0] = x >> 24;
+ reference[x + 1] = x >> 16;
+ reference[x + 2] = x >> 8;
+ reference[x + 3] = x >> 0;
+ reference[x + 4] = 0xFF;
+ reference[x + 5] = 0x00;
+ reference[x + 6] = 0xFF;
+ reference[x + 7] = 0x00;
+ }
+ if (do_write_10(0, lba_max * block_size,
+ reference, lun)) {
+ printf("FAILED\n");
+ lba_max /= 2;
+ if (lba_max)
+ goto retry_read_init;
+ goto fail;
+ }
+ printf("SUCCESS\n");
+ break;
+ case USB_MSC_IO_PATTERN_RANDOM:
+ for (x = 0; x != (block_size * lba_max); x++) {
+ reference[x] = usb_ts_rand_noise() % 255U;
+ }
+ if (do_write_10(0, lba_max * block_size,
+ reference, lun)) {
+ printf("FAILED\n");
+ lba_max /= 2;
+ if (lba_max)
+ goto retry_read_init;
+ goto fail;
+ }
+ printf("SUCCESS\n");
+ break;
+ default:
+ if (do_read_10(0, lba_max * block_size,
+ reference, lun)) {
+ printf("FAILED\n");
+ lba_max /= 2;
+ if (lba_max)
+ goto retry_read_init;
+ goto fail;
+ }
+ printf("SUCCESS\n");
+ break;
+ }
+ break;
+
+ default:
+ if (do_read_10(0, lba_max * block_size, reference, lun)) {
+ printf("FAILED\n");
+ lba_max /= 2;
+ if (lba_max)
+ goto retry_read_init;
+ goto fail;
+ }
+ printf("SUCCESS\n");
+ break;
+ }
+
+
+ if (p->try_abort_data_write) {
+ if (do_write_10(0, (2 * block_size) | 1, reference, lun))
+ printf("Aborted data write failed (OK)!\n");
+ else
+ printf("Aborted data write did not fail (ERROR)!\n");
+
+ if (do_read_10(0, (2 * block_size), reference, lun))
+ printf("Post-aborted data read failed (ERROR)\n");
+ else
+ printf("Post-aborted data read success (OK)!\n");
+ }
+ printf("Starting test ...\n");
+
+ gettimeofday(&ref_tv, 0);
+
+ last_sec = ref_tv.tv_sec;
+
+ printf("\n");
+
+ while (1) {
+
+ gettimeofday(&sub_tv, 0);
+
+ if (last_sec != sub_tv.tv_sec) {
+
+ printf("STATUS: ID=%u, RX=%u bytes/sec, "
+ "TX=%u bytes/sec, ERR=%u, RST=%u, DERR=%u\n",
+ (int)xfer_current_id,
+ (int)(stats.xfer_rx_bytes -
+ last_stat.xfer_rx_bytes),
+ (int)(stats.xfer_tx_bytes -
+ last_stat.xfer_tx_bytes),
+ (int)(stats.xfer_error),
+ (int)(stats.xfer_reset),
+ (int)(stats.data_error));
+
+ fflush(stdout);
+
+ last_sec = sub_tv.tv_sec;
+ last_stat = stats;
+ }
+ timersub(&sub_tv, &ref_tv, &res_tv);
+
+ if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)p->duration))
+ break;
+
+ do_io_test(p, lun, lba_max, buffer, reference);
+
+ if (libusb20_dev_check_connected(usb_pdev) != 0) {
+ printf("Device disconnected\n");
+ break;
+ }
+ if (p->done) {
+ printf("Maximum number of errors exceeded\n");
+ break;
+ }
+ }
+
+ printf("\nTest done!\n");
+
+fail:
+ if (buffer)
+ free(buffer);
+ if (reference)
+ free(reference);
+}
+
+void
+show_host_device_selection(uint8_t level, uint16_t *pvid, uint16_t *ppid)
+{
+ struct libusb20_backend *pbe;
+ struct libusb20_device *pdev;
+ struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+
+ uint16_t vid[USB_DEVICES_MAX];
+ uint16_t pid[USB_DEVICES_MAX];
+
+ int index;
+ int sel;
+
+ const char *ptr;
+
+top:
+ pbe = libusb20_be_alloc_default();
+ pdev = NULL;
+ index = 0;
+
+ printf("\n[] Select USB device:\n");
+
+ while ((pdev = libusb20_be_device_foreach(pbe, pdev))) {
+
+ if (libusb20_dev_get_mode(pdev) != LIBUSB20_MODE_HOST)
+ continue;
+
+ if (index < USB_DEVICES_MAX) {
+ ddesc = libusb20_dev_get_device_desc(pdev);
+ ptr = libusb20_dev_get_desc(pdev);
+ printf("%s%d) %s\n", indent[level], index, ptr);
+ vid[index] = ddesc->idVendor;
+ pid[index] = ddesc->idProduct;
+ index++;
+ } else {
+ break;
+ }
+ }
+
+ printf("%sr) Refresh device list\n", indent[level]);
+ printf("%sx) Return to previous menu\n", indent[level]);
+
+ /* release data */
+ libusb20_be_free(pbe);
+
+ sel = get_integer();
+
+ if (sel == -2)
+ goto top;
+
+ if ((sel < 0) || (sel >= index)) {
+ *pvid = 0;
+ *ppid = 0;
+ return;
+ }
+ *pvid = vid[sel];
+ *ppid = pid[sel];
+}
+
+struct libusb20_device *
+find_usb_device(uint16_t vid, uint16_t pid)
+{
+ struct libusb20_backend *pbe = libusb20_be_alloc_default();
+ struct libusb20_device *pdev = NULL;
+ struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+
+ while ((pdev = libusb20_be_device_foreach(pbe, pdev))) {
+
+ if (libusb20_dev_get_mode(pdev) != LIBUSB20_MODE_HOST)
+ continue;
+
+ ddesc = libusb20_dev_get_device_desc(pdev);
+
+ if ((vid == ddesc->idVendor) &&
+ (pid == ddesc->idProduct)) {
+ libusb20_be_dequeue_device(pbe, pdev);
+ break;
+ }
+ }
+
+ /* release data */
+ libusb20_be_free(pbe);
+
+ return (pdev);
+}
+
+void
+find_usb_endpoints(struct libusb20_device *pdev, uint8_t class,
+ uint8_t subclass, uint8_t protocol, uint8_t alt_setting,
+ uint8_t *pif, uint8_t *in_ep, uint8_t *out_ep, uint8_t next_if)
+{
+ struct libusb20_config *pcfg;
+ struct libusb20_interface *iface;
+ struct libusb20_endpoint *ep;
+ uint8_t x;
+ uint8_t y;
+ uint8_t z;
+
+ *in_ep = 0;
+ *out_ep = 0;
+ *pif = 0;
+
+ pcfg = libusb20_dev_alloc_config(pdev,
+ libusb20_dev_get_config_index(pdev));
+
+ if (pcfg == NULL)
+ return;
+
+ for (x = 0; x != pcfg->num_interface; x++) {
+
+ y = alt_setting;
+
+ iface = (pcfg->interface + x);
+
+ if ((iface->desc.bInterfaceClass == class) &&
+ (iface->desc.bInterfaceSubClass == subclass ||
+ subclass == 255) &&
+ (iface->desc.bInterfaceProtocol == protocol ||
+ protocol == 255)) {
+
+ if (next_if) {
+ x++;
+ if (x == pcfg->num_interface)
+ break;
+ iface = (pcfg->interface + x);
+ }
+ *pif = x;
+
+ for (z = 0; z != iface->num_endpoints; z++) {
+ ep = iface->endpoints + z;
+
+ /* BULK only */
+ if ((ep->desc.bmAttributes & 3) != 2)
+ continue;
+
+ if (ep->desc.bEndpointAddress & 0x80)
+ *in_ep = ep->desc.bEndpointAddress;
+ else
+ *out_ep = ep->desc.bEndpointAddress;
+ }
+ break;
+ }
+ }
+
+ free(pcfg);
+}
+
+static void
+exec_host_msc_test(struct usb_msc_params *p, uint16_t vid, uint16_t pid)
+{
+ struct libusb20_device *pdev;
+
+ uint8_t in_ep;
+ uint8_t out_ep;
+ uint8_t iface;
+
+ int error;
+
+ memset(&stats, 0, sizeof(stats));
+
+ xfer_current_id = 0;
+ xfer_wrapper_sig = CBWSIGNATURE;
+
+ pdev = find_usb_device(vid, pid);
+ if (pdev == NULL) {
+ printf("USB device not found\n");
+ return;
+ }
+ find_usb_endpoints(pdev, 8, 6, 0x50, 0, &iface, &in_ep, &out_ep, 0);
+
+ if ((in_ep == 0) || (out_ep == 0)) {
+ printf("Could not find USB endpoints\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ printf("Attaching to: %s @ iface %d\n",
+ libusb20_dev_get_desc(pdev), iface);
+
+ if (libusb20_dev_open(pdev, 2)) {
+ printf("Could not open USB device\n");
+ libusb20_dev_free(pdev);
+ return;
+ }
+ if (libusb20_dev_detach_kernel_driver(pdev, iface)) {
+ printf("WARNING: Could not detach kernel driver\n");
+ }
+ xfer_in = libusb20_tr_get_pointer(pdev, 0);
+ error = libusb20_tr_open(xfer_in, 65536, 1, in_ep);
+ if (error) {
+ printf("Could not open USB endpoint %d\n", in_ep);
+ libusb20_dev_free(pdev);
+ return;
+ }
+ xfer_out = libusb20_tr_get_pointer(pdev, 1);
+ error = libusb20_tr_open(xfer_out, 65536, 1, out_ep);
+ if (error) {
+ printf("Could not open USB endpoint %d\n", out_ep);
+ libusb20_dev_free(pdev);
+ return;
+ }
+ usb_pdev = pdev;
+ usb_iface = iface;
+
+ usb_msc_test(p);
+
+ libusb20_dev_free(pdev);
+}
+
+static void
+set_defaults(struct usb_msc_params *p)
+{
+ memset(p, 0, sizeof(*p));
+
+ p->duration = 60; /* seconds */
+ p->try_invalid_scsi_command = 1;
+ p->try_invalid_wrapper_block = 1;
+ p->try_last_lba = 1;
+ p->max_errors = -1;
+}
+
+static const char *
+get_io_mode(const struct usb_msc_params *p)
+{
+ ; /* indent fix */
+ switch (p->io_mode) {
+ case USB_MSC_IO_MODE_READ_ONLY:
+ return ("Read Only");
+ case USB_MSC_IO_MODE_WRITE_ONCE_READ_ONLY:
+ return ("Write Once, Read Only");
+ case USB_MSC_IO_MODE_WRITE_ONLY:
+ return ("Write Only");
+ case USB_MSC_IO_MODE_READ_WRITE:
+ return ("Read and Write");
+ default:
+ return ("Unknown");
+ }
+}
+
+static const char *
+get_io_pattern(const struct usb_msc_params *p)
+{
+ ; /* indent fix */
+ switch (p->io_pattern) {
+ case USB_MSC_IO_PATTERN_FIXED:
+ return ("Fixed");
+ case USB_MSC_IO_PATTERN_RANDOM:
+ return ("Random");
+ case USB_MSC_IO_PATTERN_PRESERVE:
+ return ("Preserve");
+ default:
+ return ("Unknown");
+ }
+}
+
+static const char *
+get_io_size(const struct usb_msc_params *p)
+{
+ ; /* indent fix */
+ switch (p->io_size) {
+ case USB_MSC_IO_SIZE_RANDOM:
+ return ("Random");
+ case USB_MSC_IO_SIZE_INCREASING:
+ return ("Increasing");
+ case USB_MSC_IO_SIZE_FIXED_1BLK:
+ return ("Single block");
+ case USB_MSC_IO_SIZE_FIXED_2BLK:
+ return ("2 blocks");
+ case USB_MSC_IO_SIZE_FIXED_4BLK:
+ return ("4 blocks");
+ case USB_MSC_IO_SIZE_FIXED_8BLK:
+ return ("8 blocks");
+ case USB_MSC_IO_SIZE_FIXED_16BLK:
+ return ("16 blocks");
+ case USB_MSC_IO_SIZE_FIXED_32BLK:
+ return ("32 blocks");
+ case USB_MSC_IO_SIZE_FIXED_64BLK:
+ return ("64 blocks");
+ case USB_MSC_IO_SIZE_FIXED_128BLK:
+ return ("128 blocks");
+ case USB_MSC_IO_SIZE_FIXED_256BLK:
+ return ("256 blocks");
+ case USB_MSC_IO_SIZE_FIXED_512BLK:
+ return ("512 blocks");
+ case USB_MSC_IO_SIZE_FIXED_1024BLK:
+ return ("1024 blocks");
+ default:
+ return ("Unknown");
+ }
+}
+
+static const char *
+get_io_delay(const struct usb_msc_params *p)
+{
+ ; /* indent fix */
+ switch (p->io_delay) {
+ case USB_MSC_IO_DELAY_NONE:
+ return ("None");
+ case USB_MSC_IO_DELAY_RANDOM_10MS:
+ return ("Random 10ms");
+ case USB_MSC_IO_DELAY_RANDOM_100MS:
+ return ("Random 100ms");
+ case USB_MSC_IO_DELAY_FIXED_10MS:
+ return ("Fixed 10ms");
+ case USB_MSC_IO_DELAY_FIXED_100MS:
+ return ("Fixed 100ms");
+ default:
+ return ("Unknown");
+ }
+}
+
+static const char *
+get_io_offset(const struct usb_msc_params *p)
+{
+ ; /* indent fix */
+ switch (p->io_offset) {
+ case USB_MSC_IO_OFF_START_OF_DISK:
+ return ("Start Of Disk");
+ case USB_MSC_IO_OFF_RANDOM:
+ return ("Random Offset");
+ default:
+ return ("Unknown");
+ }
+}
+
+static const char *
+get_io_area(const struct usb_msc_params *p)
+{
+ ; /* indent fix */
+ switch (p->io_area) {
+ case USB_MSC_IO_AREA_COMPLETE:
+ return ("Complete Disk");
+ case USB_MSC_IO_AREA_1MB:
+ return ("First MegaByte");
+ case USB_MSC_IO_AREA_16MB:
+ return ("First 16 MegaBytes");
+ case USB_MSC_IO_AREA_256MB:
+ return ("First 256 MegaBytes");
+ default:
+ return ("Unknown");
+ }
+}
+
+void
+show_host_msc_test(uint8_t level, uint16_t vid,
+ uint16_t pid, uint32_t duration)
+{
+ struct usb_msc_params params;
+ uint8_t retval;
+
+ set_defaults(&params);
+
+ params.duration = duration;
+
+ while (1) {
+
+ retval = usb_ts_show_menu(level,
+ "Mass Storage Test Parameters",
+ " 1) Toggle I/O mode: <%s>\n"
+ " 2) Toggle I/O size: <%s>\n"
+ " 3) Toggle I/O delay: <%s>\n"
+ " 4) Toggle I/O offset: <%s>\n"
+ " 5) Toggle I/O area: <%s>\n"
+ " 6) Toggle I/O pattern: <%s>\n"
+ " 7) Toggle try invalid SCSI command: <%s>\n"
+ " 8) Toggle try invalid wrapper block: <%s>\n"
+ " 9) Toggle try invalid MaxPacketSize: <%s>\n"
+ "10) Toggle try last Logical Block Address: <%s>\n"
+ "11) Toggle I/O lun: <%d>\n"
+ "12) Set maximum number of errors: <%d>\n"
+ "13) Set test duration: <%d> seconds\n"
+ "14) Toggle try aborted write transfer: <%s>\n"
+ "15) Toggle request sense on error: <%s>\n"
+ "16) Toggle try all LUN: <%s>\n"
+ "20) Reset parameters\n"
+ "30) Start test (VID=0x%04x, PID=0x%04x)\n"
+ "40) Select another device\n"
+ " x) Return to previous menu \n",
+ get_io_mode(&params),
+ get_io_size(&params),
+ get_io_delay(&params),
+ get_io_offset(&params),
+ get_io_area(&params),
+ get_io_pattern(&params),
+ (params.try_invalid_scsi_command ? "YES" : "NO"),
+ (params.try_invalid_wrapper_block ? "YES" : "NO"),
+ (params.try_invalid_max_packet_size ? "YES" : "NO"),
+ (params.try_last_lba ? "YES" : "NO"),
+ params.io_lun,
+ (int)params.max_errors,
+ (int)params.duration,
+ (params.try_abort_data_write ? "YES" : "NO"),
+ (params.try_sense_on_error ? "YES" : "NO"),
+ (params.try_all_lun ? "YES" : "NO"),
+ vid, pid);
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ params.io_mode++;
+ params.io_mode %= USB_MSC_IO_MODE_MAX;
+ break;
+ case 2:
+ params.io_size++;
+ params.io_size %= USB_MSC_IO_SIZE_MAX;
+ break;
+ case 3:
+ params.io_delay++;
+ params.io_delay %= USB_MSC_IO_DELAY_MAX;
+ break;
+ case 4:
+ params.io_offset++;
+ params.io_offset %= USB_MSC_IO_OFF_MAX;
+ break;
+ case 5:
+ params.io_area++;
+ params.io_area %= USB_MSC_IO_AREA_MAX;
+ break;
+ case 6:
+ params.io_pattern++;
+ params.io_pattern %= USB_MSC_IO_PATTERN_MAX;
+ break;
+ case 7:
+ params.try_invalid_scsi_command ^= 1;
+ break;
+ case 8:
+ params.try_invalid_wrapper_block ^= 1;
+ break;
+ case 9:
+ params.try_invalid_max_packet_size ^= 1;
+ break;
+ case 10:
+ params.try_last_lba ^= 1;
+ break;
+ case 11:
+ params.io_lun++;
+ params.io_lun %= USB_MSC_IO_LUN_MAX;
+ break;
+ case 12:
+ params.max_errors = get_integer();
+ break;
+ case 13:
+ params.duration = get_integer();
+ break;
+ case 14:
+ params.try_abort_data_write ^= 1;
+ break;
+ case 15:
+ params.try_sense_on_error ^= 1;
+ break;
+ case 16:
+ params.try_all_lun ^= 1;
+ break;
+ case 20:
+ set_defaults(&params);
+ break;
+ case 30:
+ exec_host_msc_test(&params, vid, pid);
+ break;
+ case 40:
+ show_host_device_selection(level + 1, &vid, &pid);
+ break;
+ default:
+ return;
+ }
+ }
+}
diff --git a/tools/tools/usbtest/usb_msc_test.h b/tools/tools/usbtest/usb_msc_test.h
new file mode 100644
index 0000000..3af7b08
--- /dev/null
+++ b/tools/tools/usbtest/usb_msc_test.h
@@ -0,0 +1,120 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _USB_MSC_TEST_H_
+#define _USB_MSC_TEST_H_
+
+enum {
+ USB_MSC_IO_MODE_READ_ONLY,
+ USB_MSC_IO_MODE_WRITE_ONCE_READ_ONLY,
+ USB_MSC_IO_MODE_WRITE_ONLY,
+ USB_MSC_IO_MODE_READ_WRITE,
+ USB_MSC_IO_MODE_MAX,
+};
+
+enum {
+ USB_MSC_IO_PATTERN_FIXED,
+ USB_MSC_IO_PATTERN_RANDOM,
+ USB_MSC_IO_PATTERN_PRESERVE,
+ USB_MSC_IO_PATTERN_MAX,
+};
+
+enum {
+ USB_MSC_IO_SIZE_RANDOM,
+ USB_MSC_IO_SIZE_INCREASING,
+ USB_MSC_IO_SIZE_FIXED_1BLK,
+ USB_MSC_IO_SIZE_FIXED_2BLK,
+ USB_MSC_IO_SIZE_FIXED_4BLK,
+ USB_MSC_IO_SIZE_FIXED_8BLK,
+ USB_MSC_IO_SIZE_FIXED_16BLK,
+ USB_MSC_IO_SIZE_FIXED_32BLK,
+ USB_MSC_IO_SIZE_FIXED_64BLK,
+ USB_MSC_IO_SIZE_FIXED_128BLK,
+ USB_MSC_IO_SIZE_FIXED_256BLK,
+ USB_MSC_IO_SIZE_FIXED_512BLK,
+ USB_MSC_IO_SIZE_FIXED_1024BLK,
+ USB_MSC_IO_SIZE_MAX,
+};
+
+enum {
+ USB_MSC_IO_DELAY_NONE,
+ USB_MSC_IO_DELAY_RANDOM_10MS,
+ USB_MSC_IO_DELAY_RANDOM_100MS,
+ USB_MSC_IO_DELAY_FIXED_10MS,
+ USB_MSC_IO_DELAY_FIXED_100MS,
+ USB_MSC_IO_DELAY_MAX,
+};
+
+enum {
+ USB_MSC_IO_OFF_START_OF_DISK,
+ USB_MSC_IO_OFF_RANDOM,
+ USB_MSC_IO_OFF_MAX,
+};
+
+enum {
+ USB_MSC_IO_AREA_COMPLETE,
+ USB_MSC_IO_AREA_1MB,
+ USB_MSC_IO_AREA_16MB,
+ USB_MSC_IO_AREA_256MB,
+ USB_MSC_IO_AREA_MAX,
+};
+
+enum {
+ USB_MSC_IO_LUN_0,
+ USB_MSC_IO_LUN_1,
+ USB_MSC_IO_LUN_2,
+ USB_MSC_IO_LUN_3,
+ USB_MSC_IO_LUN_MAX,
+};
+
+struct usb_msc_params {
+
+ uint32_t duration;
+ uint32_t max_errors;
+
+ /* See "USB_MSC_XXX" enums */
+
+ uint8_t io_mode;
+ uint8_t io_size;
+ uint8_t io_delay;
+ uint8_t io_offset;
+ uint8_t io_area;
+ uint8_t io_pattern;
+ uint8_t io_lun;
+
+ /* booleans */
+ uint8_t try_invalid_scsi_command;
+ uint8_t try_invalid_wrapper_block;
+ uint8_t try_invalid_max_packet_size;
+ uint8_t try_last_lba;
+ uint8_t try_abort_data_write;
+ uint8_t try_sense_on_error;
+ uint8_t try_all_lun;
+
+ uint8_t done;
+};
+
+#endif /* _USB_MSC_TEST_H_ */
diff --git a/tools/tools/usbtest/usbtest.c b/tools/tools/usbtest/usbtest.c
new file mode 100644
index 0000000..725b9ea
--- /dev/null
+++ b/tools/tools/usbtest/usbtest.c
@@ -0,0 +1,809 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <err.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <dev/usb/usb_ioctl.h>
+
+#include "usbtest.h"
+
+#include <g_keyboard.h>
+#include <g_mouse.h>
+#include <g_modem.h>
+#include <g_audio.h>
+
+static uint8_t usb_ts_select[USB_TS_MAX_LEVELS];
+
+const char *indent[USB_TS_MAX_LEVELS] = {
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+};
+
+/* a perceptual white noise generator (after HPS' invention) */
+
+int32_t
+usb_ts_rand_noise(void)
+{
+ uint32_t temp;
+ const uint32_t prime = 0xFFFF1D;
+ static uint32_t noise_rem = 1;
+
+ if (noise_rem & 1) {
+ noise_rem += prime;
+ }
+ noise_rem /= 2;
+
+ temp = noise_rem;
+
+ /* unsigned to signed conversion */
+
+ temp ^= 0x800000;
+ if (temp & 0x800000) {
+ temp |= (-0x800000);
+ }
+ return temp;
+}
+
+uint8_t
+usb_ts_show_menu(uint8_t level, const char *title, const char *fmt,...)
+{
+ va_list args;
+ uint8_t x;
+ uint8_t retval;
+ char *pstr;
+ char buf[16];
+ char menu[80 * 20];
+
+ va_start(args, fmt);
+ vsnprintf(menu, sizeof(menu), fmt, args);
+ va_end(args);
+
+ printf("[");
+
+ for (x = 0; x != level; x++) {
+ if ((x + 1) == level)
+ printf("%d", usb_ts_select[x]);
+ else
+ printf("%d.", usb_ts_select[x]);
+ }
+
+ printf("] - %s:\n\n", title);
+
+ x = 1;
+ for (pstr = menu; *pstr; pstr++) {
+ if (x != 0) {
+ printf("%s", indent[level]);
+ x = 0;
+ }
+ printf("%c", *pstr);
+
+ if (*pstr == '\n')
+ x = 1;
+ }
+
+ printf("\n>");
+
+ if (fgets(buf, sizeof(buf), stdin) == NULL)
+ err(1, "Cannot read input");
+
+ if (buf[0] == 'x')
+ retval = 255;
+ else
+ retval = atoi(buf);
+
+ usb_ts_select[level] = retval;
+
+ return (retval);
+}
+
+void
+get_string(char *ptr, int size)
+{
+ printf("\nEnter string>");
+
+ if (fgets(ptr, size, stdin) == NULL)
+ err(1, "Cannot read input");
+
+ ptr[size - 1] = 0;
+
+ size = strlen(ptr);
+
+ /* strip trailing newline, if any */
+ if (size == 0)
+ return;
+ else if (ptr[size - 1] == '\n')
+ ptr[size - 1] = 0;
+}
+
+int
+get_integer(void)
+{
+ char buf[32];
+
+ printf("\nEnter integer value>");
+
+ if (fgets(buf, sizeof(buf), stdin) == NULL)
+ err(1, "Cannot read input");
+
+ if (strcmp(buf, "x\n") == 0)
+ return (-1);
+ if (strcmp(buf, "r\n") == 0)
+ return (-2);
+
+ return ((int)strtol(buf, 0, 0));
+}
+
+static void
+set_template(int template)
+{
+ int error;
+
+ error = sysctlbyname("hw.usb.template", NULL, NULL,
+ &template, sizeof(template));
+
+ if (error != 0) {
+ printf("WARNING: Could not set USB template "
+ "to %d (error=%d)\n", template, errno);
+ }
+}
+
+static void
+show_default_audio_select(uint8_t level)
+{
+ int error;
+ int retval;
+ int mode = 0;
+ int pattern_interval = 128;
+ int throughput = 0;
+ size_t len;
+ char pattern[G_AUDIO_MAX_STRLEN] = {"0123456789abcdef"};
+
+ set_template(USB_TEMP_AUDIO);
+
+ while (1) {
+
+ error = sysctlbyname("hw.usb.g_audio.mode", NULL, NULL,
+ &mode, sizeof(mode));
+
+ if (error != 0) {
+ printf("WARNING: Could not set audio mode "
+ "to %d (error=%d)\n", mode, errno);
+ }
+ error = sysctlbyname("hw.usb.g_audio.pattern_interval", NULL, NULL,
+ &pattern_interval, sizeof(pattern_interval));
+
+ if (error != 0) {
+ printf("WARNING: Could not set pattern interval "
+ "to %d (error=%d)\n", pattern_interval, errno);
+ }
+ len = sizeof(throughput);
+
+ error = sysctlbyname("hw.usb.g_audio.throughput",
+ &throughput, &len, 0, 0);
+
+ if (error != 0) {
+ printf("WARNING: Could not get throughput "
+ "(error=%d)\n", errno);
+ }
+ error = sysctlbyname("hw.usb.g_audio.pattern", NULL, NULL,
+ &pattern, strlen(pattern));
+
+ if (error != 0) {
+ printf("WARNING: Could not set audio pattern "
+ "to '%s' (error=%d)\n", pattern, errno);
+ }
+ retval = usb_ts_show_menu(level, "Default Audio Settings",
+ "1) Set Silent mode %s\n"
+ "2) Set Dump mode %s\n"
+ "3) Set Loop mode %s\n"
+ "4) Set Pattern mode %s\n"
+ "5) Change DTMF pattern: '%s'\n"
+ "6) Change pattern advance interval: %d ms\n"
+ "x) Return to previous menu\n"
+ "s: Ready for enumeration\n"
+ "t: Throughput: %d bytes/second\n",
+ (mode == G_AUDIO_MODE_SILENT) ? "(selected)" : "",
+ (mode == G_AUDIO_MODE_DUMP) ? "(selected)" : "",
+ (mode == G_AUDIO_MODE_LOOP) ? "(selected)" : "",
+ (mode == G_AUDIO_MODE_PATTERN) ? "(selected)" : "",
+ pattern, pattern_interval, throughput);
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ mode = G_AUDIO_MODE_SILENT;
+ break;
+ case 2:
+ mode = G_AUDIO_MODE_DUMP;
+ break;
+ case 3:
+ mode = G_AUDIO_MODE_LOOP;
+ break;
+ case 4:
+ mode = G_AUDIO_MODE_PATTERN;
+ break;
+ case 5:
+ get_string(pattern, sizeof(pattern));
+ break;
+ case 6:
+ pattern_interval = get_integer();
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_device_audio_select(uint8_t level)
+{
+ uint8_t retval;
+
+ while (1) {
+
+ retval = usb_ts_show_menu(level, "Select Audio Device Model",
+ "1) Generic Audio Device\n"
+ "x) Return to previous menu\n");
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ show_default_audio_select(level + 1);
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_device_msc_select(uint8_t level)
+{
+ set_template(USB_TEMP_MSC);
+}
+
+static void
+show_device_ethernet_select(uint8_t level)
+{
+ set_template(USB_TEMP_CDCE);
+}
+
+static void
+show_default_keyboard_select(uint8_t level)
+{
+ int error;
+ int retval;
+ int mode = 0;
+ int interval = 1023;
+ char pattern[G_KEYBOARD_MAX_STRLEN] = {"abcdefpattern"};
+
+ set_template(USB_TEMP_KBD);
+
+ while (1) {
+
+ error = sysctlbyname("hw.usb.g_keyboard.mode", NULL, NULL,
+ &mode, sizeof(mode));
+
+ if (error != 0) {
+ printf("WARNING: Could not set keyboard mode "
+ " to %d (error=%d) \n", mode, errno);
+ }
+ error = sysctlbyname("hw.usb.g_keyboard.key_press_interval", NULL, NULL,
+ &interval, sizeof(interval));
+
+ if (error != 0) {
+ printf("WARNING: Could not set key press interval "
+ "to %d (error=%d)\n", interval, errno);
+ }
+ error = sysctlbyname("hw.usb.g_keyboard.key_press_pattern", NULL, NULL,
+ &pattern, strlen(pattern));
+
+ if (error != 0) {
+ printf("WARNING: Could not set key pattern "
+ "to '%s' (error=%d)\n", pattern, errno);
+ }
+ retval = usb_ts_show_menu(level, "Default Keyboard Settings",
+ "1) Set silent mode %s\n"
+ "2) Set pattern mode %s\n"
+ "3) Change pattern: '%s'\n"
+ "4) Change key press interval: %d ms\n"
+ "x) Return to previous menu\n"
+ "s: Ready for enumeration\n",
+ (mode == G_KEYBOARD_MODE_SILENT) ? "(selected)" : "",
+ (mode == G_KEYBOARD_MODE_PATTERN) ? "(selected)" : "",
+ pattern, interval);
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ mode = G_KEYBOARD_MODE_SILENT;
+ break;
+ case 2:
+ mode = G_KEYBOARD_MODE_PATTERN;
+ break;
+ case 3:
+ get_string(pattern, sizeof(pattern));
+ break;
+ case 4:
+ interval = get_integer();
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_device_keyboard_select(uint8_t level)
+{
+ uint8_t retval;
+
+ while (1) {
+
+ retval = usb_ts_show_menu(level, "Select Keyboard Model",
+ "1) Generic Keyboard \n"
+ "x) Return to previous menu \n");
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ show_default_keyboard_select(level + 1);
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_default_mouse_select(uint8_t level)
+{
+ int error;
+ int retval;
+ int mode = 0;
+ int cursor_interval = 128;
+ int cursor_radius = 75;
+ int button_interval = 0;
+
+ set_template(USB_TEMP_MOUSE);
+
+ while (1) {
+
+ error = sysctlbyname("hw.usb.g_mouse.mode", NULL, NULL,
+ &mode, sizeof(mode));
+
+ if (error != 0) {
+ printf("WARNING: Could not set mouse mode "
+ "to %d (error=%d)\n", mode, errno);
+ }
+ error = sysctlbyname("hw.usb.g_mouse.cursor_update_interval", NULL, NULL,
+ &cursor_interval, sizeof(cursor_interval));
+
+ if (error != 0) {
+ printf("WARNING: Could not set cursor update interval "
+ "to %d (error=%d)\n", cursor_interval, errno);
+ }
+ error = sysctlbyname("hw.usb.g_mouse.button_press_interval", NULL, NULL,
+ &button_interval, sizeof(button_interval));
+
+ if (error != 0) {
+ printf("WARNING: Could not set button press interval "
+ "to %d (error=%d)\n", button_interval, errno);
+ }
+ error = sysctlbyname("hw.usb.g_mouse.cursor_radius", NULL, NULL,
+ &cursor_radius, sizeof(cursor_radius));
+
+ if (error != 0) {
+ printf("WARNING: Could not set cursor radius "
+ "to %d (error=%d)\n", cursor_radius, errno);
+ }
+ retval = usb_ts_show_menu(level, "Default Mouse Settings",
+ "1) Set Silent mode %s\n"
+ "2) Set Circle mode %s\n"
+ "3) Set Square mode %s\n"
+ "4) Set Spiral mode %s\n"
+ "5) Change cursor radius: %d pixels\n"
+ "6) Change cursor update interval: %d ms\n"
+ "7) Change button[0] press interval: %d ms\n"
+ "x) Return to previous menu\n"
+ "s: Ready for enumeration\n",
+ (mode == G_MOUSE_MODE_SILENT) ? "(selected)" : "",
+ (mode == G_MOUSE_MODE_CIRCLE) ? "(selected)" : "",
+ (mode == G_MOUSE_MODE_BOX) ? "(selected)" : "",
+ (mode == G_MOUSE_MODE_SPIRAL) ? "(selected)" : "",
+ cursor_radius, cursor_interval, button_interval);
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ mode = G_MOUSE_MODE_SILENT;
+ break;
+ case 2:
+ mode = G_MOUSE_MODE_CIRCLE;
+ break;
+ case 3:
+ mode = G_MOUSE_MODE_BOX;
+ break;
+ case 4:
+ mode = G_MOUSE_MODE_SPIRAL;
+ break;
+ case 5:
+ cursor_radius = get_integer();
+ break;
+ case 6:
+ cursor_interval = get_integer();
+ break;
+ case 7:
+ button_interval = get_integer();
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_device_mouse_select(uint8_t level)
+{
+ uint8_t retval;
+
+ while (1) {
+
+ retval = usb_ts_show_menu(level, "Select Mouse Model",
+ "1) Generic Mouse\n"
+ "x) Return to previous menu\n");
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ show_default_mouse_select(level + 1);
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_device_mtp_select(uint8_t level)
+{
+ set_template(USB_TEMP_MTP);
+}
+
+static void
+show_default_modem_select(uint8_t level)
+{
+ int error;
+ int retval;
+ int mode = 0;
+ int pattern_interval = 128;
+ int throughput = 0;
+ size_t len;
+ char pattern[G_MODEM_MAX_STRLEN] = {"abcdefpattern"};
+
+ set_template(USB_TEMP_MODEM);
+
+ while (1) {
+
+ error = sysctlbyname("hw.usb.g_modem.mode", NULL, NULL,
+ &mode, sizeof(mode));
+
+ if (error != 0) {
+ printf("WARNING: Could not set modem mode "
+ "to %d (error=%d)\n", mode, errno);
+ }
+ error = sysctlbyname("hw.usb.g_modem.pattern_interval", NULL, NULL,
+ &pattern_interval, sizeof(pattern_interval));
+
+ if (error != 0) {
+ printf("WARNING: Could not set pattern interval "
+ "to %d (error=%d)\n", pattern_interval, errno);
+ }
+ len = sizeof(throughput);
+
+ error = sysctlbyname("hw.usb.g_modem.throughput",
+ &throughput, &len, 0, 0);
+
+ if (error != 0) {
+ printf("WARNING: Could not get throughput "
+ "(error=%d)\n", errno);
+ }
+ error = sysctlbyname("hw.usb.g_modem.pattern", NULL, NULL,
+ &pattern, strlen(pattern));
+
+ if (error != 0) {
+ printf("WARNING: Could not set modem pattern "
+ "to '%s' (error=%d)\n", pattern, errno);
+ }
+ retval = usb_ts_show_menu(level, "Default Modem Settings",
+ "1) Set Silent mode %s\n"
+ "2) Set Dump mode %s\n"
+ "3) Set Loop mode %s\n"
+ "4) Set Pattern mode %s\n"
+ "5) Change test pattern: '%s'\n"
+ "6) Change data transmit interval: %d ms\n"
+ "x) Return to previous menu\n"
+ "s: Ready for enumeration\n"
+ "t: Throughput: %d bytes/second\n",
+ (mode == G_MODEM_MODE_SILENT) ? "(selected)" : "",
+ (mode == G_MODEM_MODE_DUMP) ? "(selected)" : "",
+ (mode == G_MODEM_MODE_LOOP) ? "(selected)" : "",
+ (mode == G_MODEM_MODE_PATTERN) ? "(selected)" : "",
+ pattern, pattern_interval, throughput);
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ mode = G_MODEM_MODE_SILENT;
+ break;
+ case 2:
+ mode = G_MODEM_MODE_DUMP;
+ break;
+ case 3:
+ mode = G_MODEM_MODE_LOOP;
+ break;
+ case 4:
+ mode = G_MODEM_MODE_PATTERN;
+ break;
+ case 5:
+ get_string(pattern, sizeof(pattern));
+ break;
+ case 6:
+ pattern_interval = get_integer();
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_device_modem_select(uint8_t level)
+{
+ uint8_t retval;
+
+ while (1) {
+
+ retval = usb_ts_show_menu(level, "Select Modem Model",
+ "1) Generic Modem\n"
+ "x) Return to previous menu\n");
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ show_default_modem_select(level + 1);
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_device_generic_select(uint8_t level)
+{
+}
+
+static void
+show_device_select(uint8_t level)
+{
+ uint8_t retval;
+
+ while (1) {
+
+ retval = usb_ts_show_menu(level, "Select Device Mode Test Group",
+ "1) Audio (UAUDIO)\n"
+ "2) Mass Storage (MSC)\n"
+ "3) Ethernet (CDCE)\n"
+ "4) Keyboard Input Device (UKBD)\n"
+ "5) Mouse Input Device (UMS)\n"
+ "6) Message Transfer Protocol (MTP)\n"
+ "7) Modem (CDC)\n"
+ "8) Generic Endpoint Loopback (GENERIC)\n"
+ "x) Return to previous menu\n");
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ show_device_audio_select(level + 1);
+ break;
+ case 2:
+ show_device_msc_select(level + 1);
+ break;
+ case 3:
+ show_device_ethernet_select(level + 1);
+ break;
+ case 4:
+ show_device_keyboard_select(level + 1);
+ break;
+ case 5:
+ show_device_mouse_select(level + 1);
+ break;
+ case 6:
+ show_device_mtp_select(level + 1);
+ break;
+ case 7:
+ show_device_modem_select(level + 1);
+ break;
+ case 8:
+ show_device_generic_select(level + 1);
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_host_select(uint8_t level)
+{
+ int force_fs = 0;
+ int error;
+ uint32_t duration = 60;
+
+ uint16_t dev_vid = 0;
+ uint16_t dev_pid = 0;
+ uint8_t retval;
+
+ while (1) {
+
+ error = sysctlbyname("hw.usb.ehci.no_hs", NULL, NULL,
+ &force_fs, sizeof(force_fs));
+
+ if (error != 0) {
+ printf("WARNING: Could not set non-FS mode "
+ "to %d (error=%d)\n", force_fs, errno);
+ }
+ retval = usb_ts_show_menu(level, "Select Host Mode Test (via LibUSB)",
+ " 1) Select USB device (VID=0x%04x, PID=0x%04x)\n"
+ " 2) Manually enter USB vendor and product ID\n"
+ " 3) Force FULL speed operation: <%s>\n"
+ " 4) Mass Storage (UMASS)\n"
+ " 5) Modem (UMODEM)\n"
+ "10) Start String Descriptor Test\n"
+ "11) Start Port Reset Test\n"
+ "12) Start Set Config Test\n"
+ "13) Start Get Descriptor Test\n"
+ "14) Start Suspend and Resume Test\n"
+ "15) Start Set and Clear Endpoint Stall Test\n"
+ "16) Start Set Alternate Interface Setting Test\n"
+ "17) Start Invalid Control Request Test\n"
+ "30) Duration: <%d> seconds\n"
+ "x) Return to previous menu\n",
+ dev_vid, dev_pid,
+ force_fs ? "YES" : "NO",
+ (int)duration);
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ show_host_device_selection(level + 1, &dev_vid, &dev_pid);
+ break;
+ case 2:
+ dev_vid = get_integer() & 0xFFFF;
+ dev_pid = get_integer() & 0xFFFF;
+ break;
+ case 3:
+ force_fs ^= 1;
+ break;
+ case 4:
+ show_host_msc_test(level + 1, dev_vid, dev_pid, duration);
+ break;
+ case 5:
+ show_host_modem_test(level + 1, dev_vid, dev_pid, duration);
+ break;
+ case 10:
+ usb_get_string_desc_test(dev_vid, dev_pid);
+ break;
+ case 11:
+ usb_port_reset_test(dev_vid, dev_pid, duration);
+ break;
+ case 12:
+ usb_set_config_test(dev_vid, dev_pid, duration);
+ break;
+ case 13:
+ usb_get_descriptor_test(dev_vid, dev_pid, duration);
+ break;
+ case 14:
+ usb_suspend_resume_test(dev_vid, dev_pid, duration);
+ break;
+ case 15:
+ usb_set_and_clear_stall_test(dev_vid, dev_pid);
+ break;
+ case 16:
+ usb_set_alt_interface_test(dev_vid, dev_pid);
+ break;
+ case 17:
+ usb_control_ep_error_test(dev_vid, dev_pid);
+ break;
+ case 30:
+ duration = get_integer();
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void
+show_mode_select(uint8_t level)
+{
+ uint8_t retval;
+
+ while (1) {
+
+ retval = usb_ts_show_menu(level, "Select Computer Mode",
+ "1) This computer is Running the Device Side\n"
+ "2) This computer is Running the Host Side\n"
+ "x) Return to previous menu\n");
+
+ switch (retval) {
+ case 0:
+ break;
+ case 1:
+ show_device_select(level + 1);
+ break;
+ case 2:
+ show_host_select(level + 1);
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ show_mode_select(1);
+
+ return (0);
+}
diff --git a/tools/tools/usbtest/usbtest.h b/tools/tools/usbtest/usbtest.h
new file mode 100644
index 0000000..3d6643c
--- /dev/null
+++ b/tools/tools/usbtest/usbtest.h
@@ -0,0 +1,62 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _USBTEST_H_
+#define _USBTEST_H_
+
+#define USB_DEVICES_MAX 128
+#define USB_TS_MAX_LEVELS 8
+
+struct libusb20_device;
+
+struct bps {
+ uint32_t bytes;
+ time_t time;
+};
+
+extern void usb_get_string_desc_test(uint16_t, uint16_t);
+extern void usb_port_reset_test(uint16_t, uint16_t, uint32_t);
+extern void usb_set_config_test(uint16_t, uint16_t, uint32_t);
+extern void usb_get_descriptor_test(uint16_t, uint16_t, uint32_t);
+extern void usb_control_ep_error_test(uint16_t, uint16_t);
+extern void usb_set_and_clear_stall_test(uint16_t, uint16_t);
+extern void usb_set_alt_interface_test(uint16_t, uint16_t);
+
+extern void usb_suspend_resume_test(uint16_t, uint16_t, uint32_t);
+extern void do_bps(const char *, struct bps *, uint32_t len);
+extern const char *indent[USB_TS_MAX_LEVELS];
+extern void show_host_msc_test(uint8_t, uint16_t, uint16_t, uint32_t);
+extern void show_host_modem_test(uint8_t, uint16_t, uint16_t, uint32_t);
+extern void show_host_device_selection(uint8_t, uint16_t *, uint16_t *);
+extern struct libusb20_device *find_usb_device(uint16_t, uint16_t);
+extern void find_usb_endpoints(struct libusb20_device *, uint8_t, uint8_t,
+ uint8_t, uint8_t, uint8_t *, uint8_t *, uint8_t *, uint8_t);
+extern void get_string(char *, int);
+extern int get_integer(void);
+extern uint8_t usb_ts_show_menu(uint8_t, const char *, const char *,...);
+extern int32_t usb_ts_rand_noise(void);
+
+#endif /* _USBTEST_H_ */
diff --git a/tools/tools/zfsboottest/Makefile b/tools/tools/zfsboottest/Makefile
index c0c7d92..a04c78f 100644
--- a/tools/tools/zfsboottest/Makefile
+++ b/tools/tools/zfsboottest/Makefile
@@ -15,8 +15,7 @@ CFLAGS= -O1 \
-I${.CURDIR}/../../../sys/cddl/boot/zfs \
-I. \
-fdiagnostics-show-option \
- -W -Wextra -Wno-sign-compare -Wno-unused-parameter \
- -Werror
+ -W -Wextra -Wno-sign-compare -Wno-unused-parameter
LDFLAGS+=-lmd
.if ${MACHINE_CPUARCH} == "amd64"
diff --git a/tools/tools/zfsboottest/zfsboottest.c b/tools/tools/zfsboottest/zfsboottest.c
index 3058046..29e9a48 100644
--- a/tools/tools/zfsboottest/zfsboottest.c
+++ b/tools/tools/zfsboottest/zfsboottest.c
@@ -52,6 +52,7 @@ pager_output(const char *line)
#define ZFS_TEST
#define printf(...) fprintf(stderr, __VA_ARGS__)
+#include "libzfs.h"
#include "zfsimpl.c"
#undef printf
@@ -134,7 +135,6 @@ main(int argc, char** argv)
close(fd[i - 1]);
}
}
- spa_all_status();
spa = STAILQ_FIRST(&zfs_pools);
if (spa == NULL) {
@@ -147,7 +147,10 @@ main(int argc, char** argv)
exit(1);
}
+ spa_all_status();
+
#if 0
+ uint64_t rootobj;
if (zfs_get_root(spa, &rootobj)) {
fprintf(stderr, "can't get root\n");
exit(1);
@@ -158,8 +161,8 @@ main(int argc, char** argv)
if (zfs_mount(spa, 0, &zfsmnt)) {
fprintf(stderr, "can't mount\n");
exit(1);
- }
#endif
+ }
printf("\n");
for (++i, failures = 0; i < argc; i++) {
diff --git a/tools/tools/zfsboottest/zfsboottest.sh b/tools/tools/zfsboottest/zfsboottest.sh
index 1707e3f..1aea755 100755
--- a/tools/tools/zfsboottest/zfsboottest.sh
+++ b/tools/tools/zfsboottest/zfsboottest.sh
@@ -54,11 +54,6 @@ bootfs=`zpool get bootfs "${pool}" | tail -1 | awk '{print $3}'`
if [ "${bootfs}" = "-" ]; then
bootfs="${pool}"
fi
-# Dataset's mountpoint property should be set to 'legacy'.
-if [ "`zfs get -H -o value mountpoint ${bootfs}`" != "legacy" ]; then
- echo "The \"mountpoint\" property of dataset \"${bootfs}\" should be set to \"legacy\"." >&2
- exit 1
-fi
mountpoint=`df -t zfs "${bootfs}" 2>/dev/null | tail -1 | awk '{print $6}'`
if [ -z "${mountpoint}" ]; then
echo "The \"${bootfs}\" dataset is not mounted." >&2
@@ -68,19 +63,6 @@ if [ ! -d "${mountpoint}${startdir}" ]; then
echo "The \"${mountpoint}${startdir}\" directory doesn't exist." >&2
exit 1
fi
-# To be able to mount root ZFS file system we need either /etc/fstab entry
-# or vfs.root.mountfrom variable set in /boot/loader.conf.
-egrep -q '^'"${bootfs}"'[[:space:]]+/[[:space:]]+zfs[[:space:]]+' "${mountpoint}/etc/fstab" 2>/dev/null
-if [ $? -ne 0 ]; then
- egrep -q 'vfs.root.mountfrom="?'"zfs:${bootfs}"'"?[[:space:]]*$' "${mountpoint}/boot/loader.conf" 2>/dev/null
- if [ $? -ne 0 ]; then
- echo "To be able to boot from \"${bootfs}\", you need to declare" >&2
- echo "\"${bootfs}\" as being root file system in ${mountpoint}/etc/fstab" >&2
- echo "or add \"vfs.root.mountfrom\" variable set to \"zfs:${bootfs}\" to" >&2
- echo "${mountpoint}/boot/loader.conf." >&2
- exit 1
- fi
-fi
vdevs=""
for vdev in `zpool status "${pool}" | grep ONLINE | awk '{print $1}'`; do
vdev="/dev/${vdev#/dev/}"
OpenPOWER on IntegriCloud